relocatable-prog: fix link error
[gnulib.git] / lib / fts.c
index 1daf69c..7210c1b 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1,6 +1,6 @@
 /* Traverse a file hierarchy.
 
-   Copyright (C) 2004-2010 Free Software Foundation, Inc.
+   Copyright (C) 2004-2011 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -160,8 +160,6 @@ enum Fts_stat
 # define fchdir __fchdir
 # undef open
 # define open __open
-# undef opendir
-# define opendir __opendir
 # undef readdir
 # define readdir __readdir
 #else
@@ -290,7 +288,7 @@ fts_set_stat_required (FTSENT *p, bool required)
 /* 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 @@ opendirat (int fd, char const *dir, int extra_flags)
     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);
@@ -349,7 +349,8 @@ internal_function
 diropen (FTS const *sp, char const *dir)
 {
   int open_flags = (O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
-                    | (ISSET (FTS_PHYSICAL) ? O_NOFOLLOW : 0));
+                    | (ISSET (FTS_PHYSICAL) ? O_NOFOLLOW : 0)
+                    | (ISSET (FTS_NOATIME) ? O_NOATIME : 0));
 
   int fd = (ISSET (FTS_CWDFD)
             ? openat (sp->fts_cwd_fd, dir, open_flags)
@@ -406,7 +407,8 @@ fts_open (char * const *argv,
                early, doing it here saves us the trouble of ensuring
                later (where it'd be messier) that "." can in fact
                be opened.  If not, revert to FTS_NOCHDIR mode.  */
-            int fd = open (".", O_SEARCH);
+            int fd = open (".",
+                           O_SEARCH | (ISSET (FTS_NOATIME) ? O_NOATIME : 0));
             if (fd < 0)
               {
                 /* Even if `.' is unreadable, don't revert to FTS_NOCHDIR mode
@@ -628,7 +630,7 @@ fts_close (FTS *sp)
 #if defined __linux__ \
   && HAVE_SYS_VFS_H && HAVE_FSTATFS && HAVE_STRUCT_STATFS_F_TYPE
 
-#include <sys/vfs.h>
+# include <sys/vfs.h>
 
 /* Linux-specific constants from coreutils' src/fs.h */
 # define S_MAGIC_TMPFS 0x1021994
@@ -710,7 +712,7 @@ leaf_optimization_applies (int dir_fd _GL_UNUSED) { return false; }
 #endif
 
 /* link-count-optimization entry:
-   map an stat.st_dev number to a boolean: leaf_optimization_works */
+   map a stat.st_dev number to a boolean: leaf_optimization_works */
 struct LCO_ent
 {
   dev_t st_dev;
@@ -1222,6 +1224,7 @@ fts_build (register FTS *sp, int type)
         bool nostat;
         size_t len, maxlen, new_len;
         char *cp;
+        int dir_fd;
 
         /* Set current node pointer. */
         cur = sp->fts_cur;
@@ -1237,13 +1240,15 @@ fts_build (register FTS *sp, int type)
                 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)                           \
+                   | (ISSET (FTS_NOATIME) ? O_NOATIME : 0)),    \
+                  &dir_fd)
 #endif
        if ((dirp = __opendir2(cur->fts_accpath, oflag)) == NULL) {
                 if (type == BREAD) {
@@ -1306,8 +1311,7 @@ fts_build (register FTS *sp, int type)
          * 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)
@@ -1652,7 +1656,7 @@ fd_ring_check (FTS const *sp)
       int fd = i_ring_pop (&fd_w);
       if (0 <= fd)
         {
-          int parent_fd = openat (cwd_fd, "..", O_SEARCH);
+          int parent_fd = openat (cwd_fd, "..", O_SEARCH | O_NOATIME);
           if (parent_fd < 0)
             {
               // Warn?