diff lib/fts.c @ 13676:223800d7ac7d

fts, getcwd, glob: audit for dirfd returning -1 * lib/fts.c (opendir): Remove #define; no longer used. (opendirat): New arg PDIR_FD. All callers changed. (fts_build, _opendir2): Use new opendirat to avoid the need for dirfd, or for checking whether dirfd returns a negative value. Don't use opendir; always use openat followed by fdopendir. * lib/getcwd.c (__getcwd): Don't reset fd; fdopendir no longer clobbers it. * lib/glob.c (link_exists_p): Add comment explaining why dirfd never returns -1 here. * modules/fts (Depends-on): Remove dirfd. * modules/getcwd (Depends-on): Likewise.
author Paul Eggert <eggert@cs.ucla.edu>
date Tue, 14 Sep 2010 09:03:55 -0700
parents 5c447be5815d
children 97fc9a21a8fb
line wrap: on
line diff
--- a/lib/fts.c	Mon Sep 13 14:33:22 2010 -0600
+++ b/lib/fts.c	Tue Sep 14 09:03:55 2010 -0700
@@ -160,8 +160,6 @@
 # define fchdir __fchdir
 # undef open
 # define open __open
-# undef opendir
-# define opendir __opendir
 # undef readdir
 # define readdir __readdir
 #else
@@ -290,7 +288,7 @@
 /* FIXME: if others need this function, move it into lib/openat.c */
 static inline DIR *
 internal_function
-opendirat (int fd, char const *dir, int extra_flags)
+opendirat (int fd, char const *dir, int extra_flags, int *pdir_fd)
 {
   int new_fd = openat (fd, dir,
                        (O_RDONLY | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
@@ -301,7 +299,9 @@
     return NULL;
   set_cloexec_flag (new_fd, true);
   dirp = fdopendir (new_fd);
-  if (dirp == NULL)
+  if (dirp)
+    *pdir_fd = new_fd;
+  else
     {
       int saved_errno = errno;
       close (new_fd);
@@ -1222,6 +1222,7 @@
         bool nostat;
         size_t len, maxlen, new_len;
         char *cp;
+        int dir_fd;
 
         /* Set current node pointer. */
         cur = sp->fts_cur;
@@ -1237,13 +1238,14 @@
                 oflag = DTF_HIDEW|DTF_NODUP|DTF_REWIND;
 #else
 # define __opendir2(file, flag) \
-        ( ! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD) \
-          ? opendirat(sp->fts_cwd_fd, file,        \
-                      ((ISSET(FTS_PHYSICAL)                   \
-                        && ! (cur->fts_level == FTS_ROOTLEVEL \
-                              && ISSET(FTS_COMFOLLOW)))       \
-                       ? O_NOFOLLOW : 0))                     \
-          : opendir(file))
+        opendirat((! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD)     \
+                   ? sp->fts_cwd_fd : AT_FDCWD),                \
+                  file,                                         \
+                  ((ISSET(FTS_PHYSICAL)                         \
+                    && ! (ISSET(FTS_COMFOLLOW)                  \
+                          && cur->fts_level == FTS_ROOTLEVEL))  \
+                   ? O_NOFOLLOW : 0),                           \
+                  &dir_fd)
 #endif
        if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
                 if (type == BREAD) {
@@ -1306,8 +1308,7 @@
          * checking FTS_NS on the returned nodes.
          */
         if (nlinks || type == BREAD) {
-                int dir_fd = dirfd(dirp);
-                if (ISSET(FTS_CWDFD) && 0 <= dir_fd)
+                if (ISSET(FTS_CWDFD))
                   {
                     dir_fd = dup (dir_fd);
                     if (0 <= dir_fd)