make timed kgio_wait_* implementation safer
[kgio.git] / ext / kgio / missing_accept4.h
blob22bd9bcd5250282298cf886f717e637517d9827e
1 #ifndef HAVE_ACCEPT4
2 # ifndef _GNU_SOURCE
3 # define _GNU_SOURCE
4 # endif
5 # include <sys/types.h>
6 # include <sys/socket.h>
7 # ifndef SOCK_CLOEXEC
8 # if (FD_CLOEXEC == O_NONBLOCK)
9 # define SOCK_CLOEXEC 1
10 # define SOCK_NONBLOCK 2
11 # else
12 # define SOCK_CLOEXEC FD_CLOEXEC
13 # define SOCK_NONBLOCK O_NONBLOCK
14 # endif
15 # endif
16 #endif /* !HAVE_ACCEPT4 */
18 /* accept4() is currently a Linux-only goodie */
19 static int
20 my_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
22 int fd = accept(sockfd, addr, addrlen);
24 if (fd >= 0) {
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
32 * in most cases...
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
49 errno = 0;
51 return fd;
54 typedef int accept_fn_t(int, struct sockaddr *, socklen_t *, int);
55 #ifdef HAVE_ACCEPT4
56 static accept_fn_t *accept_fn = accept4;
57 #else
58 static accept_fn_t *accept_fn = my_accept4;
59 #endif