aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/fd_util.c27
-rw-r--r--src/fd_util.h22
2 files changed, 49 insertions, 0 deletions
diff --git a/src/fd_util.c b/src/fd_util.c
index d8fe166d7..b9443b03d 100644
--- a/src/fd_util.c
+++ b/src/fd_util.c
@@ -246,6 +246,33 @@ accept_cloexec_nonblock(int fd, struct sockaddr *address,
return ret;
}
+#ifndef WIN32
+
+ssize_t
+recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags)
+{
+#ifdef MSG_CMSG_CLOEXEC
+ flags |= MSG_CMSG_CLOEXEC;
+#endif
+
+ ssize_t result = recvmsg(sockfd, msg, flags);
+ if (result >= 0) {
+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg);
+ while (cmsg != NULL) {
+ if (cmsg->cmsg_type == SCM_RIGHTS) {
+ int fd = *(const int *)CMSG_DATA(cmsg);
+ fd_set_cloexec(fd, true);
+ }
+
+ cmsg = CMSG_NXTHDR(msg, cmsg);
+ }
+ }
+
+ return result;
+}
+
+#endif
+
#ifdef HAVE_INOTIFY_INIT
int
diff --git a/src/fd_util.h b/src/fd_util.h
index b49a51373..80fb98703 100644
--- a/src/fd_util.h
+++ b/src/fd_util.h
@@ -39,6 +39,14 @@
#include <stdbool.h>
#include <stddef.h>
+#ifndef WIN32
+#if !defined(_GNU_SOURCE) && (defined(HAVE_PIPE2) || defined(HAVE_ACCEPT4))
+#define _GNU_SOURCE
+#endif
+
+#include <sys/types.h>
+#endif
+
struct sockaddr;
/**
@@ -91,6 +99,20 @@ int
accept_cloexec_nonblock(int fd, struct sockaddr *address,
size_t *address_length_r);
+
+#ifndef WIN32
+
+struct msghdr;
+
+/**
+ * Wrapper for recvmsg(), which sets the CLOEXEC flag (atomically if
+ * supported by the OS).
+ */
+ssize_t
+recvmsg_cloexec(int sockfd, struct msghdr *msg, int flags);
+
+#endif
+
/**
* Wrapper for inotify_init(), which sets the CLOEXEC flag (atomically
* if supported by the OS).