summaryrefslogtreecommitdiffstats
path: root/lib/fileutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/fileutils.c')
-rw-r--r--lib/fileutils.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/lib/fileutils.c b/lib/fileutils.c
index bffa8ff34..81b38ad3a 100644
--- a/lib/fileutils.c
+++ b/lib/fileutils.c
@@ -50,6 +50,36 @@ int xmkstemp(char **tmpname, char *dir)
return fd;
}
+int dup_fd_cloexec(int oldfd, int lowfd)
+{
+ int fd, flags, errno_save;
+
+#ifdef F_DUPFD_CLOEXEC
+ fd = fcntl(oldfd, F_DUPFD_CLOEXEC, lowfd);
+ if (fd >= 0)
+ return fd;
+#endif
+
+ fd = dup(oldfd);
+ if (fd < 0)
+ return fd;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags < 0)
+ goto unwind;
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
+ goto unwind;
+
+ return fd;
+
+unwind:
+ errno_save = errno;
+ close(fd);
+ errno = errno_save;
+
+ return -1;
+}
+
/*
* portable getdtablesize()
*/