diff options
-rw-r--r-- | libasyncns/asyncns.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/libasyncns/asyncns.c b/libasyncns/asyncns.c index e5d4291..bc0b708 100644 --- a/libasyncns/asyncns.c +++ b/libasyncns/asyncns.c @@ -83,7 +83,7 @@ enum { }; struct asyncns { - int fds[4]; + int fds[MESSAGE_FD_MAX]; #ifndef HAVE_PTHREAD pid_t workers[MAX_WORKERS]; @@ -221,6 +221,8 @@ static int close_allv(const int except_fds[]) { assert(except_fds); + /* We ignore FD_CLOEXEC here, since this is called in the child only anyway */ + if ((d = opendir("/proc/self/fd"))) { struct dirent *de; @@ -781,9 +783,21 @@ asyncns_t* asyncns_new(unsigned n_proc) { memset(asyncns->queries, 0, sizeof(asyncns->queries)); - if (socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds) < 0 || - socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds+2) < 0) - goto fail; +#ifdef SOCK_CLOEXEC + if (socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, asyncns->fds) < 0 || + socketpair(PF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, asyncns->fds+2) < 0) { + + /* Try again, without SOCK_CLOEXEC */ + if (errno == EINVAL) { +#endif + if (socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds) < 0 || + socketpair(PF_UNIX, SOCK_DGRAM, 0, asyncns->fds+2) < 0) + goto fail; +#ifdef SOCK_CLOEXEC + } else + goto fail; + } +#endif for (i = 0; i < MESSAGE_FD_MAX; i++) fd_cloexec(asyncns->fds[i]); |