From: Eric Blake Date: Tue, 20 Aug 2019 16:34:34 +0000 (-0500) Subject: accept4: Support SOCK_NONBLOCK, if defined X-Git-Tag: v1.0~4706 X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=b3ee76fab752ae51f408df764bf6f7df913669cd;p=gnulib.git accept4: Support SOCK_NONBLOCK, if defined Ideally, we would improve our replacement to define a replacement SOCK_NONBLOCK on all platforms, and teach socket() to honor it as well; but that's a bigger task. In the meantime, if the platform already has SOCK_NONBLOCK, we should honor it when doing a fallback. * lib/accept4.c (accept4): If SOCK_NONBLOCK is defined, honor it. --- diff --git a/ChangeLog b/ChangeLog index 6253f92218..f5eda2fa3d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2019-08-20 Eric Blake + accept4: Support SOCK_NONBLOCK, if defined + * lib/accept4.c (accept4): If SOCK_NONBLOCK is defined, honor it. + accept4: Fix compilation when native accept4() exists. Reported by Richard W.M. Jones in https://lists.gnu.org/archive/html/bug-gnulib/2019-08/msg00029.html diff --git a/lib/accept4.c b/lib/accept4.c index c6e59c955f..9ce78fa969 100644 --- a/lib/accept4.c +++ b/lib/accept4.c @@ -31,6 +31,9 @@ #ifndef SOCK_CLOEXEC # define SOCK_CLOEXEC 0 #endif +#ifndef SOCK_NONBLOCK +# define SOCK_NONBLOCK 0 +#endif int accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) @@ -58,7 +61,7 @@ accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) #endif /* Check the supported flags. */ - if ((flags & ~(SOCK_CLOEXEC | O_TEXT | O_BINARY)) != 0) + if ((flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK | O_TEXT | O_BINARY)) != 0) { errno = EINVAL; return -1; @@ -121,6 +124,22 @@ accept4 (int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) # endif #endif +#if SOCK_CLOEXEC + if (flags & SOCK_NONBLOCK) + { + int fcntl_flags; + + if ((fcntl_flags = fcntl (fd, F_GETFL, 0)) < 0 + || fcntl (fd, F_SETFL, fcntl_flags | O_NONBLOCK) == -1) + { + int saved_errno = errno; + close (fd); + errno = saved_errno; + return -1; + } + } +#endif + #if O_BINARY if (flags & O_BINARY) set_binary_mode (fd, O_BINARY);