summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libasyncns/asyncns.c22
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]);