1 #if !defined(HAVE_ACCEPT4) || !defined(SOCK_CLOEXEC) || !defined(SOCK_NONBLOCK)
5 # include <sys/types.h>
6 # include <sys/socket.h>
8 # if (02000000 == O_NONBLOCK)
9 # define SOCK_CLOEXEC 1
10 # define SOCK_NONBLOCK 2
12 # define SOCK_CLOEXEC 02000000
13 # define SOCK_NONBLOCK O_NONBLOCK
16 #endif /* !HAVE_ACCEPT4 */
18 /* accept4() is currently a Linux-only goodie */
20 my_accept4(int sockfd
, struct sockaddr
*addr
, socklen_t
*addrlen
, int flags
)
22 int fd
= accept(sockfd
, addr
, addrlen
);
25 if ((flags
& SOCK_CLOEXEC
) == SOCK_CLOEXEC
)
26 (void)fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
29 * Some systems inherit O_NONBLOCK across accept().
30 * We also expect our users to use MSG_DONTWAIT under
31 * Linux, so fcntl() is completely unnecessary
34 if ((flags
& SOCK_NONBLOCK
) == SOCK_NONBLOCK
) {
35 int fl
= fcntl(fd
, F_GETFL
);
38 * unconditional, OSX 10.4 (and maybe other *BSDs)
39 * F_GETFL returns a false O_NONBLOCK with TCP sockets
40 * (but not UNIX sockets) [ruby-talk:274079]
42 (void)fcntl(fd
, F_SETFL
, fl
| O_NONBLOCK
);
46 * nothing we can do about fcntl() errors in this wrapper
47 * function, let the user (Ruby) code figure it out
54 typedef int accept_fn_t(int, struct sockaddr
*, socklen_t
*, int);
56 static accept_fn_t
*accept_fn
= accept4
;
58 static accept_fn_t
*accept_fn
= my_accept4
;