src/raw_sock.c
static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
{
	int ret, done = 0;
	int try = count;

	if (unlikely(!(fdtab[conn->t.sock.fd].ev & FD_POLL_IN))) {
		/* stop here if we reached the end of data */
		if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP)
			goto read0;

		/* report error on POLL_ERR before connection establishment */
		if ((fdtab[conn->t.sock.fd].ev & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) {
			conn->flags |= CO_FL_ERROR;
			return done;
		}
	}

	/* compute the maximum block size we can read at once. */
	if (buffer_empty(buf)) {
		/* let's realign the buffer to optimize I/O */
		buf->p = buf->data;
	}
	else if (buf->data + buf->o < buf->p &&
		 buf->p + buf->i < buf->data + buf->size) {
		/* remaining space wraps at the end, with a moving limit */
		if (try > buf->data + buf->size - (buf->p + buf->i))
			try = buf->data + buf->size - (buf->p + buf->i);
	}

	/* read the largest possible block. For this, we perform only one call
	 * to recv() unless the buffer wraps and we exactly fill the first hunk,
	 * in which case we accept to do it once again. A new attempt is made on
	 * EINTR too.
	 */
	while (try) {
		ret = recv(conn->t.sock.fd, bi_end(buf), try, 0);

		if (ret > 0) {
			buf->i += ret;
			done += ret;
			if (ret < try) {
				/* unfortunately, on level-triggered events, POLL_HUP
				 * is generally delivered AFTER the system buffer is
				 * empty, so this one might never match.
				 */
				if (fdtab[conn->t.sock.fd].ev & FD_POLL_HUP)
					goto read0;
				break;
			}
			count -= ret;
			try = count;
		}
		else if (ret == 0) {
			goto read0;
		}
		else if (errno == EAGAIN) {
			__conn_data_poll_recv(conn);
			break;
		}
		else if (errno != EINTR) {
			conn->flags |= CO_FL_ERROR;
			break;
		}
	}

	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done)
		conn->flags &= ~CO_FL_WAIT_L4_CONN;
	return done;

 read0:
	conn_sock_read0(conn);
	conn->flags &= ~CO_FL_WAIT_L4_CONN;

	/* Now a final check for a possible asynchronous low-level error
	 * report. This can happen when a connection receives a reset
	 * after a shutdown, both POLL_HUP and POLL_ERR are queued, and
	 * we might have come from there by just checking POLL_HUP instead
	 * of recv()'s return value 0, so we have no way to tell there was
	 * an error without checking.
	 */
	if (unlikely(fdtab[conn->t.sock.fd].ev & FD_POLL_ERR))
		conn->flags |= CO_FL_ERROR;
	return done;
}
/* Receive up to <count> bytes from connection <conn>'s socket and store them
 * into buffer <buf>. The caller must ensure that <count> is always smaller
 * than the buffer's size. Only one call to recv() is performed, unless the
 * buffer wraps, in which case a second call may be performed. The connection's
 * flags are updated with whatever special event is detected (error, read0,
 * empty). The caller is responsible for taking care of those events and
 * avoiding the call if inappropriate. The function does not call the
 * connection's polling update function, so the caller is responsible for this.
 */
Receive up to  bytes from connection 's socket and store them
into buffer . The caller must ensure that  is always smaller
than the buffer's size. Only one call to recv() is performed, unless the
buffer wraps, in which case a second call may be performed. The connection's
flags are updated with whatever special event is detected (error, read0,
empty). The caller is responsible for taking care of those events and
avoiding the call if inappropriate. The function does not call the
connection's polling update function, so the caller is responsible for this.
Receive up to bytes from connection ' s socket and store them into buffer . The caller must ensure that is always smaller than the buffer ' s size . Only one call to recv () is performed unless the buffer wraps in which case a second call may be performed . The connection ' s flags are updated with whatever special event is detected ( error read0 empty ) . The caller is responsible for taking care of those events and avoiding the call if inappropriate . The function does not call the connection ' s polling update function so the caller is responsible for this .
static int raw_sock_to_buf(struct connection *conn, struct buffer *buf, int count)
{
	int ret, done = 0;
	int try = count;
	if (unlikely(!(fdtab[conn->t.sock.fd].ev & FD_POLL_IN))) {
		if ((fdtab[conn->t.sock.fd].ev & (FD_POLL_ERR|FD_POLL_HUP)) == FD_POLL_HUP)
			goto read0;
		if ((fdtab[conn->t.sock.fd].ev & FD_POLL_ERR) && (conn->flags & CO_FL_WAIT_L4_CONN)) {
			conn->flags |= CO_FL_ERROR;
			return done;
		}
	}
	if (buffer_empty(buf)) {
		buf->p = buf->data;
	}
	else if (buf->data + buf->o < buf->p &&
		 buf->p + buf->i < buf->data + buf->size) {
		if (try > buf->data + buf->size - (buf->p + buf->i))
			try = buf->data + buf->size - (buf->p + buf->i);
	}
	while (try) {
		ret = recv(conn->t.sock.fd, bi_end(buf), try, 0);
		if (ret > 0) {
			buf->i += ret;
			done += ret;
			if (ret < try) {
				if (fdtab[conn->t.sock.fd].ev & FD_POLL_HUP)
					goto read0;
				break;
			}
			count -= ret;
			try = count;
		}
		else if (ret == 0) {
			goto read0;
		}
		else if (errno == EAGAIN) {
			__conn_data_poll_recv(conn);
			break;
		}
		else if (errno != EINTR) {
			conn->flags |= CO_FL_ERROR;
			break;
		}
	}
	if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done)
		conn->flags &= ~CO_FL_WAIT_L4_CONN;
	return done;
 read0:
	conn_sock_read0(conn);
	conn->flags &= ~CO_FL_WAIT_L4_CONN;
	if (unlikely(fdtab[conn->t.sock.fd].ev & FD_POLL_ERR))
		conn->flags |= CO_FL_ERROR;
	return done;
}
static int raw_sock_to_buf ( struct connection * conn , struct buffer * buf , int count ) { int ret , done = 0 ; int try = count ; if ( unlikely ( ! ( fdtab [ conn -> t . sock . fd ] . ev & FD_POLL_IN ) ) ) { if ( ( fdtab [ conn -> t . sock . fd ] . ev & ( FD_POLL_ERR | FD_POLL_HUP ) ) == FD_POLL_HUP ) goto read0 ; if ( ( fdtab [ conn -> t . sock . fd ] . ev & FD_POLL_ERR ) && ( conn -> flags & CO_FL_WAIT_L4_CONN ) ) { conn -> flags |= CO_FL_ERROR ; return done ; } } if ( buffer_empty ( buf ) ) { buf -> p = buf -> data ; } else if ( buf -> data + buf -> o < buf -> p && buf -> p + buf -> i < buf -> data + buf -> size ) { if ( try > buf -> data + buf -> size - ( buf -> p + buf -> i ) ) try = buf -> data + buf -> size - ( buf -> p + buf -> i ) ; } while ( try ) { ret = recv ( conn -> t . sock . fd , bi_end ( buf ) , try , 0 ) ; if ( ret > 0 ) { buf -> i += ret ; done += ret ; if ( ret < try ) { if ( fdtab [ conn -> t . sock . fd ] . ev & FD_POLL_HUP ) goto read0 ; break ; } count -= ret ; try = count ; } else if ( ret == 0 ) { goto read0 ; } else if ( errno == EAGAIN ) { __conn_data_poll_recv ( conn ) ; break ; } else if ( errno != EINTR ) { conn -> flags |= CO_FL_ERROR ; break ; } } if ( unlikely ( conn -> flags & CO_FL_WAIT_L4_CONN ) && done ) conn -> flags &= ~ CO_FL_WAIT_L4_CONN ; return done ; read0 : conn_sock_read0 ( conn ) ; conn -> flags &= ~ CO_FL_WAIT_L4_CONN ; if ( unlikely ( fdtab [ conn -> t . sock . fd ] . ev & FD_POLL_ERR ) ) conn -> flags |= CO_FL_ERROR ; return done ; }
Receive up to <count> bytes from connection <conn>'s socket and store them
 into buffer <buf>.
Receive up to <count > bytes from connection <conn > ' s socket and store them into buffer <buf > .
/* stop here if we reached the end of data */ /* report error on POLL_ERR before connection establishment */ /* compute the maximum block size we can read at once. */ /* let's realign the buffer to optimize I/O */ /* remaining space wraps at the end, with a moving limit */ /* read the largest possible block. For this, we perform only one call
	 * to recv() unless the buffer wraps and we exactly fill the first hunk,
	 * in which case we accept to do it once again. A new attempt is made on
	 * EINTR too.
	 */ /* unfortunately, on level-triggered events, POLL_HUP
				 * is generally delivered AFTER the system buffer is
				 * empty, so this one might never match.
				 */ /* Now a final check for a possible asynchronous low-level error
	 * report. This can happen when a connection receives a reset
	 * after a shutdown, both POLL_HUP and POLL_ERR are queued, and
	 * we might have come from there by just checking POLL_HUP instead
	 * of recv()'s return value 0, so we have no way to tell there was
	 * an error without checking.
	 */