summaryrefslogtreecommitdiff
path: root/libguile
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2017-02-15 22:01:51 +0100
committerAndy Wingo <wingo@pobox.com>2017-02-15 22:10:25 +0100
commit6e0965104c579431e5a786b60e1a964a112c73b8 (patch)
tree20039c935d8968fcc6d0b50b45a52026165088d1 /libguile
parent9399c1347918fb9b39ee4b1443bcc0df78ebf750 (diff)
Add accept4 support
* doc/ref/posix.texi (Network Sockets and Communication): Add documentation. * libguile/socket.c (scm_accept4): New function, replaces accept implementation. (scm_accept): Call scm_accept4. (scm_init_socket): Define SOCK_CLOEXEC and SOCK_NONBLOCK. * libguile/socket.h: Add private scm_accept4 decl. * module/ice-9/suspendable-ports.scm (accept): Update.
Diffstat (limited to 'libguile')
-rw-r--r--libguile/socket.c26
-rw-r--r--libguile/socket.h1
2 files changed, 21 insertions, 6 deletions
diff --git a/libguile/socket.c b/libguile/socket.c
index 9ddc4a21f..64df64f4b 100644
--- a/libguile/socket.c
+++ b/libguile/socket.c
@@ -1243,8 +1243,8 @@ SCM_DEFINE (scm_make_socket_address, "make-socket-address", 2, 0, 1,
#undef FUNC_NAME
-SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
- (SCM sock),
+SCM_DEFINE (scm_accept4, "accept", 1, 1, 0,
+ (SCM sock, SCM flags),
"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"
@@ -1256,10 +1256,11 @@ SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
"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
+#define FUNC_NAME s_scm_accept4
{
int fd;
int newfd;
+ int c_flags;
SCM address;
SCM newsock;
socklen_t addr_size = MAX_ADDR_SIZE;
@@ -1267,8 +1268,11 @@ SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
sock = SCM_COERCE_OUTPORT (sock);
SCM_VALIDATE_OPFPORT (1, sock);
+ c_flags = SCM_UNBNDP (flags) ? 0 : scm_to_int (flags);
+
fd = SCM_FPORT_FDES (sock);
- SCM_SYSCALL (newfd = accept4 (fd, (struct sockaddr *) &addr, &addr_size, 0));
+ SCM_SYSCALL (newfd = accept4 (fd, (struct sockaddr *) &addr, &addr_size,
+ c_flags));
if (newfd == -1)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
@@ -1276,13 +1280,18 @@ SCM_DEFINE (scm_accept, "accept", 1, 0, 0,
SCM_SYSERROR;
}
newsock = scm_socket_fd_to_port (newfd);
- address = _scm_from_sockaddr (&addr, addr_size,
- FUNC_NAME);
+ address = _scm_from_sockaddr (&addr, addr_size, FUNC_NAME);
return scm_cons (newsock, address);
}
#undef FUNC_NAME
+SCM
+scm_accept (SCM sock)
+{
+ return scm_accept4 (sock, SCM_UNDEFINED);
+}
+
SCM_DEFINE (scm_getsockname, "getsockname", 1, 0, 0,
(SCM sock),
"Return the address of @var{sock}, in the same form as the\n"
@@ -1644,6 +1653,11 @@ scm_init_socket ()
scm_c_define ("SOCK_RDM", scm_from_int (SOCK_RDM));
#endif
+ /* accept4 flags. No ifdef as accept4 has a gnulib
+ implementation. */
+ scm_c_define ("SOCK_CLOEXEC", scm_from_int (SOCK_CLOEXEC));
+ scm_c_define ("SOCK_NONBLOCK", scm_from_int (SOCK_NONBLOCK));
+
/* setsockopt level.
SOL_IP, SOL_TCP and SOL_UDP are defined on gnu/linux, but not on for
diff --git a/libguile/socket.h b/libguile/socket.h
index a211867c6..d7c368a22 100644
--- a/libguile/socket.h
+++ b/libguile/socket.h
@@ -42,6 +42,7 @@ SCM_API SCM scm_shutdown (SCM sfd, SCM how);
SCM_API SCM scm_connect (SCM sockfd, SCM fam, SCM address, SCM args);
SCM_API SCM scm_bind (SCM sockfd, SCM fam, SCM address, SCM args);
SCM_API SCM scm_listen (SCM sfd, SCM backlog);
+SCM_INTERNAL SCM scm_accept4 (SCM sockfd, SCM flags);
SCM_API SCM scm_accept (SCM sockfd);
SCM_API SCM scm_getsockname (SCM sockfd);
SCM_API SCM scm_getpeername (SCM sockfd);