示例#1
0
/* dbs_server_write_data
 * The connection is writable, so send any pending data.  Returns
 * false on failure.  (EAGAIN doesn't count as a failure.)
 */
BOOL dbs_server_write_data(t_d2dbs_connection* conn)
{
	unsigned int sendlen;
	int nBytes ;

	if (conn->nCharsInWriteBuffer>kMaxPacketLength) sendlen=kMaxPacketLength;
	else sendlen=conn->nCharsInWriteBuffer;
	nBytes = psock_send(conn->sd, conn->WriteBuf, sendlen, 0);
	if (nBytes < 0) {
	        int 		err;
		psock_t_socklen errlen;

		err = 0;
		errlen = sizeof(err);
		if (psock_getsockopt(conn->sd, PSOCK_SOL_SOCKET, PSOCK_SO_ERROR, &err, &errlen)<0)
			return TRUE;
		if (errlen==0 || err==PSOCK_EAGAIN) {
			return TRUE;
		} else {
			eventlog(eventlog_level_error,__FUNCTION__,"psock_send() failed : %s",strerror(err));
			return FALSE;
		}
	}
	if (nBytes == conn->nCharsInWriteBuffer) {
		conn->nCharsInWriteBuffer = 0;
	} else {
		conn->nCharsInWriteBuffer -= nBytes;
		memmove(conn->WriteBuf, conn->WriteBuf + nBytes, conn->nCharsInWriteBuffer);
	}
	return TRUE;
}
示例#2
0
int myp_send( MYSQL *m, void *buf, int size ) {
	while( size ) {
		int len = psock_send(m->s,(char*)buf,size);
		if( len <= 0 ) return size == 0 ? 1 : 0;
		buf = ((char*)buf) + len;
		size -= len;
	}
	return 1;
}
示例#3
0
文件: sendto.c 项目: dagar/NuttX
ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
                     size_t len, int flags, FAR const struct sockaddr *to,
                     socklen_t tolen)
{
  ssize_t nsent;

  /* Verify that non-NULL pointers were passed */

#ifdef CONFIG_DEBUG_FEATURES
  if (buf == NULL)
    {
      return -EINVAL;
    }
#endif

  /* If to is NULL or tolen is zero, then this function is same as send (for
   * connected socket types)
   */

  if (to == NULL || tolen <= 0)
    {
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM) || \
    defined(CONFIG_NET_USRSOCK)
      return psock_send(psock, buf, len, flags);
#else
      nerr("ERROR: No 'to' address\n");
      return -EINVAL;
#endif
    }

  /* Verify that the psock corresponds to valid, allocated socket */

  if (psock == NULL || psock->s_crefs <= 0)
    {
      nerr("ERROR: Invalid socket\n");
      return -EBADF;
    }

  /* Let the address family's sendto() method handle the operation */

  DEBUGASSERT(psock->s_sockif != NULL && psock->s_sockif->si_sendto != NULL);
  nsent = psock->s_sockif->si_sendto(psock, buf, len, flags, to, tolen);

  /* Check if the domain-specific sendto() logic failed */

  if (nsent < 0)
    {
      nerr("ERROR:  Family-specific send failed: %ld\n", (long)nsent);
      return nsent;
    }

  return nsent;
}
示例#4
0
static void telnetd_sendopt(FAR struct telnetd_dev_s *priv, uint8_t option,
                            uint8_t value)
{
  uint8_t optbuf[4];
  optbuf[0] = TELNET_IAC;
  optbuf[1] = option;
  optbuf[2] = value;
  optbuf[3] = 0;

  telnetd_dumpbuffer("Send optbuf", optbuf, 4);
  if (psock_send(&priv->td_psock, optbuf, 4, 0) < 0)
    {
      nlldbg("Failed to send TELNET_IAC\n");
    }
}
示例#5
0
文件: net.cpp 项目: AleXoundOS/pvpgn
extern int net_send_data(int sock, char * buff, int buffsize, int * pos, int * currsize)
{
	int	nsend;

	ASSERT(buff,-1);
	ASSERT(pos,-1);
	if (*pos>buffsize) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer overflow pos=%d buffsize=%d",sock,*pos,buffsize);
		return -1;
	}
	if (*currsize>*pos) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] send buffer error currsize=%d pos=%d",sock,*currsize,*pos);
		return -1;
	}
	nsend=psock_send(sock,buff+*pos-*currsize,*currsize,0);
	if (nsend==0) {
		eventlog(eventlog_level_error,__FUNCTION__,"[%d] no data sent (close connection)",sock);
		return -1;
	}
	if (nsend<0) {
		if (
#ifdef PSOCK_EINTR
			psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
			psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
			psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_NOBUFS
			psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
			psock_errno()==ENOMEM ||
#endif
		0)
			return 0;

		eventlog(eventlog_level_error,__FUNCTION__,"[%d] error sent data (closing connection) (psock_send: %s)",sock,pstrerror(psock_errno()));
		return -1;
	}
	*currsize -= nsend;
	return 1;
}
示例#6
0
文件: send.c 项目: a1ien/nuttx
ssize_t send(int sockfd, FAR const void *buf, size_t len, int flags)
{
  FAR struct socket *psock;
  ssize_t ret;

  /* send() is a cancellation point */

  (void)enter_cancellation_point();

  /* Get the underlying socket structure */

  psock = sockfd_socket(sockfd);

  /* And let psock_send do all of the work */

  ret = psock_send(psock, buf, len, flags);
  leave_cancellation_point();
  return ret;
}
示例#7
0
extern int net_send(int sock, const void *buff, int len)
{
    int res;

    res = psock_send(sock, buff, len, 0);

    if (res > 0) return res;
    if (!res) return -1;

    if (
#ifdef PSOCK_EINTR
	psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOBUFS
	psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
	psock_errno()==PSOCK_ENOMEM ||
#endif
	0)
	return 0; /* try again later */

    if (
#ifdef PSOCK_EPIPE
	psock_errno()!=PSOCK_EPIPE &&
#endif
#ifdef PSOCK_ECONNRESET
	psock_errno()!=PSOCK_ECONNRESET &&
#endif
	1) eventlog(eventlog_level_debug,__FUNCTION__,"[%d] could not send data (closing connection) (psock_send: %s)",sock,std::strerror(psock_errno()));

    return -1;
}
ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
                     size_t len, int flags, FAR const struct sockaddr *to,
                     socklen_t tolen)
{
#ifdef CONFIG_NET_UDP
  FAR struct uip_udp_conn *conn;
#ifdef CONFIG_NET_IPv6
  FAR const struct sockaddr_in6 *into = (const struct sockaddr_in6 *)to;
#else
  FAR const struct sockaddr_in *into = (const struct sockaddr_in *)to;
#endif
  struct sendto_s state;
  uip_lock_t save;
  int ret;
#endif
  int err;

  /* If to is NULL or tolen is zero, then this function is same as send (for
   * connected socket types)
   */

  if (!to || !tolen)
    {
#ifdef CONFIG_NET_TCP
      return psock_send(psock, buf, len, flags);
#else
      err = EINVAL;
      goto errout;
#endif
    }

  /* Verify that a valid address has been provided */

#ifdef CONFIG_NET_IPv6
  if (to->sa_family != AF_INET6 || tolen < sizeof(struct sockaddr_in6))
#else
  if (to->sa_family != AF_INET || tolen < sizeof(struct sockaddr_in))
#endif
  {
      err = EBADF;
      goto errout;
  }

  /* Verify that the psock corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      err = EBADF;
      goto errout;
    }

  /* If this is a connected socket, then return EISCONN */

  if (psock->s_type != SOCK_DGRAM)
    {
      err = EISCONN;
      goto errout;
    }

  /* Perform the UDP sendto operation */

#ifdef CONFIG_NET_UDP
  /* Set the socket state to sending */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_SEND);

  /* Initialize the state structure.  This is done with interrupts
   * disabled because we don't want anything to happen until we
   * are ready.
   */

  save = uip_lock();
  memset(&state, 0, sizeof(struct sendto_s));
  sem_init(&state.st_sem, 0, 0);
  state.st_buflen = len;
  state.st_buffer = buf;

  /* Set the initial time for calculating timeouts */

#ifdef CONFIG_NET_SENDTO_TIMEOUT
  state.st_sock = psock;
  state.st_time = clock_systimer();
#endif

  /* Setup the UDP socket */

  conn = (struct uip_udp_conn *)psock->s_conn;
  ret = uip_udpconnect(conn, into);
  if (ret < 0)
    {
      uip_unlock(save);
      err = -ret;
      goto errout;
    }

  /* Set up the callback in the connection */

  state.st_cb = uip_udpcallbackalloc(conn);
  if (state.st_cb)
    {
      state.st_cb->flags   = UIP_POLL;
      state.st_cb->priv    = (void*)&state;
      state.st_cb->event   = sendto_interrupt;

      /* Notify the device driver of the availabilty of TX data */

      netdev_txnotify(conn->ripaddr);

      /* Wait for either the receive to complete or for an error/timeout to occur.
       * NOTES:  (1) uip_lockedwait will also terminate if a signal is received, (2)
       * interrupts may be disabled!  They will be re-enabled while the task sleeps
       * and automatically re-enabled when the task restarts.
       */

      uip_lockedwait(&state.st_sem);

      /* Make sure that no further interrupts are processed */

      uip_udpcallbackfree(conn, state.st_cb);
    }
  uip_unlock(save);

  sem_destroy(&state.st_sem);

  /* Set the socket state to idle */

  psock->s_flags = _SS_SETSTATE(psock->s_flags, _SF_IDLE);

  /* Check for errors */

  if (state.st_sndlen < 0)
    {
      err = -state.st_sndlen;
      goto errout;
    }

  /* Sucess */

  return state.st_sndlen;
#else
  err = ENOSYS;
#endif

errout:
  set_errno(err);
  return ERROR;
}
示例#9
0
文件: vnc_raw.c 项目: a1ien/nuttx
int vnc_raw(FAR struct vnc_session_s *session, FAR struct nxgl_rect_s *rect)
{
  FAR struct rfb_framebufferupdate_s *update;
  FAR const uint8_t *src;
  nxgl_coord_t srcwidth;
  nxgl_coord_t srcheight;
  nxgl_coord_t destwidth;
  nxgl_coord_t destheight;
  nxgl_coord_t deststride;
  nxgl_coord_t updwidth;
  nxgl_coord_t updheight;
  nxgl_coord_t width;
  nxgl_coord_t x;
  nxgl_coord_t y;
  unsigned int bytesperpixel;
  unsigned int maxwidth;
  size_t size;
  ssize_t nsent;
  uint8_t colorfmt;

  union
  {
    vnc_convert8_t bpp8;
    vnc_convert16_t bpp16;
    vnc_convert32_t bpp32;
  } convert;

  /* Set up characteristics of the client pixel format to use on this
   * update.  These can change at any time if a SetPixelFormat is
   * received asynchronously.
   */

  bytesperpixel = (session->bpp + 7) >> 3;
  maxwidth      = CONFIG_VNCSERVER_UPDATE_BUFSIZE / bytesperpixel;

  /* Set up the color conversion */

  colorfmt = session->colorfmt;
  switch (colorfmt)
    {
      case FB_FMT_RGB8_222:
        convert.bpp8 = vnc_convert_rgb8_222;
        break;

      case FB_FMT_RGB8_332:
        convert.bpp8 = vnc_convert_rgb8_332;
        break;

      case FB_FMT_RGB16_555:
        convert.bpp16 = vnc_convert_rgb16_555;
        break;

      case FB_FMT_RGB16_565:
        convert.bpp16 = vnc_convert_rgb16_565;
        break;

      case FB_FMT_RGB32:
        convert.bpp32 = vnc_convert_rgb32_888;
        break;

      default:
        gerr("ERROR: Unrecognized color format: %d\n", session->colorfmt);
        return -EINVAL;
    }

  /* Get with width and height of the source and destination rectangles.
   * The source rectangle many be larger than the destination rectangle.
   * In that case, we will have to emit multiple rectangles.
   */

  DEBUGASSERT(rect->pt1.x <= rect->pt2.x);
  srcwidth = rect->pt2.x - rect->pt1.x + 1;

  DEBUGASSERT(rect->pt1.y <= rect->pt2.y);
  srcheight = rect->pt2.y - rect->pt1.y + 1;

  deststride = srcwidth * bytesperpixel;
  if (deststride > maxwidth)
    {
      deststride = maxwidth;
    }

  destwidth  = deststride / bytesperpixel;
  destheight = CONFIG_VNCSERVER_UPDATE_BUFSIZE / deststride;

  if (destheight > srcheight)
    {
      destheight = srcheight;
    }

  /* Format the rectangle header.  We may have to send several update
   * messages if the pre-allocated outbuf is smaller than the rectangle.
   * Each update contains a small "sub-rectangle" of the origin update.
   *
   * Loop until all sub-rectangles have been output.  Start with the
   * top row and transfer rectangles horizontally across each swath.
   * The height of the swath is destwidth (the last may be shorter).
   *
   * NOTE that the loop also terminates of the color format changes
   * asynchronously.
   */

  for (y = rect->pt1.y;
       srcheight > 0 && colorfmt == session->colorfmt;
       srcheight -= updheight, y += updheight)
    {
      /* updheight = Height to update on this pass through the loop.
       * This will be destheight unless fewer than that number of rows
       * remain.
       */

      updheight = destheight;
      if (updheight > srcheight)
        {
          updheight = srcheight;
        }

      /* Loop until this horizontal swath has sent to the VNC client.
       * Start with the leftmost pixel and transfer rectangles
       * horizontally with width of destwidth until all srcwidth
       * columns have been transferred (the last rectangle may be
       * narrower).
       *
       * NOTE that the loop also terminates of the color format
       * changes asynchronously.
       */

      for (width = srcwidth, x = rect->pt1.x;
           width > 0 && colorfmt == session->colorfmt;
           width -= updwidth, x += updwidth)
        {
          /* updwidth = Width to update on this pass through the loop.
           * This will be destwidth unless fewer than that number of
           * columns remain.
           */

          updwidth = destwidth;
          if (updwidth > width)
            {
              updwidth = width;
            }

          /* Transfer the frame buffer data into the rectangle,
           * performing the necessary color conversions.
           */

          if (bytesperpixel == 1)
            {
              size = vnc_copy8(session, y, x, updheight, updwidth,
                               convert.bpp8);
            }
          else if (bytesperpixel == 2)
            {
              size = vnc_copy16(session, y, x, updheight, updwidth,
                                convert.bpp16);
            }
          else /* bytesperpixel == 4 */
            {
              size = vnc_copy32(session, y, x, updheight, updwidth,
                                convert.bpp32);
            }

          /* Format the FramebufferUpdate message */

          update          = (FAR struct rfb_framebufferupdate_s *)session->outbuf;
          update->msgtype = RFB_FBUPDATE_MSG;
          update->padding = 0;
          rfb_putbe16(update->nrect, 1);

          rfb_putbe16(update->rect[0].xpos, x);
          rfb_putbe16(update->rect[0].ypos, y);
          rfb_putbe16(update->rect[0].width, updwidth);
          rfb_putbe16(update->rect[0].height, updheight);
          rfb_putbe32(update->rect[0].encoding, RFB_ENCODING_RAW);

          DEBUGASSERT(size <= CONFIG_VNCSERVER_UPDATE_BUFSIZE);

          /* We are ready to send the update packet to the VNC client */

          size += SIZEOF_RFB_FRAMEBUFFERUPDATE_S(SIZEOF_RFB_RECTANGE_S(0));
          src   = session->outbuf;

          /* At the very last most, make certain that the color format
           * has not changed asynchronously.
           */

          if (colorfmt == session->colorfmt)
            {
              /* Okay send until all of the bytes are out.  This may
               * loop for the case where TCP write buffering is enabled
               * and there are a limited number of IOBs available.
               */

              do
                {
                  nsent = psock_send(&session->connect, src, size, 0);
                  if (nsent < 0)
                    {
                      int errcode = get_errno();
                      gerr("ERROR: Send FrameBufferUpdate failed: %d\n",
                           errcode);
                      DEBUGASSERT(errcode > 0);
                      return -errcode;
                    }

                  DEBUGASSERT(nsent <= size);
                  src  += nsent;
                  size -= nsent;
                }
              while (size > 0);

              updinfo("Sent {(%d, %d),(%d, %d)}\n",
                      x, y, x + updwidth -1, y + updheight - 1);
            }
        }
    }

  return OK;
}
示例#10
0
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
{
  return psock_send(sockfd_socket(sockfd), buf, len, flags);
}
示例#11
0
ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
                     size_t len, int flags, FAR const struct sockaddr *to,
                     socklen_t tolen)
{
  socklen_t minlen;
#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
  ssize_t nsent;
#endif
  int err;

  /* If to is NULL or tolen is zero, then this function is same as send (for
   * connected socket types)
   */

  if (!to || !tolen)
    {
#if defined(CONFIG_NET_TCP) || defined(CONFIG_NET_LOCAL_STREAM)
      return psock_send(psock, buf, len, flags);
#else
      ndbg("ERROR: No 'to' address\n");
      err = EINVAL;
      goto errout;
#endif
    }

  /* Verify that a valid address has been provided */

  switch (to->sa_family)
    {
#ifdef CONFIG_NET_IPv4
    case AF_INET:
      minlen = sizeof(struct sockaddr_in);
      break;
#endif

#ifdef CONFIG_NET_IPv6
    case AF_INET6:
      minlen = sizeof(struct sockaddr_in6);
      break;
#endif

#ifdef CONFIG_NET_LOCAL_DGRAM
    case AF_LOCAL:
      minlen = sizeof(sa_family_t);
      break;
#endif

    default:
      ndbg("ERROR: Unrecognized address family: %d\n", to->sa_family);
      err = EAFNOSUPPORT;
      goto errout;
    }

  if (tolen < minlen)
    {
      ndbg("ERROR: Invalid address length: %d < %d\n", tolen, minlen);
      err = EBADF;
      goto errout;
    }

  /* Verify that the psock corresponds to valid, allocated socket */

  if (!psock || psock->s_crefs <= 0)
    {
      ndbg("ERROR: Invalid socket\n");
      err = EBADF;
      goto errout;
    }

  /* If this is a connected socket, then return EISCONN */

  if (psock->s_type != SOCK_DGRAM)
    {
      ndbg("ERROR: Connected socket\n");
      err = EISCONN;
      goto errout;
    }

#if defined(CONFIG_NET_UDP) || defined(CONFIG_NET_LOCAL_DGRAM)
  /* Now handle the sendto() operation according to the socket domain,
   * currently either IP or Unix domains.
   */

#ifdef CONFIG_NET_LOCAL_DGRAM
#ifdef CONFIG_NET_UDP
  if (psock->s_domain == PF_LOCAL)
#endif
    {
      nsent = psock_local_sendto(psock, buf, len, flags, to, tolen);
    }
#endif /* CONFIG_NET_LOCAL_DGRAM */

#ifdef CONFIG_NET_UDP
#ifdef CONFIG_NET_LOCAL_DGRAM
  else
#endif
    {
      nsent = psock_udp_sendto(psock, buf, len, flags, to, tolen);
    }
#endif /* CONFIG_NET_UDP */

  /* Check if the domain-specific sendto() logic failed */

  if (nsent < 0)
    {
      ndbg("ERROR: Unix domain sendto() failed: %ld\n", (long)nsent);
      err = -nsent;
      goto errout;
    }

  return nsent;
#else
  err = ENOSYS;
#endif /* CONFIG_NET_UDP || CONFIG_NET_LOCAL_DGRAM */

errout:
  set_errno(err);
  return ERROR;
}
示例#12
0
static void aio_write_worker(FAR void *arg)
{
  FAR struct aio_container_s *aioc = (FAR struct aio_container_s *)arg;
  FAR struct aiocb *aiocbp;
  pid_t pid;
#ifdef CONFIG_PRIORITY_INHERITANCE
  uint8_t prio;
#endif
  ssize_t nwritten = 0;
#ifdef AIO_HAVE_FILEP
  int oflags;
#endif

  /* Get the information from the container, decant the AIO control block,
   * and free the container before starting any I/O.  That will minimize
   * the delays by any other threads waiting for a pre-allocated container.
   */

  DEBUGASSERT(aioc && aioc->aioc_aiocbp);
  pid    = aioc->aioc_pid;
#ifdef CONFIG_PRIORITY_INHERITANCE
  prio   = aioc->aioc_prio;
#endif
  aiocbp = aioc_decant(aioc);

#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK)
  if (aiocbp->aio_fildes < CONFIG_NFILE_DESCRIPTORS)
#endif
#ifdef AIO_HAVE_FILEP
    {
      /* Call fcntl(F_GETFL) to get the file open mode. */

      oflags = file_fcntl(aioc->u.aioc_filep, F_GETFL);
      if (oflags < 0)
        {
          int errcode = get_errno();
          fdbg("ERROR: fcntl failed: %d\n", errcode);
          aiocbp->aio_result = -errcode;
          goto errout;
        }

      /* Perform the write using:
       *
       *   u.aioc_filep - File structure pointer
       *   aio_buf      - Location of buffer
       *   aio_nbytes   - Length of transfer
       *   aio_offset   - File offset
       */

      /* Check if O_APPEND is set in the file open flags */

      if ((oflags & O_APPEND) != 0)
        {
          /* Append to the current file position */

          nwritten = file_write(aioc->u.aioc_filep,
                                (FAR const void *)aiocbp->aio_buf,
                                aiocbp->aio_nbytes);
        }
      else
        {
          nwritten = file_pwrite(aioc->u.aioc_filep,
                                 (FAR const void *)aiocbp->aio_buf,
                                 aiocbp->aio_nbytes,
                                 aiocbp->aio_offset);
        }
    }
#endif
#if defined(AIO_HAVE_FILEP) && defined(AIO_HAVE_PSOCK)
  else
#endif
#ifdef AIO_HAVE_PSOCK
    {
      /* Perform the send using:
       *
       *   u.aioc_psock - Socket structure pointer
       *   aio_buf      - Location of buffer
       *   aio_nbytes   - Length of transfer
       */

      nwritten = psock_send(aioc->u.aioc_psock,
                            (FAR const void *)aiocbp->aio_buf,
                            aiocbp->aio_nbytes, 0);
    }
#endif

  /* Check the result of the write */

  if (nwritten < 0)
    {
      int errcode = get_errno();
      fdbg("ERROR: write/pwrite failed: %d\n", errcode);
      DEBUGASSERT(errcode > 0);
      aiocbp->aio_result = -errcode;
    }
  else
    {
      aiocbp->aio_result = nwritten;
    }

#ifdef AIO_HAVE_FILEP
errout:
#endif

  /* Signal the client */

  (void)aio_signal(pid, aiocbp);

#ifdef CONFIG_PRIORITY_INHERITANCE
  /* Restore the low priority worker thread default priority */

  lpwork_restorepriority(prio);
#endif
}
示例#13
0
extern int net_send_packet(int sock, t_packet const * packet, unsigned int * currsize)
{
    unsigned int size;
    int          addlen;
    
    if (!packet)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] got NULL packet (closing connection)",sock);
	return -1;
    }
    if (!currsize)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] got NULL currsize (closing connection)",sock);
	return -1;
    }
    
    if ((size = packet_get_size(packet))<1)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] packet to send is empty (skipping it)",sock);
	*currsize = 0;
	return 1;
    }
    
    addlen = psock_send(sock,
		        packet_get_raw_data_const(packet,*currsize),
		        size-*currsize,
		        0);
    
    if (addlen<0)
    {
	if (
#ifdef PSOCK_EINTR
	    psock_errno()==PSOCK_EINTR ||
#endif
#ifdef PSOCK_EAGAIN
	    psock_errno()==PSOCK_EAGAIN ||
#endif
#ifdef PSOCK_EWOULDBLOCK
	    psock_errno()==PSOCK_EWOULDBLOCK ||
#endif
#ifdef PSOCK_ENOBUFS
	    psock_errno()==PSOCK_ENOBUFS ||
#endif
#ifdef PSOCK_ENOMEM
	    psock_errno()==PSOCK_ENOMEM ||
#endif
	    0)
	    return 0; /* try again later */
	
	eventlog(eventlog_level_error,"net_send_packet","[%d] could not send data (closing connection) (psock_send: %s)",sock,strerror(psock_errno()));
	return -1;
    }
    
    if (addlen==0)
    {
	eventlog(eventlog_level_error,"net_send_packet","[%d] no data sent (closing connection)",sock);
	return -1;
    }
    
    *currsize += addlen;
    
    /* sent all data in this packet? */
    if (size==*currsize)
    {
	*currsize = 0;
	return 1;
    }
    
    return 0;
}
示例#14
0
static ssize_t telnetd_write(FAR struct file *filep, FAR const char *buffer, size_t len)
{
  FAR struct inode *inode = filep->f_inode;
  FAR struct telnetd_dev_s *priv = inode->i_private;
  FAR const char *src = buffer;
  ssize_t nsent;
  ssize_t ret;
  int ncopied;
  char ch;
  bool eol;

  nllvdbg("len: %d\n", len);

  /* Process each character from the user buffer */

  for (nsent = 0, ncopied = 0; nsent < len; nsent++)
    {
      /* Get the next character from the user buffer */

      ch = *src++;

      /* Add the character to the TX buffer */

      eol = telnetd_putchar(priv, ch, &ncopied);

      /* Was that the end of a line? Or is the buffer too full to hold the
       * next largest character sequence ("\r\n\0")?
       */

      if (eol || ncopied > CONFIG_TELNETD_TXBUFFER_SIZE-3)
        {
          /* Yes... send the data now */

          ret = psock_send(&priv->td_psock, priv->td_txbuffer, ncopied, 0);
          if (ret < 0)
            {
              nlldbg("psock_send failed '%s': %d\n", priv->td_txbuffer, ret);
              return ret;
            }

          /* Reset the index to the beginning of the TX buffer. */

          ncopied = 0;
        }
    }

  /* Send anything remaining in the TX buffer */

  if (ncopied > 0)
    {
      ret = psock_send(&priv->td_psock, priv->td_txbuffer, ncopied, 0);
      if (ret < 0)
        {
          nlldbg("psock_send failed '%s': %d\n", priv->td_txbuffer, ret);
          return ret;
        }
    }

  /* Notice that we don't actually return the number of bytes sent, but
   * rather, the number of bytes that the caller asked us to send.  We may
   * have sent more bytes (because of CR-LF expansion and because of NULL
   * termination). But it confuses some logic if you report that you sent
   * more than you were requested to.
   */

  return len;
}