fts: avoid leaking fds
authorEric Blake <ebb9@byu.net>
Wed, 2 Sep 2009 20:44:51 +0000 (14:44 -0600)
committerEric Blake <ebb9@byu.net>
Thu, 3 Sep 2009 02:35:45 +0000 (20:35 -0600)
* modules/fts (Depends-on): Add cloexec.
* lib/fts.c (opendirat, diropen, fts_build): Set close-on-exec
flag.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/fts.c
modules/fts

index cd31557fb5b53463d9efbb7954e14ceae575428f..1f8d5e80010ce01ce2225f68f40df879f199ac39 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2009-09-02  Eric Blake  <ebb9@byu.net>
 
+       fts: avoid leaking fds
+       * modules/fts (Depends-on): Add cloexec.
+       * lib/fts.c (opendirat, diropen, fts_build): Set close-on-exec
+       flag.
+
        fts: make directory fds more robust
        * lib/fts.c (O_DIRECTORY): Let <fcntl.h> take care of this.
        (opendirat): Specify O_DIRECTORY, and add fallbacks for safety.
index ebf66fc45f9f46c5d53ebe27cd29037a6bd97df6..c05eb8b68e1ca9410e8024389d404446a26aff34 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -71,6 +71,9 @@ static char sccsid[] = "@(#)fts.c     8.6 (Berkeley) 8/14/94";
 # include "fcntl--.h"
 # include "dirent--.h"
 # include "unistd--.h"
+/* FIXME - use fcntl(F_DUPFD_CLOEXEC)/openat(O_CLOEXEC) once they are
+   supported.  */
+# include "cloexec.h"
 # include "same-inode.h"
 #endif
 
@@ -311,6 +314,7 @@ opendirat (int fd, char const *dir)
 
   if (new_fd < 0)
     return NULL;
+  set_cloexec_flag (new_fd, true);
   dirp = fdopendir (new_fd);
   if (dirp == NULL)
     {
@@ -362,9 +366,12 @@ diropen (FTS const *sp, char const *dir)
   int open_flags = (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
                    | (ISSET (FTS_PHYSICAL) ? O_NOFOLLOW : 0));
 
-  return (ISSET (FTS_CWDFD)
-         ? openat (sp->fts_cwd_fd, dir, open_flags)
-         : open (dir, open_flags));
+  int fd = (ISSET (FTS_CWDFD)
+            ? openat (sp->fts_cwd_fd, dir, open_flags)
+            : open (dir, open_flags));
+  if (0 <= fd)
+    set_cloexec_flag (fd, true);
+  return fd;
 }
 
 FTS *
@@ -1305,7 +1312,10 @@ fts_build (register FTS *sp, int type)
        if (nlinks || type == BREAD) {
                int dir_fd = dirfd(dirp);
                if (ISSET(FTS_CWDFD) && 0 <= dir_fd)
-                 dir_fd = dup (dir_fd);
+                 {
+                   dir_fd = dup (dir_fd);
+                   set_cloexec_flag (dir_fd, true);
+                 }
                if (dir_fd < 0 || fts_safe_changedir(sp, cur, dir_fd, NULL)) {
                        if (nlinks && type == BREAD)
                                cur->fts_errno = errno;
index f80a827db5756605068470479aae63a22cd0a2ab..9509557b7183c71564f6a006d8b159cc5a039fbc 100644 (file)
@@ -8,6 +8,7 @@ lib/fts-cycle.c
 m4/fts.m4
 
 Depends-on:
+cloexec
 cycle-check
 d-ino
 d-type