forked from Archive/PX4-Autopilot
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
This commit is contained in:
parent
f60d578a46
commit
f04310d559
|
@ -188,7 +188,15 @@ int ftpd_daemon(int s_argc, char **s_argv)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = ftpd_session(handle, 5000);
|
ret = ftpd_session(handle, 5000);
|
||||||
printf("FTP daemon [%d] ftpd_session returned %d\n", g_ftpdglob.pid, ret);
|
|
||||||
|
/* If any interesting happened (i.e., any thing other than a timeout),
|
||||||
|
* then report the interesting event.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (ret != -ETIMEDOUT)
|
||||||
|
{
|
||||||
|
printf("FTP daemon [%d] ftpd_session returned %d\n", g_ftpdglob.pid, ret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close the FTPD server and exit (we can get here only if
|
/* Close the FTPD server and exit (we can get here only if
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/nettest/nettest-client.c
|
* examples/nettest/nettest-client.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -169,6 +169,11 @@ void send_client(void)
|
||||||
message("client: recv failed: %d\n", errno);
|
message("client: recv failed: %d\n", errno);
|
||||||
goto errout_with_socket;
|
goto errout_with_socket;
|
||||||
}
|
}
|
||||||
|
else if (nbytesrecvd == 0)
|
||||||
|
{
|
||||||
|
message("client: The server closed the connection\n");
|
||||||
|
goto errout_with_socket;
|
||||||
|
}
|
||||||
totalbytesrecvd += nbytesrecvd;
|
totalbytesrecvd += nbytesrecvd;
|
||||||
message("client: Received %d of %d bytes\n", totalbytesrecvd, SENDSIZE);
|
message("client: Received %d of %d bytes\n", totalbytesrecvd, SENDSIZE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/nettest/nettest-server.c
|
* examples/nettest/nettest-server.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -149,11 +149,16 @@ void recv_server(void)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
nbytesread = recv(acceptsd, buffer, 2*SENDSIZE, 0);
|
nbytesread = recv(acceptsd, buffer, 2*SENDSIZE, 0);
|
||||||
if (nbytesread <= 0)
|
if (nbytesread < 0)
|
||||||
{
|
{
|
||||||
message("server: recv failed: %d\n", errno);
|
message("server: recv failed: %d\n", errno);
|
||||||
goto errout_with_acceptsd;
|
goto errout_with_acceptsd;
|
||||||
}
|
}
|
||||||
|
else if (nbytesread == 0)
|
||||||
|
{
|
||||||
|
message("server: The client broke the connection\n");
|
||||||
|
goto errout_with_acceptsd;
|
||||||
|
}
|
||||||
message("Received %d bytes\n", nbytesread);
|
message("Received %d bytes\n", nbytesread);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -164,11 +169,16 @@ void recv_server(void)
|
||||||
{
|
{
|
||||||
message("server: Reading...\n");
|
message("server: Reading...\n");
|
||||||
nbytesread = recv(acceptsd, &buffer[totalbytesread], 2*SENDSIZE - totalbytesread, 0);
|
nbytesread = recv(acceptsd, &buffer[totalbytesread], 2*SENDSIZE - totalbytesread, 0);
|
||||||
if (nbytesread <= 0)
|
if (nbytesread < 0)
|
||||||
{
|
{
|
||||||
message("server: recv failed: %d\n", errno);
|
message("server: recv failed: %d\n", errno);
|
||||||
goto errout_with_acceptsd;
|
goto errout_with_acceptsd;
|
||||||
}
|
}
|
||||||
|
else if (nbytesread == 0)
|
||||||
|
{
|
||||||
|
message("server: The client broke the connection\n");
|
||||||
|
goto errout_with_acceptsd;
|
||||||
|
}
|
||||||
|
|
||||||
totalbytesread += nbytesread;
|
totalbytesread += nbytesread;
|
||||||
message("server: Received %d of %d bytes\n", totalbytesread, SENDSIZE);
|
message("server: Received %d of %d bytes\n", totalbytesread, SENDSIZE);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/poll/host.c
|
* examples/poll/host.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -137,6 +137,11 @@ int main(int argc, char **argv, char **envp)
|
||||||
message("client: recv failed: %d\n", errno);
|
message("client: recv failed: %d\n", errno);
|
||||||
goto errout_with_socket;
|
goto errout_with_socket;
|
||||||
}
|
}
|
||||||
|
else if (nbytesrecvd == 0)
|
||||||
|
{
|
||||||
|
message("client: The server broke the connections\n");
|
||||||
|
goto errout_with_socket;
|
||||||
|
}
|
||||||
|
|
||||||
inbuf[nbytesrecvd] = '\0';
|
inbuf[nbytesrecvd] = '\0';
|
||||||
message("client: Received '%s' (%d bytes)\n", inbuf, nbytesrecvd);
|
message("client: Received '%s' (%d bytes)\n", inbuf, nbytesrecvd);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/poll/net_listener.c
|
* examples/poll/net_listener.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/poll/net_reader.c
|
* examples/poll/net_reader.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* examples/udp/udp-server.c
|
* examples/udp/udp-server.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* netutils/dhcpc/dhcpc.c
|
* netutils/dhcpc/dhcpc.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Based heavily on portions of uIP:
|
* Based heavily on portions of uIP:
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* netutils/dhcpd/dhcpd.c
|
* netutils/dhcpd/dhcpd.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
|
|
@ -796,7 +796,7 @@ static int ftpd_rxpoll(int sd, int timeout)
|
||||||
|
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
nvdbg("poll() timed out\n");
|
//nvdbg("poll() timed out\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
else if (ret < 0)
|
else if (ret < 0)
|
||||||
|
@ -870,7 +870,14 @@ static int ftpd_accept(int sd, FAR void *addr, FAR socklen_t *addrlen,
|
||||||
ret = ftpd_rxpoll(sd, timeout);
|
ret = ftpd_rxpoll(sd, timeout);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
nvdbg("ftpd_rxpoll() failed: %d\n", ret);
|
/* Only report interesting, infrequent errors (not the common timeout) */
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_NET
|
||||||
|
if (ret != -ETIMEDOUT)
|
||||||
|
{
|
||||||
|
ndbg("ftpd_rxpoll() failed: %d\n", ret);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,34 +916,18 @@ static ssize_t ftpd_recv(int sd, FAR void *data, size_t size, int timeout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Receive the data... waiting if necessary */
|
/* Receive the data... waiting if necessary. The client side will break the
|
||||||
|
* connection after the file has been sent. Zero (end-of-file) should be
|
||||||
|
* received in this case.
|
||||||
|
*/
|
||||||
|
|
||||||
ret = recv(sd, data, size, 0);
|
ret = recv(sd, data, size, 0);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
int errval = errno;
|
int errval = errno;
|
||||||
|
|
||||||
/* Special case some TCP read errors. The client side will break the
|
ndbg("recv() failed: %d\n", errval);
|
||||||
* connection after the file has been sent.
|
return -errval;
|
||||||
*/
|
|
||||||
#warning FIXME
|
|
||||||
/* When the client breaks the connection, the NuttX socket layer will
|
|
||||||
* return an error with errno == ENOTCONN. This is wrong! It should
|
|
||||||
* return 0 (end-of-file) in that case! We work around the bug and
|
|
||||||
* report end-of-file for that case here. This needs to be fixed
|
|
||||||
* someday.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (errval == ENOTCONN)
|
|
||||||
{
|
|
||||||
nvdbg("Connection lost, returning end-of-file\n");
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ndbg("recv() failed: %d\n", errval);
|
|
||||||
return -errval;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -4342,7 +4333,14 @@ int ftpd_session(FTPD_SESSION handle, int timeout)
|
||||||
&session->cmd.addrlen, timeout);
|
&session->cmd.addrlen, timeout);
|
||||||
if (session->cmd.sd < 0)
|
if (session->cmd.sd < 0)
|
||||||
{
|
{
|
||||||
ndbg("ftpd_accept() failed: %d\n", session->cmd.sd);
|
/* Only report interesting, infrequent errors (not the common timeout) */
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_NET
|
||||||
|
if (session->cmd.sd != -ETIMEDOUT)
|
||||||
|
{
|
||||||
|
ndbg("ftpd_accept() failed: %d\n", session->cmd.sd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
ret = session->cmd.sd;
|
ret = session->cmd.sd;
|
||||||
goto errout_with_session;
|
goto errout_with_session;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
* the resolver code calls a callback function called resolv_found()
|
* the resolver code calls a callback function called resolv_found()
|
||||||
* that must be implemented by the module that uses the resolver.
|
* that must be implemented by the module that uses the resolver.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Based heavily on portions of uIP:
|
* Based heavily on portions of uIP:
|
||||||
*
|
*
|
||||||
|
|
|
@ -234,7 +234,7 @@ int tftpget(const char *remote, const char *local, in_addr_t addr, bool binary)
|
||||||
|
|
||||||
/* Check if anything valid was received */
|
/* Check if anything valid was received */
|
||||||
|
|
||||||
if (nbytesrecvd >= 0)
|
if (nbytesrecvd > 0)
|
||||||
{
|
{
|
||||||
/* Verify the sender address and port number */
|
/* Verify the sender address and port number */
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* netuils/tftp/tftpc_packets.c
|
* netuils/tftp/tftpc_packets.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2008-2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2008-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
@ -217,9 +217,17 @@ static int tftp_rcvack(int sd, uint8_t *packet, struct sockaddr_in *server,
|
||||||
{
|
{
|
||||||
/* Failed to receive a good packet */
|
/* Failed to receive a good packet */
|
||||||
|
|
||||||
if (nbytes >= 0)
|
if (nbytes == 0)
|
||||||
{
|
{
|
||||||
ndbg("tftp_recvfrom short packet: %d bytes\n", nbytes);
|
ndbg("Connection lost: %d bytes\n", nbytes);
|
||||||
|
}
|
||||||
|
else if (nbytes > 0)
|
||||||
|
{
|
||||||
|
ndbg("Short packet: %d bytes\n", nbytes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ndbg("Recveid failure\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Break out to bump up the retry count */
|
/* Break out to bump up the retry count */
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* netutils/webclient/webclient.c
|
* netutils/webclient/webclient.c
|
||||||
* Implementation of the HTTP client.
|
* Implementation of the HTTP client.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007, 2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Based on uIP which also has a BSD style license:
|
* Based on uIP which also has a BSD style license:
|
||||||
*
|
*
|
||||||
|
@ -526,6 +526,7 @@ int wget(FAR const char *url, FAR char *buffer, int buflen,
|
||||||
}
|
}
|
||||||
else if (ret == 0)
|
else if (ret == 0)
|
||||||
{
|
{
|
||||||
|
nvdbg("Connection lost\n");
|
||||||
close(sockfd);
|
close(sockfd);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
* netutils/webserver/httpd.c
|
* netutils/webserver/httpd.c
|
||||||
* httpd Web server
|
* httpd Web server
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2009, 2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2009, 2011-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* This is a leverage of similar logic from uIP:
|
* This is a leverage of similar logic from uIP:
|
||||||
*
|
*
|
||||||
|
@ -380,6 +380,11 @@ static inline int httpd_cmd(struct httpd_state *pstate)
|
||||||
ndbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);
|
ndbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
|
lese if (recvlen == 0)
|
||||||
|
{
|
||||||
|
ndbg("[%d] connection lost\n", pstate->ht_sockfd);
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
httpd_dumpbuffer("Incoming buffer", pstate->ht_buffer, recvlen);
|
httpd_dumpbuffer("Incoming buffer", pstate->ht_buffer, recvlen);
|
||||||
|
|
||||||
/* We will handle only GET */
|
/* We will handle only GET */
|
||||||
|
|
|
@ -2467,3 +2467,5 @@
|
||||||
a lower-half quadrature encoder driver for the STM32. On initial check-in,
|
a lower-half quadrature encoder driver for the STM32. On initial check-in,
|
||||||
this is little more than a "skeleton" file.
|
this is little more than a "skeleton" file.
|
||||||
* Various files: CAN ISO-11783 support contributed by Gary Teravskis.
|
* Various files: CAN ISO-11783 support contributed by Gary Teravskis.
|
||||||
|
* net/recv.c and net/recvfrom.c: Correct a bug in return value: The the peer
|
||||||
|
gracefully closes the connections, needs to return zero and not ENOTCONN
|
|
@ -13,7 +13,7 @@
|
||||||
<h1><big><font color="#3c34ec"><i>NuttX Operating System<p>User's Manual</i></font></big></h1>
|
<h1><big><font color="#3c34ec"><i>NuttX Operating System<p>User's Manual</i></font></big></h1>
|
||||||
<p><small>by</small></p>
|
<p><small>by</small></p>
|
||||||
<p>Gregory Nutt<p>
|
<p>Gregory Nutt<p>
|
||||||
<p>Last Updated: December 5, 2011</p>
|
<p>Last Updated: February 18, 2011</p>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
@ -7391,8 +7391,7 @@ Those socket APIs are discussed in the following paragraphs.</p>
|
||||||
</ul>
|
</ul>
|
||||||
<p>
|
<p>
|
||||||
<b>Returned Values:</b>
|
<b>Returned Values:</b>
|
||||||
see <a href="#recvfrom"><code>recvfrom()</code></a>.
|
See <a href="#recvfrom"><code>recvfrom()</code></a>.
|
||||||
Zero on success.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<h3><a name="recvfrom">2.12.9 <code>recvfrom</code></a></h3>
|
<h3><a name="recvfrom">2.12.9 <code>recvfrom</code></a></h3>
|
||||||
|
@ -7429,7 +7428,8 @@ Those socket APIs are discussed in the following paragraphs.</p>
|
||||||
<p>
|
<p>
|
||||||
<b>Returned Values:</b>
|
<b>Returned Values:</b>
|
||||||
On success, returns the number of characters sent.
|
On success, returns the number of characters sent.
|
||||||
On error, -1 is returned, and <a href="#ErrnoAccess"><code>errno</code></a> is set appropriately:
|
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 <a href="#ErrnoAccess"><code>errno</code></a> is set appropriately:
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>EAGAIN</code>.
|
<li><code>EAGAIN</code>.
|
||||||
|
|
16
nuttx/TODO
16
nuttx/TODO
|
@ -13,7 +13,7 @@ nuttx/
|
||||||
(1) pthreads (sched/)
|
(1) pthreads (sched/)
|
||||||
(2) C++ Support
|
(2) C++ Support
|
||||||
(5) Binary loaders (binfmt/)
|
(5) Binary loaders (binfmt/)
|
||||||
(18) Network (net/, drivers/net)
|
(17) Network (net/, drivers/net)
|
||||||
(2) USB (drivers/usbdev, drivers/usbhost)
|
(2) USB (drivers/usbdev, drivers/usbhost)
|
||||||
(8) Libraries (lib/)
|
(8) Libraries (lib/)
|
||||||
(10) File system/Generic drivers (fs/, drivers/)
|
(10) File system/Generic drivers (fs/, drivers/)
|
||||||
|
@ -437,20 +437,8 @@ o Network (net/, drivers/net)
|
||||||
Status: Open
|
Status: Open
|
||||||
Priority: Low unless you need it.
|
Priority: Low unless you need it.
|
||||||
|
|
||||||
Title: RECV/RECVFROM RETURN VALUE
|
|
||||||
Description: If the peer performs an orderly shutdown, then recvfrom currently returns
|
|
||||||
an error with errno set to ENOTCONN. This is wrong. There is a fine
|
|
||||||
distinction. The ENOTCONN errno is intended for the case where the socket
|
|
||||||
was never connected. In the case were the socket was connected then the
|
|
||||||
peer performs an order shutdown: "...If no messages are available to be
|
|
||||||
received and the peer has performed an orderly shutdown, recv() shall
|
|
||||||
return 0. ..."
|
|
||||||
Status: Open and there is a kludge in apps/netutils/ftpd/ftpdc.c work around this
|
|
||||||
bad return value.
|
|
||||||
Priority: Medium
|
|
||||||
|
|
||||||
o USB (drivers/usbdev, drivers/usbhost)
|
o USB (drivers/usbdev, drivers/usbhost)
|
||||||
^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
Title: USB STORAGE DRIVER DELAYS
|
Title: USB STORAGE DRIVER DELAYS
|
||||||
Description: There is a workaround for a bug in drivers/usbdev/usbdev_storage.c.
|
Description: There is a workaround for a bug in drivers/usbdev/usbdev_storage.c.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* net/accept.c
|
* net/accept.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2007-2011 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2007-2012 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
@ -441,6 +441,7 @@ int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)
|
||||||
pnewsock->s_type = SOCK_STREAM;
|
pnewsock->s_type = SOCK_STREAM;
|
||||||
pnewsock->s_conn = state.acpt_newconn;
|
pnewsock->s_conn = state.acpt_newconn;
|
||||||
pnewsock->s_flags |= _SF_CONNECTED;
|
pnewsock->s_flags |= _SF_CONNECTED;
|
||||||
|
pnewsock->s_flags &= ~_SF_CLOSED;
|
||||||
return newfd;
|
return newfd;
|
||||||
|
|
||||||
errout_with_lock:
|
errout_with_lock:
|
||||||
|
|
|
@ -116,15 +116,37 @@ static void connection_event(struct uip_conn *conn, uint16_t flags)
|
||||||
{
|
{
|
||||||
nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags);
|
nllvdbg("flags: %04x s_flags: %02x\n", flags, psock->s_flags);
|
||||||
|
|
||||||
/* UIP_CLOSE: The remote host has closed the connection
|
/* These loss-of-connection events may be reported:
|
||||||
* UIP_ABORT: The remote host has aborted the connection
|
*
|
||||||
* UIP_TIMEDOUT: Connection aborted due to too many retransmissions.
|
* 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.
|
||||||
|
*
|
||||||
|
* And we need to set these two socket status bits appropriately:
|
||||||
|
*
|
||||||
|
* _SF_CONNECTED==1 && _SF_CLOSED==0 - the socket is connected
|
||||||
|
* _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was gracefully disconnected
|
||||||
|
* _SF_CONNECTED==0 && _SF_CLOSED==0 - the socket was rudely disconnected
|
||||||
*/
|
*/
|
||||||
if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
|
||||||
|
if ((flags & UIP_CLOSE) != 0)
|
||||||
{
|
{
|
||||||
/* Indicate that the socket is no longer connected */
|
/* The peer gracefully closed the connection. Marking the
|
||||||
|
* connection as disconnected will suppress some subsequent
|
||||||
|
* ENOTCONN errors from receive. A graceful disconnection is
|
||||||
|
* not handle as an error but as an "end-of-file"
|
||||||
|
*/
|
||||||
|
|
||||||
psock->s_flags &= ~_SF_CONNECTED;
|
psock->s_flags &= ~_SF_CONNECTED;
|
||||||
|
psock->s_flags |= _SF_CLOSED;
|
||||||
|
}
|
||||||
|
else if ((flags & (UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
||||||
|
{
|
||||||
|
/* The loss of connection was less than graceful. This will (eventually)
|
||||||
|
* be reported as an ENOTCONN error.
|
||||||
|
*/
|
||||||
|
|
||||||
|
psock->s_flags &= ~(_SF_CONNECTED |_SF_CLOSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* UIP_CONNECTED: The socket is successfully connected */
|
/* UIP_CONNECTED: The socket is successfully connected */
|
||||||
|
@ -134,6 +156,7 @@ static void connection_event(struct uip_conn *conn, uint16_t flags)
|
||||||
/* Indicate that the socket is now connected */
|
/* Indicate that the socket is now connected */
|
||||||
|
|
||||||
psock->s_flags |= _SF_CONNECTED;
|
psock->s_flags |= _SF_CONNECTED;
|
||||||
|
psock->s_flags &= ~_SF_CLOSED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,16 +57,25 @@
|
||||||
/* Definitions of 8-bit socket flags */
|
/* Definitions of 8-bit socket flags */
|
||||||
|
|
||||||
/* Bits 0-2: Socket state */
|
/* Bits 0-2: Socket state */
|
||||||
#define _SF_IDLE 0x00 /* There is no socket activity */
|
#define _SF_IDLE 0x00 /* - There is no socket activity */
|
||||||
#define _SF_ACCEPT 0x01 /* Socket is waiting to accept a connection */
|
#define _SF_ACCEPT 0x01 /* - Socket is waiting to accept a connection */
|
||||||
#define _SF_RECV 0x02 /* Waiting for recv action to complete */
|
#define _SF_RECV 0x02 /* - Waiting for recv action to complete */
|
||||||
#define _SF_SEND 0x03 /* Waiting for send action to complete */
|
#define _SF_SEND 0x03 /* - Waiting for send action to complete */
|
||||||
#define _SF_MASK 0x03 /* Mask to isolate the above actions */
|
#define _SF_MASK 0x03 /* - Mask to isolate the above actions */
|
||||||
/* Bit 3: unused */
|
|
||||||
#define _SF_NONBLOCK 0x10 /* Bit 4: Don't block if no data (TCP/READ only) */
|
#define _SF_NONBLOCK 0x08 /* Bit 3: Don't block if no data (TCP/READ only) */
|
||||||
#define _SF_LISTENING 0x20 /* Bit 5: SOCK_STREAM is listening */
|
#define _SF_LISTENING 0x10 /* Bit 4: SOCK_STREAM is listening */
|
||||||
#define _SF_BOUND 0x40 /* Bit 6: SOCK_STREAM is bound to an address */
|
#define _SF_BOUND 0x20 /* Bit 5: SOCK_STREAM is bound to an address */
|
||||||
#define _SF_CONNECTED 0x80 /* Bit 7: SOCK_STREAM is connected */
|
/* Bits 6-7: Connection state */
|
||||||
|
#define _SF_CONNECTED 0x40 /* Bit 6: SOCK_STREAM is connected */
|
||||||
|
#define _SF_CLOSED 0x80 /* Bit 7: SOCK_STREAM was gracefully disconnected */
|
||||||
|
|
||||||
|
/* Connection state encoding:
|
||||||
|
*
|
||||||
|
* _SF_CONNECTED==1 && _SF_CLOSED==0 - the socket is connected
|
||||||
|
* _SF_CONNECTED==0 && _SF_CLOSED==1 - the socket was gracefully disconnected
|
||||||
|
* _SF_CONNECTED==0 && _SF_CLOSED==0 - the socket was rudely disconnected
|
||||||
|
*/
|
||||||
|
|
||||||
/* Macro to manage the socket state and flags */
|
/* Macro to manage the socket state and flags */
|
||||||
|
|
||||||
|
@ -78,6 +87,7 @@
|
||||||
#define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0)
|
#define _SS_ISLISTENING(s) (((s) & _SF_LISTENING) != 0)
|
||||||
#define _SS_ISBOUND(s) (((s) & _SF_CONNECTED) != 0)
|
#define _SS_ISBOUND(s) (((s) & _SF_CONNECTED) != 0)
|
||||||
#define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0)
|
#define _SS_ISCONNECTED(s) (((s) & _SF_CONNECTED) != 0)
|
||||||
|
#define _SS_ISCLOSED(s) (((s) & _SF_CLOSED) != 0)
|
||||||
|
|
||||||
/* This macro converts a socket option value into a bit setting */
|
/* This macro converts a socket option value into a bit setting */
|
||||||
|
|
||||||
|
|
|
@ -419,7 +419,12 @@ static uint16_t recvfrom_tcpinterrupt(struct uip_driver_s *dev, void *conn,
|
||||||
#endif
|
#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)
|
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->priv = NULL;
|
||||||
pstate->rf_cb->event = 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 */
|
/* 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);
|
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
|
/* No data has been received -- this is some other event... probably a
|
||||||
* poll -- check for a timeout.
|
* 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)
|
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;
|
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 */
|
/* 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->priv = (void*)&state;
|
||||||
state.rf_cb->event = recvfrom_udpinterrupt;
|
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))
|
if (!_SS_ISCONNECTED(psock->s_flags))
|
||||||
{
|
{
|
||||||
/* Was any data transferred from the readahead buffer after we were
|
/* 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 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
|
#endif
|
||||||
{
|
{
|
||||||
/* Nothing was previously received from the readahead buffers.
|
/* 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
|
* fromlen The length of the address structure
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* On success, returns the number of characters sent. On error,
|
* On success, returns the number of characters sent. If no data is
|
||||||
* -1 is returned, and errno is set appropriately:
|
* 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
|
* EAGAIN
|
||||||
* The socket is marked non-blocking and the receive operation would block,
|
* The socket is marked non-blocking and the receive operation would block,
|
||||||
|
|
|
@ -103,22 +103,13 @@ static uint16_t sendto_interrupt(struct uip_driver_s *dev, void *conn,
|
||||||
nllvdbg("flags: %04x\n", flags);
|
nllvdbg("flags: %04x\n", flags);
|
||||||
if (pstate)
|
if (pstate)
|
||||||
{
|
{
|
||||||
/* Check if the connection was rejected */
|
|
||||||
|
|
||||||
if ((flags & (UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT)) != 0)
|
|
||||||
{
|
|
||||||
/* Yes.. then terminate with an error */
|
|
||||||
|
|
||||||
pstate->st_sndlen = -ENOTCONN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if the outgoing packet is available (it may have been claimed
|
/* Check if the outgoing packet is available (it may have been claimed
|
||||||
* by a sendto interrupt serving a different thread -OR- if the output
|
* by a sendto interrupt serving a different thread -OR- if the output
|
||||||
* buffer currently contains unprocessed incoming data. In these cases
|
* buffer currently contains unprocessed incoming data. In these cases
|
||||||
* we will just have to wait for the next polling cycle.
|
* we will just have to wait for the next polling cycle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
else if (dev->d_sndlen > 0 || (flags & UIP_NEWDATA) != 0)
|
if (dev->d_sndlen > 0 || (flags & UIP_NEWDATA) != 0)
|
||||||
{
|
{
|
||||||
/* Another thread has beat us sending data or the buffer is busy,
|
/* Another thread has beat us sending data or the buffer is busy,
|
||||||
* wait for the next polling cycle
|
* wait for the next polling cycle
|
||||||
|
@ -314,7 +305,7 @@ ssize_t psock_sendto(FAR struct socket *psock, FAR const void *buf,
|
||||||
state.st_cb = uip_udpcallbackalloc(conn);
|
state.st_cb = uip_udpcallbackalloc(conn);
|
||||||
if (state.st_cb)
|
if (state.st_cb)
|
||||||
{
|
{
|
||||||
state.st_cb->flags = UIP_POLL|UIP_CLOSE|UIP_ABORT|UIP_TIMEDOUT;
|
state.st_cb->flags = UIP_POLL;
|
||||||
state.st_cb->priv = (void*)&state;
|
state.st_cb->priv = (void*)&state;
|
||||||
state.st_cb->event = sendto_interrupt;
|
state.st_cb->event = sendto_interrupt;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue