Exemplo n.º 1
0
ssize_t psock_local_send(FAR struct socket *psock, FAR const void *buf,
                         size_t len, int flags)
{
  FAR struct local_conn_s *peer;
  int ret;

  DEBUGASSERT(psock && psock->s_conn && buf);
  peer = (FAR struct local_conn_s *)psock->s_conn;

  /* Verify that this is a connected peer socket and that it has opened the
   * outgoing FIFO for write-only access.
   */

  if (peer->lc_state != LOCAL_STATE_CONNECTED ||
      peer->lc_outfd < 0)
    {
      nerr("ERROR: not connected\n");
      return -ENOTCONN;
    }

  /* Send the packet */

  ret = local_send_packet(peer->lc_outfd, (FAR uint8_t *)buf, len);

  /* If the send was successful, then the full packet will have been sent */

  return ret < 0 ? ret : len;
}
Exemplo n.º 2
0
ssize_t psock_local_sendto(FAR struct socket *psock, FAR const void *buf,
                           size_t len, int flags, FAR const struct sockaddr *to,
                           socklen_t tolen)
{
  FAR struct local_conn_s *conn = (FAR struct local_conn_s *)psock->s_conn;
  FAR struct sockaddr_un *unaddr = (FAR struct sockaddr_un *)to;
  ssize_t nsent;
  int ret;

  /* We keep packet sizes in a uint16_t, so there is a upper limit to the
   * 'len' that can be supported.
   */

  DEBUGASSERT(buf && len <= UINT16_MAX);

  /* Verify that this is not a connected peer socket.  It need not be
   * bound, however.  If unbound, recvfrom will see this as a nameless
   * connection.
   */

  if (conn->lc_state != LOCAL_STATE_UNBOUND &&
      conn->lc_state != LOCAL_STATE_BOUND)
    {
      /* Either not bound to address or it is connected */

      ndbg("ERROR: Connected state\n");
      return -EISCONN;
    }

  /* The outgoing FIFO should not be open */

  DEBUGASSERT(conn->lc_outfd < 0);

  /* At present, only standard pathname type address are support */

  if (tolen < sizeof(sa_family_t) + 2)
    {
     /* EFAULT - An invalid user space address was specified for a parameter */

     return -EFAULT;
    }

  /* Make sure that half duplex FIFO has been created.
   * REVISIT:  Or should be just make sure that it already exists?
   */

  ret = local_create_halfduplex(conn, unaddr->sun_path);
  if (ret < 0)
    {
      ndbg("ERROR: Failed to create FIFO for %s: %d\n",
           conn->lc_path, ret);
      return ret;
    }

  /* Open the sending side of the transfer */

  ret = local_open_sender(conn, unaddr->sun_path,
                          _SS_ISNONBLOCK(psock->s_flags));
  if (ret < 0)
    {
      ndbg("ERROR: Failed to open FIFO for %s: %d\n",
           unaddr->sun_path, ret);

      nsent = ret;
      goto errout_with_halfduplex;
    }

  /* Send the packet */

  nsent = local_send_packet(conn->lc_outfd, buf, len);
  if (nsent < 0)
    {
      ndbg("ERROR: Failed to send the packet: %d\n", ret);
    }
  else
    {
      /* local_send_packet returns 0 if all 'len' bytes were sent */

      nsent = len;
    }

  /* Now we can close the write-only socket descriptor */

  close(conn->lc_outfd);
  conn->lc_outfd = -1;

errout_with_halfduplex:
  /* Release our reference to the half duplex FIFO*/

  (void)local_release_halfduplex(conn);
  return nsent;
}