[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
- [Findutils-patches] [PATCH] find: properly support -noleaf in ftsfind.,
James Youngman <=