bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 6/8] fts: add/use new struct member, fts_dirp


From: Jim Meyering
Subject: [PATCH 6/8] fts: add/use new struct member, fts_dirp
Date: Thu, 18 Aug 2011 15:53:25 +0200

From: Jim Meyering <address@hidden>

We are about to use this to manage any directory with
too many entries to read all of them into memory at once.
To do that, we'll need to save the DIR* pointer in each
affected FTSENT struct.
* lib/fts_.h: Include <dirent.h>.
(struct FTSENT) [fts_dirp]: New member.
* lib/fts.c (closedir_and_clear): Define.
Use it in place of closedir so that we are sure to
clear the new fts_dirp member when done with it.
(fts_alloc): Initialize the new member.
(fts_lfree): Free, if needed.
---
 lib/fts.c  |   34 +++++++++++++++++++++-------------
 lib/fts_.h |    4 ++++
 2 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/lib/fts.c b/lib/fts.c
index 33ecffb..9e935ba 100644
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1192,6 +1192,14 @@ set_stat_type (struct stat *st, unsigned int dtype)
   st->st_mode = type;
 }

+#define closedir_and_clear(dirp)                \
+  do                                            \
+    {                                           \
+      closedir (dirp);                          \
+      dirp = NULL;                              \
+    }                                           \
+  while (0)
+
 #define __opendir2(file, Pdir_fd)                               \
         opendirat((! ISSET(FTS_NOCHDIR) && ISSET(FTS_CWDFD)     \
                    ? sp->fts_cwd_fd : AT_FDCWD),                \
@@ -1224,8 +1232,7 @@ fts_build (register FTS *sp, int type)
         register struct dirent *dp;
         register FTSENT *p, *head;
         register size_t nitems;
-        FTSENT *cur, *tail;
-        DIR *dirp;
+        FTSENT *tail;
         void *oldaddr;
         int saved_errno;
         bool descend;
@@ -1236,13 +1243,11 @@ fts_build (register FTS *sp, int type)
         size_t len, maxlen, new_len;
         char *cp;
         int dir_fd;
-
-        /* Set current node pointer. */
-        cur = sp->fts_cur;
+        FTSENT *cur = sp->fts_cur;

         /* Open the directory for reading.  If this fails, we're done.
            If being called from fts_read, set the fts_info field.  */
-        if ((dirp = __opendir2(cur->fts_accpath, &dir_fd)) == NULL) {
+        if ((cur->fts_dirp = __opendir2(cur->fts_accpath, &dir_fd)) == NULL) {
                 if (type == BREAD) {
                         cur->fts_info = FTS_DNR;
                         cur->fts_errno = errno;
@@ -1313,10 +1318,10 @@ fts_build (register FTS *sp, int type)
                                 cur->fts_errno = errno;
                         cur->fts_flags |= FTS_DONTCHDIR;
                         descend = false;
-                        closedir(dirp);
+                        closedir_and_clear(cur->fts_dirp);
                         if (ISSET(FTS_CWDFD) && 0 <= dir_fd)
                                 close (dir_fd);
-                        dirp = NULL;
+                        cur->fts_dirp = NULL;
                 } else
                         descend = true;
         } else
@@ -1347,7 +1352,7 @@ fts_build (register FTS *sp, int type)

         /* Read the directory, attaching each entry to the `link' pointer. */
         doadjust = false;
-        for (head = tail = NULL, nitems = 0; dirp && (dp = readdir(dirp));) {
+        for (head = tail = NULL, nitems = 0; cur->fts_dirp && (dp = 
readdir(cur->fts_dirp));) {
                 bool is_dir;

                 if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
@@ -1368,7 +1373,7 @@ fts_build (register FTS *sp, int type)
 mem1:                           saved_errno = errno;
                                 free(p);
                                 fts_lfree(head);
-                                closedir(dirp);
+                                closedir_and_clear(cur->fts_dirp);
                                 cur->fts_info = FTS_ERR;
                                 SET(FTS_STOP);
                                 __set_errno (saved_errno);
@@ -1393,7 +1398,7 @@ mem1:                           saved_errno = errno;
                          */
                         free(p);
                         fts_lfree(head);
-                        closedir(dirp);
+                        closedir_and_clear(cur->fts_dirp);
                         cur->fts_info = FTS_ERR;
                         SET(FTS_STOP);
                         __set_errno (ENAMETOOLONG);
@@ -1459,8 +1464,8 @@ mem1:                           saved_errno = errno;
                 }
                 ++nitems;
         }
-        if (dirp)
-                closedir(dirp);
+        if (cur->fts_dirp)
+                closedir_and_clear(cur->fts_dirp);

         /*
          * If realloc() changed the address of the file name, adjust the
@@ -1803,6 +1808,7 @@ fts_alloc (FTS *sp, const char *name, register size_t 
namelen)
         p->fts_fts = sp;
         p->fts_path = sp->fts_path;
         p->fts_errno = 0;
+        p->fts_dirp = NULL;
         p->fts_flags = 0;
         p->fts_instr = FTS_NOINSTR;
         p->fts_number = 0;
@@ -1819,6 +1825,8 @@ fts_lfree (register FTSENT *head)
         /* Free a linked list of structures. */
         while ((p = head)) {
                 head = head->fts_link;
+                if (p->fts_dirp)
+                        closedir (p->fts_dirp);
                 free(p);
         }
 }
diff --git a/lib/fts_.h b/lib/fts_.h
index fe92cfd..a0235a9 100644
--- a/lib/fts_.h
+++ b/lib/fts_.h
@@ -67,6 +67,7 @@

 # include <stddef.h>
 # include <sys/types.h>
+# include <dirent.h>
 # include <sys/stat.h>
 # include "i-ring.h"

@@ -191,6 +192,9 @@ typedef struct _ftsent {
         struct _ftsent *fts_cycle;      /* cycle node */
         struct _ftsent *fts_parent;     /* parent directory */
         struct _ftsent *fts_link;       /* next file in directory */
+        DIR *fts_dirp;                  /* Dir pointer for any directory
+                                           containing more entries than we
+                                           read at one time.  */
         long fts_number;                /* local numeric value */
         void *fts_pointer;              /* local address value */
         char *fts_accpath;              /* access file name */
-- 
1.7.6.857.gf34cf




reply via email to

[Prev in Thread] Current Thread [Next in Thread]