findutils-patches
[Top][All Lists]
Advanced

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

[Findutils-patches] [PATCH] find: properly support -noleaf in ftsfind.


From: James Youngman
Subject: [Findutils-patches] [PATCH] find: properly support -noleaf in ftsfind.
Date: Sat, 2 Sep 2017 16:35:31 +0100

* gnulib-local/lib/fts.c.diff: incorporated from a patch by Kamil
Dudka <address@hidden>.  This patch introduces an FTS_NOLEAF option
to fts.
* gnulib-local/lib/fts_.h.diff: Likewise.
* find/ftsfind.c (ftsoptions): point out that is_fts_enabled
reflects the settings made in the initialization of ftsoptions,
not the modifications made later to it (e.g. FTS_NOLEAF).
(find): Set fts_options |= FTS_NOLEAF when the -noleaf option was
specified.  With -D search, the debugging output now shows the
options passed to fts_open.
(is_fts_enabled): Point out that the result doesn't reflect any
dynamic changes to ftsoptions (e.g.  FTS_NOLEAF).
* Makefile.am (EXTRA_DIST): Distribute fts.c.diff and fts_.h.diff in
gnulib-local/lib.  These diffs will be applied to the gnulib sources
by gnulib-tool (hence, the gnulib code shipped in the source tarball
will already include these patches).
* find/parser.c (parse_version): For the FTS feature, indicate
whether FTS_NOLEAF is available (but not whether it was used; for
that you have to use the command-line flag -D search).
---
 Makefile.am                  |  4 +++-
 find/ftsfind.c               | 12 ++++++++++++
 find/parser.c                | 12 ++++++++++++
 gnulib-local/lib/fts.c.diff  | 23 +++++++++++++++++++++++
 gnulib-local/lib/fts_.h.diff | 24 ++++++++++++++++++++++++
 5 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 gnulib-local/lib/fts.c.diff
 create mode 100644 gnulib-local/lib/fts_.h.diff

diff --git a/Makefile.am b/Makefile.am
index c31e7f03..030a4d58 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,9 @@ AM_CFLAGS = $(WARN_CFLAGS)
 
 EXTRA_DIST = COPYING ChangeLog TODO config.h.in stamp-h.in \
                THANKS bootstrap \
-               tool-versions.txt README-hacking
+               tool-versions.txt README-hacking \
+               gnulib-local/lib/fts.c.diff \
+               gnulib-local/lib/fts_.h.diff
 DISTCLEANFILES = tool-versions.txt
 
 
diff --git a/find/ftsfind.c b/find/ftsfind.c
index f9b03e2d..7bb6c145 100644
--- a/find/ftsfind.c
+++ b/find/ftsfind.c
@@ -72,6 +72,7 @@
 /* FTS_TIGHT_CYCLE_CHECK tries to work around Savannah bug #17877
  * (but actually using it doesn't fix the bug).
  */
+/* The --version output will reflect only flags set here (via is_fts_enabled). 
*/
 static int ftsoptions = 
FTS_NOSTAT|FTS_TIGHT_CYCLE_CHECK|FTS_CWDFD|FTS_VERBATIM;
 
 static int prev_depth = INT_MIN; /* fts_level can be < 0 */
@@ -545,6 +546,13 @@ find (char *arg)
   if (options.stay_on_filesystem)
     ftsoptions |= FTS_XDEV;
 
+  if (options.no_leaf_check)
+    ftsoptions |= FTS_NOLEAF;
+
+  if (options.debug_options & DebugSearch)
+    fprintf (stderr, "calling fts_open with options %#x\n",
+            (unsigned)ftsoptions);
+
   p = fts_open (arglist, ftsoptions, NULL);
   if (NULL == p)
     {
@@ -742,6 +750,10 @@ main (int argc, char **argv)
   return state.exit_status;
 }
 
+/* The result of is_fts_enabled will reflect only flags set in
+   ftsoptions directly.  However, ftsoptions is dynamically modified
+   as the command line is parsed.   The effect of this is that --version
+   cannot reflect thse dynamic options. */
 bool
 is_fts_enabled (int *fts_options)
 {
diff --git a/find/parser.c b/find/parser.c
index 855ed1f8..bbe17641 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -2552,6 +2552,8 @@ parse_version (const struct parser_table* entry, char 
**argv, int *arg_ptr)
     }
 
   flags = 0;
+  /* See function header for is_fts_enabled for limitations on the
+     interpretation of its result. */
   if (is_fts_enabled (&flags))
     {
       int nflags = 0;
@@ -2565,8 +2567,18 @@ parse_version (const struct parser_table* entry, char 
**argv, int *arg_ptr)
              printf (",");
            }
          printf ("FTS_CWDFD");
+         ++nflags;
          has_features = true;
        }
+#if defined(FTS_NOLEAF)
+      if (nflags)
+       {
+         printf (",");
+       }
+      printf ("FTS_NOLEAF=%#x", (unsigned)FTS_NOLEAF);
+      ++nflags;
+      has_features = true;
+#endif
       printf (") ");
     }
 
diff --git a/gnulib-local/lib/fts.c.diff b/gnulib-local/lib/fts.c.diff
new file mode 100644
index 00000000..fa36cf2a
--- /dev/null
+++ b/gnulib-local/lib/fts.c.diff
@@ -0,0 +1,23 @@
+The flag is needed to implement the -noleaf option of find.
+* lib/fts.c (link_count_optimize_ok): Implement the FTS_NOLEAF flag.
+* lib/fts_.h (FTS_NOLEAF): New macro, shifted conflicting constants.
+---
+ lib/fts.c  |  4 ++++
+ lib/fts_.h | 12 +++++++++---
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/lib/fts.c b/lib/fts.c
+index ea73675..76bbc06 100644
+--- a/lib/fts.c
++++ b/lib/fts.c
+@@ -781,6 +781,10 @@ link_count_optimize_ok (FTSENT const *p)
+   bool opt_ok;
+   struct LCO_ent *t2;
+ 
++  if (ISSET(FTS_NOLEAF))
++    /* leaf optimization explicitly disabled by the FTS_NOLEAF flag */
++    return false;
++
+   /* If we're not in CWDFD mode, don't bother with this optimization,
+      since the caller is not serious about performance. */
+   if (!ISSET(FTS_CWDFD))
diff --git a/gnulib-local/lib/fts_.h.diff b/gnulib-local/lib/fts_.h.diff
new file mode 100644
index 00000000..ff9fe666
--- /dev/null
+++ b/gnulib-local/lib/fts_.h.diff
@@ -0,0 +1,24 @@
+diff --git a/lib/fts_.h b/lib/fts_.h
+index b9a3f12..1a500fc 100644
+--- a/lib/fts_.h
++++ b/lib/fts_.h
+@@ -155,10 +155,16 @@ typedef struct {
+      from input path names during fts_open initialization.  */
+ # define FTS_VERBATIM   0x1000
+ 
+-# define FTS_OPTIONMASK 0x1fff          /* valid user option mask */
++  /* Disable leaf optimization (which eliminates stat() calls during 
traversal,
++     based on the count of nested directories stored in stat.st_nlink of each
++     directory).  Note that the optimization is by default enabled only for
++     selected file systems, and only if the FTS_CWDFD flag is set.  */
++# define FTS_NOLEAF     0x2000
+ 
+-# define FTS_NAMEONLY   0x2000          /* (private) child names only */
+-# define FTS_STOP       0x4000          /* (private) unrecoverable error */
++# define FTS_OPTIONMASK 0x3fff          /* valid user option mask */
++
++# define FTS_NAMEONLY   0x4000          /* (private) child names only */
++# define FTS_STOP       0x8000          /* (private) unrecoverable error */
+         int fts_options;                /* fts_open options, global flags */
+ 
+         /* Map a directory's device number to a boolean.  The boolean is
-- 
2.11.0




reply via email to

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