diff options
author | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-02-18 18:13:30 +0000 |
---|---|---|
committer | patacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679> | 2012-02-18 18:13:30 +0000 |
commit | f04310d55941bf5e4db3a71a5d3eaca6a6f89616 (patch) | |
tree | ca4c58d32d12949e8d08cb69a652b5e3f7fd0e58 /nuttx/net/recvfrom.c | |
parent | f60d578a461ee991f5eb42f9ae0dd2e7def75f75 (diff) | |
download | px4-firmware-f04310d55941bf5e4db3a71a5d3eaca6a6f89616.tar.gz px4-firmware-f04310d55941bf5e4db3a71a5d3eaca6a6f89616.tar.bz2 px4-firmware-f04310d55941bf5e4db3a71a5d3eaca6a6f89616.zip |
Correct and error in recv() and recvfrom() return value
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@4402 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'nuttx/net/recvfrom.c')
-rw-r--r-- | nuttx/net/recvfrom.c | 66 |
1 files changed, 36 insertions, 30 deletions
diff --git a/nuttx/net/recvfrom.c b/nuttx/net/recvfrom.c index f1f08d66d..aabfcedfd 100644 --- a/nuttx/net/recvfrom.c +++ b/nuttx/net/recvfrom.c @@ -419,7 +419,12 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn, #endif } - /* Check for a loss of connection */ + /* Check for a loss of connection. + * + * UIP_CLOSE: The remote host has closed the connection + * UIP_ABORT: The remote host has aborted the connection + * UIP_TIMEDOUT: Connection aborted due to too many retransmissions. + */ else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) { @@ -431,9 +436,18 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn, pstate->rf_cb->priv = NULL; pstate->rf_cb->event = NULL; - /* Report not connected */ + /* If the peer gracefully closed the connection, then return zero + * (end-of-file). Otherwise, report a not-connected error + */ - pstate->rf_result = -ENOTCONN; + if ((flags & UIP_CLOSE) != 0) + { + pstate->rf_result = 0; + } + else + { + pstate->rf_result = -ENOTCONN; + } /* Wake up the waiting thread */ @@ -585,27 +599,6 @@ static uint16_t recvfrom_udpinterrupt(struct uip_driver_s *dev, void *pvconn, sem_post(&pstate->rf_sem); } - /* Check for a loss of connection */ - - else if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0) - { - nllvdbg("error\n"); - - /* Stop further callbacks */ - - pstate->rf_cb->flags = 0; - pstate->rf_cb->priv = NULL; - pstate->rf_cb->event = NULL; - - /* Report not connected */ - - pstate->rf_result = -ENOTCONN; - - /* Wake up the waiting thread */ - - sem_post(&pstate->rf_sem); - } - /* No data has been received -- this is some other event... probably a * poll -- check for a timeout. */ @@ -719,7 +712,9 @@ static ssize_t recvfrom_result(int result, struct recvfrom_s *pstate) if (pstate->rf_result < 0) { - /* Return EGAIN on a timeout or ENOTCONN on loss of connection */ + /* This might return EGAIN on a timeout or ENOTCONN on loss of + * connection (TCP only) + */ return pstate->rf_result; } @@ -796,7 +791,7 @@ static ssize_t udp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, { /* Set up the callback in the connection */ - state.rf_cb->flags = UIP_NEWDATA|UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT; + state.rf_cb->flags = UIP_NEWDATA|UIP_POLL; state.rf_cb->priv = (void*)&state; state.rf_cb->event = recvfrom_udpinterrupt; @@ -900,11 +895,20 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, if (!_SS_ISCONNECTED(psock->s_flags)) { /* Was any data transferred from the readahead buffer after we were - * disconnected? + * disconnected? If so, then return the number of bytes received. We + * will wait to return end disconnection indications the next time that + * recvfrom() is called. + * + * If no data was received (i.e., ret == 0 -- it will not be negative) + * and the connection was gracefully closed by the remote peer, then return + * success. If rf_recvlen is zero, the caller of recvfrom() will get an + * end-of-file indication. */ #if CONFIG_NET_NTCP_READAHEAD_BUFFERS > 0 - if (ret <= 0) + if (ret <= 0 && !_SS_ISCLOSED(psock->s_flags)) +#else + if (!_SS_ISCLOSED(psock->s_flags)) #endif { /* Nothing was previously received from the readahead buffers. @@ -1008,8 +1012,10 @@ static ssize_t tcp_recvfrom(FAR struct socket *psock, FAR void *buf, size_t len, * fromlen The length of the address structure * * Returned Value: - * On success, returns the number of characters sent. On error, - * -1 is returned, and errno is set appropriately: + * On success, returns the number of characters sent. If no data is + * available to be received and the peer has performed an orderly shutdown, + * recv() will return 0. Othwerwise, on errors, -1 is returned, and errno + * is set appropriately: * * EAGAIN * The socket is marked non-blocking and the receive operation would block, |