]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/fileutils: Add new dup_fd_cloexec function
authorGuillem Jover <guillem@hadrons.org>
Sat, 6 Jun 2015 04:19:05 +0000 (06:19 +0200)
committerKarel Zak <kzak@redhat.com>
Mon, 8 Jun 2015 10:10:02 +0000 (12:10 +0200)
This function duplicates and marks a file descriptor as close-on-exec.
Takes care of build and run-time support for the fcntl F_DUPFD_CLOEXEC
command, and other errors.

Signed-off-by: Guillem Jover <guillem@hadrons.org>
include/fileutils.h
lib/fileutils.c

index 3353f69a07ffd91c4b1262d9e53c1ef86a564c2c..e0e2ecee129e0e66bb835383f3e08627974e3152 100644 (file)
@@ -25,6 +25,7 @@ static inline FILE *xfmkstemp(char **tmpname, char *dir)
        return ret;
 }
 
+extern int dup_fd_cloexec(int oldfd, int lowfd);
 extern int get_fd_tabsize(void);
 
 extern int mkdir_p(const char *path, mode_t mode);
index bffa8ff34c19810a623a1e92996b2146778648fa..81b38ad3a7013275f21958b3ab1833674ba338a8 100644 (file)
@@ -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()
  */