diff options
author | Andy Wingo <wingo@pobox.com> | 2016-06-02 22:37:34 +0200 |
---|---|---|
committer | Andy Wingo <wingo@pobox.com> | 2016-06-09 10:59:08 +0200 |
commit | e6cc051f8c3f6851be4f51ccb14109d03ae867ba (patch) | |
tree | b2039d5c292787677ff0aa0fa60209328a1b1309 | |
parent | d8067213dc3728a37c3c60d15aa0f1113d2e8daa (diff) | |
download | guile-e6cc051f8c3f6851be4f51ccb14109d03ae867ba.tar.gz |
`accept' on nonblocking socket can return #f
* doc/ref/posix.texi (Network Sockets and Communication):
* libguile/socket.c (scm_accept): Return #f if the socket is nonblocking
and no connection is ready.
-rw-r--r-- | doc/ref/posix.texi | 25 | ||||
-rw-r--r-- | libguile/socket.c | 25 |
2 files changed, 32 insertions, 18 deletions
diff --git a/doc/ref/posix.texi b/doc/ref/posix.texi index edcff9dc2..4d2a850cf 100644 --- a/doc/ref/posix.texi +++ b/doc/ref/posix.texi @@ -3260,15 +3260,26 @@ The return value is unspecified. @deffn {Scheme Procedure} accept sock @deffnx {C Function} scm_accept (sock) Accept a connection from socket port @var{sock} which has been enabled -for listening with @code{listen} above. If there are no incoming -connections in the queue, wait until one is available (unless -@code{O_NONBLOCK} has been set on the socket, @pxref{Ports and File -Descriptors,@code{fcntl}}). +for listening with @code{listen} above. + +If there are no incoming connections in the queue, there are two +possible behaviors, depending on whether @var{sock} has been configured +for non-blocking operation or not: + +@itemize +@item +If there is no connection waiting and the socket was set to non-blocking +mode with the @code{O_NONBLOCK} port option (@pxref{Ports and File +Descriptors,@code{fcntl}}), return @code{#f} directly. + +@item +Otherwise wait until a connection is available. +@end itemize The return value is a pair. The @code{car} is a new socket port, -connected and ready to communicate. The @code{cdr} is a socket -address object (@pxref{Network Socket Address}) which is where the -remote connection is from (like @code{getpeername} below). +connected and ready to communicate. The @code{cdr} is a socket address +object (@pxref{Network Socket Address}) which is where the remote +connection is from (like @code{getpeername} below). All communication takes place using the new socket returned. The given @var{sock} remains bound and listening, and @code{accept} may be diff --git a/libguile/socket.c b/libguile/socket.c index 1c4f2ae36..55b93572c 100644 --- a/libguile/socket.c +++ b/libguile/socket.c @@ -1236,16 +1236,15 @@ SCM_DEFINE (scm_make_socket_address, "make-socket-address", 2, 0, 1, SCM_DEFINE (scm_accept, "accept", 1, 0, 0, (SCM sock), - "Accept a connection on a bound, listening socket.\n" - "If there\n" - "are no pending connections in the queue, wait until\n" - "one is available unless the non-blocking option has been\n" - "set on the socket.\n\n" - "The return value is a\n" - "pair in which the @emph{car} is a new socket port for the\n" - "connection and\n" - "the @emph{cdr} is an object with address information about the\n" - "client which initiated the connection.\n\n" + "Accept a connection on a bound, listening socket. If there\n" + "are no pending connections in the queue, there are two\n" + "possibilities: if the socket has been configured as\n" + "non-blocking, return @code{#f} directly. Otherwise wait\n" + "until a connection is available. When a connection comes,\n" + "the return value is a pair in which the @emph{car} is a new\n" + "socket port for the connection and the @emph{cdr} is an\n" + "object with address information about the client which\n" + "initiated the connection.\n\n" "@var{sock} does not become part of the\n" "connection and will continue to accept new requests.") #define FUNC_NAME s_scm_accept @@ -1262,7 +1261,11 @@ SCM_DEFINE (scm_accept, "accept", 1, 0, 0, fd = SCM_FPORT_FDES (sock); SCM_SYSCALL (newfd = accept (fd, (struct sockaddr *) &addr, &addr_size)); if (newfd == -1) - SCM_SYSERROR; + { + if (errno == EAGAIN || errno == EWOULDBLOCK) + return SCM_BOOL_F; + SCM_SYSERROR; + } newsock = SCM_SOCK_FD_TO_PORT (newfd); address = _scm_from_sockaddr (&addr, addr_size, FUNC_NAME); |