commit
064578b20e
@ -1,108 +0,0 @@
|
||||
From 26d48c7cf9c25ddc8874d5483c0b5156dcc62132 Mon Sep 17 00:00:00 2001
|
||||
From: Maximiliano Curia <maxy@debian.org>
|
||||
Date: Thu, 30 Jun 2016 01:18:17 +0200
|
||||
Subject: [PATCH 069/224] Fix bug #48314: find: fix -type option regression on
|
||||
some platforms
|
||||
|
||||
Since commit v4.6.0-61-g6c37ce4, the option -type and -ltype is broken
|
||||
on armel, armhf and mipsel at least. The reason is that the union member
|
||||
args of the struct predicate was not completely initialized as its new
|
||||
bool types[] member may be implemented larger than the union member
|
||||
initialized: str.
|
||||
|
||||
* find/tree.c (set_new_parent): Replace xmalloc() by xzalloc() to
|
||||
initialize the complete new predicate structure. Therefore, remove all
|
||||
individual NULL and false initializations.
|
||||
(get_new_pred): Likewise, plus move the xzmalloc() invocations before
|
||||
the if-condition to have only one place left for the allocation, thus
|
||||
improving readability.
|
||||
|
||||
Reported by Andreas Metzler <ametzler@bebt.de> in
|
||||
https://savannah.gnu.org/bugs/?48314
|
||||
|
||||
Co-authored-by: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Copyright-paperwork-exempt: Yes
|
||||
---
|
||||
find/tree.c | 31 +++++--------------------------
|
||||
1 file changed, 5 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/find/tree.c b/find/tree.c
|
||||
index 8a413f88..2bbfbe5a 100644
|
||||
--- a/find/tree.c
|
||||
+++ b/find/tree.c
|
||||
@@ -865,14 +865,11 @@ set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, str
|
||||
{
|
||||
struct predicate *new_parent;
|
||||
|
||||
- new_parent = xmalloc (sizeof (struct predicate));
|
||||
+ /* Allocate + initialize a new predicate. */
|
||||
+ new_parent = xzalloc (sizeof (struct predicate));
|
||||
new_parent->p_type = BI_OP;
|
||||
new_parent->p_prec = high_prec;
|
||||
- new_parent->need_stat = false;
|
||||
- new_parent->need_type = false;
|
||||
- new_parent->need_inum = false;
|
||||
new_parent->p_cost = NeedsNothing;
|
||||
- new_parent->arg_text = NULL;
|
||||
|
||||
switch (high_prec)
|
||||
{
|
||||
@@ -895,14 +892,8 @@ set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, str
|
||||
; /* empty */
|
||||
}
|
||||
|
||||
- new_parent->side_effects = false;
|
||||
- new_parent->no_default_print = false;
|
||||
- new_parent->args.str = NULL;
|
||||
- new_parent->pred_next = NULL;
|
||||
-
|
||||
/* Link in new_parent.
|
||||
Pushes rest of left branch down 1 level to new_parent->pred_right. */
|
||||
- new_parent->pred_left = NULL;
|
||||
new_parent->pred_right = curr;
|
||||
*prevp = new_parent;
|
||||
|
||||
@@ -1488,37 +1479,25 @@ get_new_pred (const struct parser_table *entry)
|
||||
assert (entry->type != ARG_OPTION);
|
||||
assert (entry->type != ARG_POSITIONAL_OPTION);
|
||||
|
||||
+ /* Allocate + initialize a new predicate. */
|
||||
+ new_pred = xzalloc (sizeof (struct predicate));
|
||||
if (predicates == NULL)
|
||||
{
|
||||
- predicates = (struct predicate *)
|
||||
- xmalloc (sizeof (struct predicate));
|
||||
- last_pred = predicates;
|
||||
+ last_pred = predicates = new_pred;
|
||||
}
|
||||
else
|
||||
{
|
||||
- new_pred = xmalloc (sizeof (struct predicate));
|
||||
last_pred->pred_next = new_pred;
|
||||
last_pred = new_pred;
|
||||
}
|
||||
last_pred->parser_entry = entry;
|
||||
- last_pred->pred_func = NULL;
|
||||
- last_pred->p_name = NULL;
|
||||
last_pred->p_type = NO_TYPE;
|
||||
last_pred->p_prec = NO_PREC;
|
||||
- last_pred->side_effects = false;
|
||||
- last_pred->no_default_print = false;
|
||||
last_pred->need_stat = true;
|
||||
last_pred->need_type = true;
|
||||
- last_pred->need_inum = false;
|
||||
last_pred->p_cost = NeedsUnknown;
|
||||
last_pred->arg_text = "ThisShouldBeSetToSomethingElse";
|
||||
- last_pred->args.str = NULL;
|
||||
- last_pred->args.scontext = NULL;
|
||||
- last_pred->pred_next = NULL;
|
||||
- last_pred->pred_left = NULL;
|
||||
- last_pred->pred_right = NULL;
|
||||
last_pred->literal_control_chars = options.literal_control_chars;
|
||||
- last_pred->artificial = false;
|
||||
last_pred->est_success_rate = 1.0;
|
||||
init_pred_perf (last_pred);
|
||||
return last_pred;
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,32 +0,0 @@
|
||||
From bcd85897c2e55d955c325f72791d3ff99eacf820 Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Wed, 30 Dec 2015 20:23:22 +0000
|
||||
Subject: [PATCH 011/224] Remove the --enable-id-cache configure option.
|
||||
|
||||
* configure.ac: Remove the --enable-id-cache option. This option
|
||||
became a no-op in findutils-4.5.15. Before that it did something
|
||||
but the code was buggy. See https://savannah.gnu.org/bugs/?45062
|
||||
for details.
|
||||
* NEWS: State that this configure option is removed.
|
||||
---
|
||||
NEWS | 5 +++++
|
||||
configure.ac | 3 ---
|
||||
2 files changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 0b9ef281..bfc94f1c 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -15,9 +15,6 @@ AC_SUBST(AUXDIR,$ac_aux_dir)
|
||||
dnl check for --with-fts
|
||||
FIND_WITH_FTS
|
||||
|
||||
-AC_ARG_ENABLE(id-cache,
|
||||
-[ --enable-id-cache This currently has no effect.],)
|
||||
-
|
||||
AC_ARG_ENABLE(debug,
|
||||
AS_HELP_STRING(--enable-debug,Enable debugging output which is likely to be interesting to people debugging findutils),
|
||||
[ac_cv_debug=$enableval],[ac_cv_debug=no])
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,30 +0,0 @@
|
||||
From bb51d3581d52890cd1c2b0e5ee919c00b0ba9eb5 Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Thu, 5 Jul 2018 13:34:06 +0100
|
||||
Subject: [PATCH 175/224] Shorten output of qmark_chars after replacing a
|
||||
multibyte characer.
|
||||
|
||||
When qmark_chars() replaces a multibyte character with a single
|
||||
character, this reduces the length of the string. When this happens,
|
||||
terminate the now-shorter string at the new length.
|
||||
|
||||
This is simple workaround for bug http://savannah.gnu.org/bugs/?54236.
|
||||
---
|
||||
lib/printquoted.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/lib/printquoted.c b/lib/printquoted.c
|
||||
index 5a31664b..14665c95 100644
|
||||
--- a/lib/printquoted.c
|
||||
+++ b/lib/printquoted.c
|
||||
@@ -62,6 +62,7 @@ print_quoted (FILE *fp,
|
||||
|
||||
/* Replace any remaining funny characters with '?'. */
|
||||
len = qmark_chars (buf, len);
|
||||
+ buf[len] = 0;
|
||||
|
||||
rv = fprintf (fp, format, buf); /* Print the quoted version */
|
||||
if (buf != smallbuf)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,217 +0,0 @@
|
||||
From e7b976a7e8b4023bd9ac2493341320f88aa9189c Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Sat, 2 Jan 2016 13:04:24 +0000
|
||||
Subject: [PATCH 023/224] find: Fix a number of compiler warnings (mostly
|
||||
const-correctness).
|
||||
|
||||
* find/find.c (get_current_dirfd): remove unused function.
|
||||
(process_dir): make parameters const: parent, pathname, name.
|
||||
(process_path): make parameters const: parent, pathname, name.
|
||||
(at_top): Modify the function pointer parameter accordingly.
|
||||
* find/ftsfind.c (get_fts_info_name): Now returns const char*, not
|
||||
char*.
|
||||
(show_outstanding_execdirs): Fix type of loop variable to avoid
|
||||
possible overflow.
|
||||
(process_all_startpoints): Avoid compiler warning about overflow
|
||||
of int loop variable.
|
||||
* find/defs.h (struct predicate): Make p_name const.
|
||||
(struct state): make rel_pathname const.
|
||||
* find/exec.c (impl_pred_exec): Make prefix const.
|
||||
(launch): Silence compiler warning about unused parameter argc.
|
||||
* find/pred.c (blank_rtrim): Make str parameter const, since we do
|
||||
not modify it.
|
||||
* find/util.c (debug_option_assoc): name and docstring are now
|
||||
const qualified.
|
||||
(show_valid_debug_options): Avoid signed/unsigned comparison by
|
||||
using a size_t array index.
|
||||
(set_stat_placeholders): Avoid a compiler warning on systems
|
||||
lacking birth time fields (and on which this function therefore
|
||||
does nothing).
|
||||
---
|
||||
find/defs.h | 3 ++-
|
||||
find/exec.c | 4 +++-
|
||||
find/ftsfind.c | 6 ++++--
|
||||
find/oldfind.c | 28 +++++++++++++---------------
|
||||
find/util.c | 5 +++--
|
||||
5 files changed, 25 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/find/defs.h b/find/defs.h
|
||||
index a4647e83..981c5336 100644
|
||||
--- a/find/defs.h
|
||||
+++ b/find/defs.h
|
||||
@@ -633,7 +633,8 @@ struct state
|
||||
|
||||
/* The file being operated on, relative to the current directory.
|
||||
Used for stat, readlink, remove, and opendir. */
|
||||
- char *rel_pathname;
|
||||
+ const char *rel_pathname;
|
||||
+
|
||||
/* The directory fd to which rel_pathname is relative. This is relevant
|
||||
* when we're navigating the hierarchy with fts() and using FTS_CWDFD.
|
||||
*/
|
||||
diff --git a/find/exec.c b/find/exec.c
|
||||
index f8bd4389..8d20143f 100644
|
||||
--- a/find/exec.c
|
||||
+++ b/find/exec.c
|
||||
@@ -114,7 +114,7 @@ impl_pred_exec (const char *pathname,
|
||||
const char *target;
|
||||
bool result;
|
||||
const bool local = is_exec_in_local_dir (pred_ptr->pred_func);
|
||||
- char *prefix;
|
||||
+ const char *prefix;
|
||||
size_t pfxlen;
|
||||
|
||||
(void) stat_buf;
|
||||
@@ -292,6 +292,8 @@ launch (struct buildcmd_control *ctl, void *usercontext, int argc, char **argv)
|
||||
static int first_time = 1;
|
||||
struct exec_val *execp = usercontext;
|
||||
|
||||
+ (void) argc; /* silence compiler warning */
|
||||
+
|
||||
/* Make sure output of command doesn't get mixed with find output. */
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
diff --git a/find/ftsfind.c b/find/ftsfind.c
|
||||
index cbb46de9..5128e574 100644
|
||||
--- a/find/ftsfind.c
|
||||
+++ b/find/ftsfind.c
|
||||
@@ -152,7 +152,7 @@ static void init_mounted_dev_list (void);
|
||||
#define STRINGIFY(X) #X
|
||||
#define HANDLECASE(N) case N: return #N;
|
||||
|
||||
-static char *
|
||||
+static const char *
|
||||
get_fts_info_name (int info)
|
||||
{
|
||||
static char buf[10];
|
||||
@@ -615,16 +615,18 @@ static bool
|
||||
process_all_startpoints (int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
+ bool empty = true;
|
||||
|
||||
/* figure out how many start points there are */
|
||||
for (i = 0; i < argc && !looks_like_expression (argv[i], true); i++)
|
||||
{
|
||||
+ empty = false;
|
||||
state.starting_path_length = strlen (argv[i]); /* TODO: is this redundant? */
|
||||
if (!find (argv[i]))
|
||||
return false;
|
||||
}
|
||||
|
||||
- if (i == 0)
|
||||
+ if (empty)
|
||||
{
|
||||
/*
|
||||
* We use a temporary variable here because some actions modify
|
||||
diff --git a/find/oldfind.c b/find/oldfind.c
|
||||
index 986e7b4c..cd235c06 100644
|
||||
--- a/find/oldfind.c
|
||||
+++ b/find/oldfind.c
|
||||
@@ -95,11 +95,9 @@ enum
|
||||
static void init_mounted_dev_list (int mandatory);
|
||||
#endif
|
||||
|
||||
-static void process_top_path (char *pathname, mode_t mode, ino_t inum);
|
||||
-static int process_path (char *pathname, char *name, bool leaf, char *parent, mode_t type, ino_t inum);
|
||||
-static void process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent);
|
||||
-
|
||||
-
|
||||
+static void process_top_path (const char *pathname, mode_t mode, ino_t inum);
|
||||
+static int process_path (const char *pathname, const char *name, bool leaf, const char *parent, mode_t type, ino_t inum);
|
||||
+static void process_dir (const char *pathname, const char *name, int pathlen, const struct stat *statp, const char *parent);
|
||||
|
||||
/* A file descriptor open to the initial working directory.
|
||||
Doing it this way allows us to work when the i.w.d. has
|
||||
@@ -981,12 +979,12 @@ chdir_back (void)
|
||||
* specified directory is a child of "." or is the root directory.
|
||||
*/
|
||||
static void
|
||||
-at_top (char *pathname,
|
||||
+at_top (const char *pathname,
|
||||
mode_t mode,
|
||||
ino_t inum,
|
||||
struct stat *pstat,
|
||||
- void (*action)(char *pathname,
|
||||
- char *basename,
|
||||
+ void (*action)(const char *pathname,
|
||||
+ const char *basename,
|
||||
int mode,
|
||||
ino_t inum,
|
||||
struct stat *pstat))
|
||||
@@ -1056,8 +1054,8 @@ at_top (char *pathname,
|
||||
}
|
||||
|
||||
|
||||
-static void do_process_top_dir (char *pathname,
|
||||
- char *base,
|
||||
+static void do_process_top_dir (const char *pathname,
|
||||
+ const char *base,
|
||||
int mode,
|
||||
ino_t inum,
|
||||
struct stat *pstat)
|
||||
@@ -1069,8 +1067,8 @@ static void do_process_top_dir (char *pathname,
|
||||
}
|
||||
|
||||
static void
|
||||
-do_process_predicate (char *pathname,
|
||||
- char *base,
|
||||
+do_process_predicate (const char *pathname,
|
||||
+ const char *base,
|
||||
int mode,
|
||||
ino_t inum,
|
||||
struct stat *pstat)
|
||||
@@ -1095,7 +1093,7 @@ do_process_predicate (char *pathname,
|
||||
and move to that.
|
||||
*/
|
||||
static void
|
||||
-process_top_path (char *pathname, mode_t mode, ino_t inum)
|
||||
+process_top_path (const char *pathname, mode_t mode, ino_t inum)
|
||||
{
|
||||
at_top (pathname, mode, inum, NULL, do_process_top_dir);
|
||||
}
|
||||
@@ -1181,7 +1179,7 @@ issue_loop_warning (const char *name, const char *pathname, int level)
|
||||
Return nonzero iff PATHNAME is a directory. */
|
||||
|
||||
static int
|
||||
-process_path (char *pathname, char *name, bool leaf, char *parent,
|
||||
+process_path (const char *pathname, const char *name, bool leaf, const char *parent,
|
||||
mode_t mode, ino_t inum)
|
||||
{
|
||||
struct stat stat_buf;
|
||||
@@ -1307,7 +1305,7 @@ process_path (char *pathname, char *name, bool leaf, char *parent,
|
||||
starting directory. */
|
||||
|
||||
static void
|
||||
-process_dir (char *pathname, char *name, int pathlen, const struct stat *statp, char *parent)
|
||||
+process_dir (const char *pathname, const char *name, int pathlen, const struct stat *statp, const char *parent)
|
||||
{
|
||||
int subdirs_left; /* Number of unexamined subdirs in PATHNAME. */
|
||||
bool subdirs_unreliable; /* if true, cannot use dir link count as subdir limif (if false, it may STILL be unreliable) */
|
||||
diff --git a/find/util.c b/find/util.c
|
||||
index cf7965fc..1b4a07af 100644
|
||||
--- a/find/util.c
|
||||
+++ b/find/util.c
|
||||
@@ -55,9 +55,9 @@
|
||||
|
||||
struct debug_option_assoc
|
||||
{
|
||||
- char *name;
|
||||
+ const char *name;
|
||||
int val;
|
||||
- char *docstring;
|
||||
+ const char *docstring;
|
||||
};
|
||||
static struct debug_option_assoc debugassoc[] =
|
||||
{
|
||||
@@ -176,6 +176,7 @@ usage (FILE *fp, int status, char *msg)
|
||||
void
|
||||
set_stat_placeholders (struct stat *p)
|
||||
{
|
||||
+ (void) p; /* silence warning for systems lacking these fields. */
|
||||
#if HAVE_STRUCT_STAT_ST_BIRTHTIME
|
||||
p->st_birthtime = 0;
|
||||
#endif
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,34 +0,0 @@
|
||||
From febde26dd0e66dda5d4060fa29b85443ddc6a865 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Mon, 28 Aug 2017 23:15:12 +0200
|
||||
Subject: [PATCH 117/224] find: avoid buffer-overflow with -printf '%T+'
|
||||
|
||||
* find/print.c (format_date): Increase size of local variable
|
||||
FMT to match the longest possible content.
|
||||
|
||||
Fixes https://bugs.debian.org/873032 reported upstream by
|
||||
Andreas Metzler in https://savannah.gnu.org/bugs/?51841;
|
||||
fix proposed by Kamil Dudka.
|
||||
|
||||
Bug introduced in commit v4.6.0-111-g95816b2, so no released version
|
||||
ever saw this; therefore not adding a NEWS entry.
|
||||
---
|
||||
find/print.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index 682197f4..6b568d9c 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -611,7 +611,7 @@ format_date (struct timespec ts, int kind)
|
||||
char ns_buf[NS_BUF_LEN]; /* -.9999999990 (- sign can happen!)*/
|
||||
int charsprinted, need_ns_suffix;
|
||||
struct tm *tm;
|
||||
- char fmt[6];
|
||||
+ char fmt[12];
|
||||
|
||||
/* human_readable() assumes we pass a buffer which is at least as
|
||||
* long as LONGEST_HUMAN_READABLE. We use an assertion here to
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
From 95816b29d46fb6b64754d4a66e7d918b3f134a1f Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Sun, 23 Jul 2017 22:19:42 +0100
|
||||
Subject: [PATCH 110/224] find: avoid strftime's non-portable %F specifier.
|
||||
|
||||
* find/print.c (format_date): Avoid passing %F to strftime since
|
||||
some implementation lack it. Pass the synonymous %Y-%m-%d
|
||||
instead. This fixes a bug manifesting on HP Tru64 UNIX V5.1B.
|
||||
Reported by Steven M. Schweda <sms@antinode.info>.
|
||||
---
|
||||
find/print.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index db6155c9..682197f4 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -631,7 +631,11 @@ format_date (struct timespec ts, int kind)
|
||||
/* Format the main part of the time. */
|
||||
if (kind == '+')
|
||||
{
|
||||
- strcpy (fmt, "%F+%T");
|
||||
+ /* Avoid %F, some Unix versions lack it. For example:
|
||||
+ HP Tru64 UNIX V5.1B (Rev. 2650); Wed Feb 17 22:59:59 CST 2016
|
||||
+ Also, some older HP-UX versions expand %F as the full month (like %B).
|
||||
+ Reported by Steven M. Schweda <sms@antinode.info> */
|
||||
+ strcpy (fmt, "%Y-%m-%d+%T");
|
||||
need_ns_suffix = 1;
|
||||
}
|
||||
else
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
From 50a7c5d1f572d50d6c9d43d04e9c9fd55d66b466 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Thu, 10 Aug 2017 08:45:56 +0200
|
||||
Subject: [PATCH 113/224] find: avoid usage() in more error cases
|
||||
|
||||
When the user passes a bad command line, then find(1) outputs the
|
||||
error message followed by a short usage() text, e.g. (wrapped):
|
||||
|
||||
$ find . -name a* b*
|
||||
find: paths must precede expression: bfile
|
||||
Usage: find [-H] [-L] [-P] [-Olevel] \
|
||||
[-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
|
||||
|
||||
Omit the usage() text in more cases like this in order to make the
|
||||
error diagnostic more eye-catching.
|
||||
|
||||
* find/tree.c (build_expression_tree): Exit with EXIT_FAILURE
|
||||
immediately in more cases, i.e., without outputting also a short
|
||||
usage() text. While at it, add quotes around the offending argument
|
||||
in one another place.
|
||||
* NEWS (Improvements): Mention the fix.
|
||||
|
||||
Reported in https://savannah.gnu.org/bugs/?51711
|
||||
---
|
||||
NEWS | 3 +++
|
||||
find/tree.c | 17 +++++------------
|
||||
2 files changed, 8 insertions(+), 12 deletions(-)
|
||||
diff --git a/find/tree.c b/find/tree.c
|
||||
index 2bbfbe5a..ee466ea6 100644
|
||||
--- a/find/tree.c
|
||||
+++ b/find/tree.c
|
||||
@@ -1281,10 +1281,7 @@
|
||||
{
|
||||
state.already_issued_stat_error_msg = false;
|
||||
if (!looks_like_expression (argv[i], false))
|
||||
- {
|
||||
- error (0, 0, _("paths must precede expression: %s"), argv[i]);
|
||||
- usage (stderr, 1, NULL);
|
||||
- }
|
||||
+ error (EXIT_FAILURE, 0, _("paths must precede expression: `%s'"), argv[i]);
|
||||
|
||||
predicate_name = argv[i];
|
||||
parse_entry = find_parser (predicate_name);
|
||||
@ -1,45 +0,0 @@
|
||||
From c1556892a639f609e6d63cd456c2062419e06459 Mon Sep 17 00:00:00 2001
|
||||
From: Goffredo Baroncelli <kreijack@inwind.it>
|
||||
Date: Fri, 27 Jan 2017 02:16:08 +0100
|
||||
Subject: [PATCH 090/224] find: fix memory leak in mount list handling
|
||||
|
||||
The following gnulib commit added the structure member me_mntroot
|
||||
which our free_file_system_list function didn't consider, thus leading
|
||||
to a memory leak:
|
||||
http://git.sv.gnu.org/cgit/gnulib.git/commit/?id=c6148bca89e9
|
||||
|
||||
* find/fstype.c (free_file_system_list): Use gnulib's free_mount_entry
|
||||
function to free the mount list instead of free()ing all members here
|
||||
manually.
|
||||
* NEWS (Bug Fixes): Mention the fix.
|
||||
|
||||
Reported in
|
||||
http://lists.gnu.org/archive/html/findutils-patches/2016-12/msg00000.html
|
||||
---
|
||||
NEWS | 3 +++
|
||||
find/fstype.c | 9 +--------
|
||||
2 files changed, 4 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/find/fstype.c b/find/fstype.c
|
||||
index 535f9202..a0ac8bca 100644
|
||||
--- a/find/fstype.c
|
||||
+++ b/find/fstype.c
|
||||
@@ -75,14 +75,7 @@ free_file_system_list (struct mount_entry *p)
|
||||
while (p)
|
||||
{
|
||||
struct mount_entry *pnext = p->me_next;
|
||||
-
|
||||
- free (p->me_devname);
|
||||
- free (p->me_mountdir);
|
||||
-
|
||||
- if (p->me_type_malloced)
|
||||
- free (p->me_type);
|
||||
- p->me_next = NULL;
|
||||
- free (p);
|
||||
+ free_mount_entry (p);
|
||||
p = pnext;
|
||||
}
|
||||
}
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
From 7b7a19c95f236cd18f48e44b7cc6794d21c0369f Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Fri, 20 Jul 2018 10:07:13 +0200
|
||||
Subject: [PATCH 181/224] find: fix -printf %Y output to 'N' for broken links
|
||||
|
||||
The format %Y shall output 'N' for broken links (ENOENT), 'L' for ELOOP,
|
||||
and '?' for any other error when stat()ing the symlink target.
|
||||
|
||||
The %Y implementation implicitly fell back to lstat(); therefore it
|
||||
output 'l' for dangling symlinks.
|
||||
|
||||
$ ln -s ENOENT DANGLE
|
||||
$ find -D stat DANGLE -printf '%y %Y %p\n'
|
||||
fallback_stat(): stat(DANGLE) failed; falling back on lstat()
|
||||
l l DANGLE
|
||||
|
||||
* find/print.c (do_fprintf): For %Y, always follow links to determine
|
||||
the type of the symlink target.
|
||||
* find/testsuite/find.gnu/printf-symlink.exp: Add a test case for broken
|
||||
links and the ELOOP case ...
|
||||
* find/testsuite/find.gnu/printf-symlink.xo: ... with the expected output.
|
||||
* NEWS (Bug fixes): Mention the fix.
|
||||
|
||||
Bug introduced in version v4.5.8 with commit '25e7c5fbf9'.
|
||||
---
|
||||
NEWS | 4 ++++
|
||||
find/print.c | 9 +++++----
|
||||
find/testsuite/find.gnu/printf-symlink.exp | 5 ++++-
|
||||
find/testsuite/find.gnu/printf-symlink.xo | 4 ++++
|
||||
4 files changed, 17 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index 3af3e91d..545df96a 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -1175,11 +1175,12 @@ do_fprintf (struct format_val *dest,
|
||||
if (S_ISLNK (stat_buf->st_mode))
|
||||
{
|
||||
struct stat sbuf;
|
||||
- /* If we would normally follow links, do not do so.
|
||||
- * If we would normally not follow links, do so.
|
||||
+ /* %Y needs to stat the symlink target regardless of
|
||||
+ * whether we would normally follow symbolic links or not.
|
||||
+ * (Actually we do not even come here when following_links()
|
||||
+ * other than the ENOENT case.)
|
||||
*/
|
||||
- if ((following_links () ? optionp_stat : optionl_stat)
|
||||
- (state.rel_pathname, &sbuf) != 0)
|
||||
+ if (fstatat (state.cwd_dir_fd, state.rel_pathname, &sbuf, 0) != 0)
|
||||
{
|
||||
if ( errno == ENOENT )
|
||||
{
|
||||
diff --git a/find/testsuite/find.gnu/printf-symlink.exp b/find/testsuite/find.gnu/printf-symlink.exp
|
||||
index 6acc3e68..453f07fc 100644
|
||||
--- a/find/testsuite/find.gnu/printf-symlink.exp
|
||||
+++ b/find/testsuite/find.gnu/printf-symlink.exp
|
||||
@@ -2,5 +2,8 @@ exec rm -rf tmp
|
||||
exec mkdir tmp
|
||||
exec touch tmp/file
|
||||
exec ln -s file tmp/LINK
|
||||
-find_start p {tmp/LINK -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
|
||||
+exec ln -s ENOENT tmp/DANGLE
|
||||
+exec ln -s SELF tmp/SELF
|
||||
+exec ls -ls tmp
|
||||
+find_start p {tmp/LINK tmp/DANGLE tmp/SELF -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
|
||||
exec rm -rf tmp
|
||||
diff --git a/find/testsuite/find.gnu/printf-symlink.xo b/find/testsuite/find.gnu/printf-symlink.xo
|
||||
index cc2b69c4..08eb83c6 100644
|
||||
--- a/find/testsuite/find.gnu/printf-symlink.xo
|
||||
+++ b/find/testsuite/find.gnu/printf-symlink.xo
|
||||
@@ -1,2 +1,6 @@
|
||||
RESULT: l f tmp/LINK
|
||||
RESULT2: f l tmp/LINK
|
||||
+RESULT: l N tmp/DANGLE
|
||||
+RESULT2: N l tmp/DANGLE
|
||||
+RESULT: l L tmp/SELF
|
||||
+RESULT2: L l tmp/SELF
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,250 +0,0 @@
|
||||
From 2a6129bfccec9f23a50f037e187f85c4d000bc87 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Mon, 20 Feb 2017 18:53:48 +0100
|
||||
Subject: [PATCH 098/224] find: fix -printf '%h' for arguments with one or more
|
||||
trailing slashes
|
||||
|
||||
Previously, find would output the pathname name for the '%h' format
|
||||
when that was passed with a trailing slash:
|
||||
|
||||
$ mkdir foo
|
||||
$ find foo/ -printf '%h/%f\n'
|
||||
foo/foo/
|
||||
|
||||
* find/print.c (do_fprintf -> 'h'): Strip trailing slashes, i.e. any
|
||||
number of directory separators, unless this is the root "/" directory.
|
||||
* find/testsuite/find.gnu/printf-h.exp: Enhance test with various
|
||||
combinations of "/", "./", "foo/", "./foo", "./foolink/", etc.
|
||||
* find/testsuite/find.gnu/printf-h.xo: Add the expected output for the
|
||||
above new test cases.
|
||||
* NEWS: Mention the fix.
|
||||
|
||||
Bug introduced in commit FINDUTILS_4_2_18-1-6-g0fd15a4.
|
||||
|
||||
Reported by Tavian Barnes <tavianator@gmail.com> in
|
||||
https://savannah.gnu.org/bugs/?50259
|
||||
---
|
||||
NEWS | 8 ++-
|
||||
find/print.c | 21 +++++--
|
||||
find/testsuite/find.gnu/printf-h.exp | 94 ++++++++++++++++++++++++++--
|
||||
find/testsuite/find.gnu/printf-h.xo | 70 ++++++++++++++++++++-
|
||||
4 files changed, 181 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index 20351572..db6155c9 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -965,8 +965,18 @@ do_fprintf (struct format_val *dest,
|
||||
case 'h': /* leading directories part of path */
|
||||
/* sanitised */
|
||||
{
|
||||
- cp = strrchr (pathname, '/');
|
||||
- if (cp == NULL) /* No leading directories. */
|
||||
+ char *pname = strdup (pathname);
|
||||
+
|
||||
+ /* Remove trailing slashes - unless it's the root '/' directory. */
|
||||
+ char *s = pname + strlen (pname) -1;
|
||||
+ for ( ; pname <= s; s--)
|
||||
+ if (*s != '/')
|
||||
+ break;
|
||||
+ if (pname < s && *(s+1) == '/')
|
||||
+ *(s+1) = '\0';
|
||||
+
|
||||
+ s = strrchr (pname, '/');
|
||||
+ if (s == NULL) /* No leading directories. */
|
||||
{
|
||||
/* If there is no slash in the pathname, we still
|
||||
* print the string because it contains characters
|
||||
@@ -976,11 +986,10 @@ do_fprintf (struct format_val *dest,
|
||||
}
|
||||
else
|
||||
{
|
||||
- char *s = strdup (pathname);
|
||||
- s[cp - pathname] = 0;
|
||||
- checked_print_quoted (dest, segment->text, s);
|
||||
- free (s);
|
||||
+ *s = '\0';
|
||||
+ checked_print_quoted (dest, segment->text, pname);
|
||||
}
|
||||
+ free (pname);
|
||||
}
|
||||
break;
|
||||
|
||||
diff --git a/find/testsuite/find.gnu/printf-h.exp b/find/testsuite/find.gnu/printf-h.exp
|
||||
index fb0187cc..094a37b5 100644
|
||||
--- a/find/testsuite/find.gnu/printf-h.exp
|
||||
+++ b/find/testsuite/find.gnu/printf-h.exp
|
||||
@@ -1,5 +1,91 @@
|
||||
# Test case for Savannah bug ID #12085.
|
||||
-exec rm -rf tmp
|
||||
-exec touch tmp
|
||||
-find_start p {tmp -printf "RESULT: %h %f\n" }
|
||||
-exec rm -rf tmp
|
||||
+exec rm -rf foo
|
||||
+exec mkdir foo foo/bar
|
||||
+exec ln -s foo foolink
|
||||
+#
|
||||
+# Create the combinations with:
|
||||
+# $ printf '%s \\\n' {,./,.//}{/,.,foo,foolink,foo/bar}{,/,//,/.,//.} | sort -u
|
||||
+#
|
||||
+# Manual check against installed version:
|
||||
+# $ for opt in '' -H -L -P ; do
|
||||
+# printf "\n=== Differences for option: '%s' ===\n" "$opt"
|
||||
+# diff -u0 \
|
||||
+# <( /usr/bin/find $opt {,./,.//}{/,.,foo,foolink,foo/bar}{,/,//,/.,//.} \
|
||||
+# -maxdepth 1 -printf "%h/%f,%%p=%p,%%h='%h',%%f='%f'\n" ) \
|
||||
+# <( ./find $opt {,./,.//}{/,.,foo,foolink,foo/bar}{,/,//,/.,//.} \
|
||||
+# -maxdepth 1 -printf "%h/%f,%%p=%p,%%h='%h',%%f='%f'\n" )
|
||||
+# done | column -t -s,
|
||||
+
|
||||
+find_start p {\
|
||||
+/ \
|
||||
+// \
|
||||
+/// \
|
||||
+///. \
|
||||
+//. \
|
||||
+. \
|
||||
+./ \
|
||||
+.// \
|
||||
+./// \
|
||||
+.//// \
|
||||
+.///// \
|
||||
+./////. \
|
||||
+.////. \
|
||||
+.///. \
|
||||
+.//. \
|
||||
+.//./ \
|
||||
+.//.// \
|
||||
+.//.//. \
|
||||
+.//./. \
|
||||
+./. \
|
||||
+././ \
|
||||
+./.// \
|
||||
+././/. \
|
||||
+././. \
|
||||
+.//foo \
|
||||
+.//foo/ \
|
||||
+.//foo// \
|
||||
+.//foo//. \
|
||||
+.//foo/. \
|
||||
+./foo \
|
||||
+./foo/ \
|
||||
+./foo// \
|
||||
+./foo//. \
|
||||
+./foo/. \
|
||||
+foo \
|
||||
+foo/ \
|
||||
+foo// \
|
||||
+foo//. \
|
||||
+foo/. \
|
||||
+.//foo/bar \
|
||||
+.//foo/bar/ \
|
||||
+.//foo/bar// \
|
||||
+.//foo/bar//. \
|
||||
+.//foo/bar/. \
|
||||
+./foo/bar \
|
||||
+./foo/bar/ \
|
||||
+./foo/bar// \
|
||||
+./foo/bar//. \
|
||||
+./foo/bar/. \
|
||||
+foo/bar \
|
||||
+foo/bar/ \
|
||||
+foo/bar// \
|
||||
+foo/bar//. \
|
||||
+foo/bar/. \
|
||||
+.//foolink \
|
||||
+.//foolink/ \
|
||||
+.//foolink// \
|
||||
+.//foolink//. \
|
||||
+.//foolink/. \
|
||||
+./foolink \
|
||||
+./foolink/ \
|
||||
+./foolink// \
|
||||
+./foolink//. \
|
||||
+./foolink/. \
|
||||
+foolink \
|
||||
+foolink/ \
|
||||
+foolink// \
|
||||
+foolink//. \
|
||||
+foolink/. \
|
||||
+-maxdepth 0 -printf "%p,%h,%f\n" }
|
||||
+
|
||||
+exec rm -rf foo foolink
|
||||
diff --git a/find/testsuite/find.gnu/printf-h.xo b/find/testsuite/find.gnu/printf-h.xo
|
||||
index dc6ce01e..0ed6ad9d 100644
|
||||
--- a/find/testsuite/find.gnu/printf-h.xo
|
||||
+++ b/find/testsuite/find.gnu/printf-h.xo
|
||||
@@ -1 +1,69 @@
|
||||
-RESULT: . tmp
|
||||
+/,,/
|
||||
+//,/,/
|
||||
+///,//,/
|
||||
+///.,//,.
|
||||
+//.,/,.
|
||||
+.,.,.
|
||||
+./,.,./
|
||||
+.//,./,./
|
||||
+.///,.//,./
|
||||
+.////,.///,./
|
||||
+./////,.////,./
|
||||
+./////.,.////,.
|
||||
+.////.,.///,.
|
||||
+.///.,.//,.
|
||||
+.//.,./,.
|
||||
+.//./,./,./
|
||||
+.//.//,./,./
|
||||
+.//.//.,.//./,.
|
||||
+.//./.,.//.,.
|
||||
+./.,.,.
|
||||
+././,.,./
|
||||
+././/,.,./
|
||||
+././/.,././,.
|
||||
+././.,./.,.
|
||||
+.//foo/bar,.//foo,bar
|
||||
+.//foo/bar/,.//foo,bar/
|
||||
+.//foo/bar//,.//foo,bar/
|
||||
+.//foo/bar//.,.//foo/bar/,.
|
||||
+.//foo/bar/.,.//foo/bar,.
|
||||
+./foo/bar,./foo,bar
|
||||
+./foo/bar/,./foo,bar/
|
||||
+./foo/bar//,./foo,bar/
|
||||
+./foo/bar//.,./foo/bar/,.
|
||||
+./foo/bar/.,./foo/bar,.
|
||||
+foo/bar,foo,bar
|
||||
+foo/bar/,foo,bar/
|
||||
+foo/bar//,foo,bar/
|
||||
+foo/bar//.,foo/bar/,.
|
||||
+foo/bar/.,foo/bar,.
|
||||
+.//foo,./,foo
|
||||
+.//foo/,./,foo/
|
||||
+.//foo//,./,foo/
|
||||
+.//foo//.,.//foo/,.
|
||||
+.//foo/.,.//foo,.
|
||||
+./foo,.,foo
|
||||
+./foo/,.,foo/
|
||||
+./foo//,.,foo/
|
||||
+./foo//.,./foo/,.
|
||||
+./foo/.,./foo,.
|
||||
+foo,.,foo
|
||||
+foo/,.,foo/
|
||||
+foo//,.,foo/
|
||||
+foo//.,foo/,.
|
||||
+foo/.,foo,.
|
||||
+.//foolink,./,foolink
|
||||
+.//foolink/,./,foolink/
|
||||
+.//foolink//,./,foolink/
|
||||
+.//foolink//.,.//foolink/,.
|
||||
+.//foolink/.,.//foolink,.
|
||||
+./foolink,.,foolink
|
||||
+./foolink/,.,foolink/
|
||||
+./foolink//,.,foolink/
|
||||
+./foolink//.,./foolink/,.
|
||||
+./foolink/.,./foolink,.
|
||||
+foolink,.,foolink
|
||||
+foolink/,.,foolink/
|
||||
+foolink//,.,foolink/
|
||||
+foolink//.,foolink/,.
|
||||
+foolink/.,foolink,.
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,47 +0,0 @@
|
||||
From 9530e31f6d4febf8ff08f931f70b40d41603ef8d Mon Sep 17 00:00:00 2001
|
||||
From: Assaf Gordon <assafgordon@gmail.com>
|
||||
Date: Wed, 16 Aug 2017 14:09:17 -0600
|
||||
Subject: [PATCH 114/224] find: give helpful hint for unquoted patterns errors
|
||||
|
||||
Try to detect cases where the user provided an unquoted shell-glob
|
||||
pattern (which was expanded by the shell before calling find(1),
|
||||
resulting in an invalid usage).
|
||||
|
||||
$ touch a.txt b.txt c.txt
|
||||
$ find -name *.txt
|
||||
find: paths must precede expression: `b.txt'
|
||||
find: possible unquoted pattern after predicate `-name'?
|
||||
|
||||
Continuation of
|
||||
https://savannah.gnu.org/bugs/?51711
|
||||
https://lists.gnu.org/archive/html/bug-findutils/2017-08/msg00000.html
|
||||
https://git.sv.gnu.org/cgit/findutils.git/commit/?id=50a7c5d1f572
|
||||
|
||||
* find/tree.c (build_expression_tree): If the offending argument is an
|
||||
existing file, print a hint with the last (valid) predicate.
|
||||
---
|
||||
find/tree.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/tree.c b/find/tree.c
|
||||
index ee466ea6..cc7772d2 100644
|
||||
--- a/find/tree.c
|
||||
+++ b/find/tree.c
|
||||
@@ -1275,7 +1275,13 @@ build_expression_tree (int argc, char *argv[], int end_of_leading_options)
|
||||
{
|
||||
state.already_issued_stat_error_msg = false;
|
||||
if (!looks_like_expression (argv[i], false))
|
||||
- error (EXIT_FAILURE, 0, _("paths must precede expression: `%s'"), argv[i]);
|
||||
+ {
|
||||
+ error (0, 0, _("paths must precede expression: `%s'"), argv[i]);
|
||||
+ if (access(argv[i], F_OK)==0)
|
||||
+ error (0, 0, _("possible unquoted pattern after predicate `%s'?"),
|
||||
+ last_pred->p_name);
|
||||
+ exit (EXIT_FAILURE);
|
||||
+ }
|
||||
|
||||
predicate_name = argv[i];
|
||||
parse_entry = find_parser (predicate_name);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
From 7a6e548690b116878070665bd9844275823bb730 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Wed, 2 Nov 2016 07:32:01 +0100
|
||||
Subject: [PATCH 080/224] find: handle more readdir(3) errors
|
||||
|
||||
Similar to the FTS readdir fix in v4.6.0-72-g155c9d1, handle the last
|
||||
two unhandled readdir(3) errors.
|
||||
|
||||
* find/pred.c (pred_empty): Do the above.
|
||||
* lib/fdleak.c (get_proc_max_fd): Likewise. While at it, fix the
|
||||
condition to only skip "." and ".."; previously, also other files
|
||||
beginning with ".." would have been skipped - that was theoretically,
|
||||
as we only expect the FD files in "/proc/self/fd".
|
||||
---
|
||||
find/pred.c | 10 ++++++++++
|
||||
lib/fdleak.c | 21 +++++++++++++++++----
|
||||
2 files changed, 27 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/find/pred.c b/find/pred.c
|
||||
index f7e9b59c..c064606d 100644
|
||||
--- a/find/pred.c
|
||||
+++ b/find/pred.c
|
||||
@@ -380,6 +380,9 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
|
||||
state.exit_status = 1;
|
||||
return false;
|
||||
}
|
||||
+ /* errno is not touched in the loop body, so initializing it here
|
||||
+ * once before the loop is enough to detect readdir(3) errors. */
|
||||
+ errno = 0;
|
||||
for (dp = readdir (d); dp; dp = readdir (d))
|
||||
{
|
||||
if (dp->d_name[0] != '.'
|
||||
@@ -390,6 +393,13 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ if (errno)
|
||||
+ {
|
||||
+ /* Handle errors from readdir(3). */
|
||||
+ error (0, errno, "%s", safely_quote_err_filename (0, pathname));
|
||||
+ state.exit_status = 1;
|
||||
+ return false;
|
||||
+ }
|
||||
if (CLOSEDIR (d))
|
||||
{
|
||||
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
|
||||
diff --git a/lib/fdleak.c b/lib/fdleak.c
|
||||
index 5dc4cb1e..cf19fa26 100644
|
||||
--- a/lib/fdleak.c
|
||||
+++ b/lib/fdleak.c
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
/* system headers. */
|
||||
#include <assert.h>
|
||||
+#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <poll.h>
|
||||
@@ -77,11 +78,23 @@ get_proc_max_fd (void)
|
||||
int good = 0;
|
||||
struct dirent *dent;
|
||||
|
||||
- while ((dent=readdir (dir)) != NULL)
|
||||
- {
|
||||
+ while (1)
|
||||
+ {
|
||||
+ errno = 0;
|
||||
+ dent = readdir (dir);
|
||||
+ if (NULL == dent)
|
||||
+ {
|
||||
+ if (errno)
|
||||
+ {
|
||||
+ error (0, errno, "%s", quotearg_n_style (0, locale_quoting_style, path));
|
||||
+ good = 0;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
if (dent->d_name[0] != '.'
|
||||
- || (dent->d_name[0] != 0
|
||||
- && dent->d_name[1] != 0 && dent->d_name[1] != '.'))
|
||||
+ || (dent->d_name[1] != 0
|
||||
+ && (dent->d_name[1] != '.' || dent->d_name[2] != 0)))
|
||||
{
|
||||
const int fd = safe_atoi (dent->d_name, literal_quoting_style);
|
||||
if (fd > maxfd)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,73 +0,0 @@
|
||||
From 66174c10c617a1a50fa804c1e2f9c6becd7c90f8 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Wed, 26 Dec 2018 10:47:11 +0100
|
||||
Subject: [PATCH 207/224] find: improve warning diagnostic for the -name/-iname
|
||||
with '/' in pattern
|
||||
|
||||
* find/parser.c (check_name_arg): Add parameter ALT for the alternative
|
||||
option to suggest. Avoid confusing quoting in the warning by making
|
||||
the message more terse.
|
||||
(parse_iname): Pass "-iwholename" as alternative parameter.
|
||||
(parse_name): Pass "-wholename" as alternative parameter.
|
||||
|
||||
Reported by Andreas Metzler in
|
||||
https://sv.gnu.org/bugs/?55272
|
||||
---
|
||||
find/parser.c | 24 +++++++++++-------------
|
||||
1 file changed, 11 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/find/parser.c b/find/parser.c
|
||||
index ae456ddb..a3b9e762 100644
|
||||
--- a/find/parser.c
|
||||
+++ b/find/parser.c
|
||||
@@ -1257,20 +1257,18 @@ fnmatch_sanitycheck (void)
|
||||
|
||||
|
||||
static bool
|
||||
-check_name_arg (const char *pred, const char *arg)
|
||||
+check_name_arg (const char *pred, const char *alt, const char *arg)
|
||||
{
|
||||
if (should_issue_warnings () && strchr (arg, '/'))
|
||||
{
|
||||
- error (0, 0,_("warning: Unix filenames usually don't contain slashes "
|
||||
- "(though pathnames do). That means that '%s %s' will "
|
||||
- "probably evaluate to false all the time on this system. "
|
||||
- "You might find the '-wholename' test more useful, or "
|
||||
- "perhaps '-samefile'. Alternatively, if you are using "
|
||||
- "GNU grep, you could "
|
||||
- "use 'find ... -print0 | grep -FzZ %s'."),
|
||||
- pred,
|
||||
- safely_quote_err_filename (0, arg),
|
||||
- safely_quote_err_filename (1, arg));
|
||||
+ error (0, 0,
|
||||
+ _("warning: %s matches against basenames only, "
|
||||
+ "but the given pattern contains a directory separator (%s), "
|
||||
+ "thus the expression will evaluate to false all the time. "
|
||||
+ "Did you mean %s?"),
|
||||
+ safely_quote_err_filename (0, pred),
|
||||
+ safely_quote_err_filename (1, "/"),
|
||||
+ safely_quote_err_filename (2, alt));
|
||||
}
|
||||
return true; /* allow it anyway */
|
||||
}
|
||||
@@ -1284,7 +1282,7 @@ parse_iname (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
fnmatch_sanitycheck ();
|
||||
if (collect_arg (argv, arg_ptr, &name))
|
||||
{
|
||||
- if (check_name_arg ("-iname", name))
|
||||
+ if (check_name_arg ("-iname", "-iwholename", name))
|
||||
{
|
||||
struct predicate *our_pred = insert_primary (entry, name);
|
||||
our_pred->need_stat = our_pred->need_type = false;
|
||||
@@ -1471,7 +1469,7 @@ parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
if (collect_arg (argv, arg_ptr, &name))
|
||||
{
|
||||
fnmatch_sanitycheck ();
|
||||
- if (check_name_arg ("-name", name))
|
||||
+ if (check_name_arg ("-name", "-wholename", name))
|
||||
{
|
||||
struct predicate *our_pred = insert_primary (entry, name);
|
||||
our_pred->need_stat = our_pred->need_type = false;
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
From 0afb2efada7e435ae18ef7d3db0758464189f44f Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 30 Jan 2018 23:30:09 +0100
|
||||
Subject: [PATCH 159/224] find: make -delete honour the -ignore_readdir_race
|
||||
option
|
||||
|
||||
* find/pred.c (pred_delete): Return true when the -ignore_readdir_race
|
||||
option is active and unlinkat() came back with ENOENT.
|
||||
* doc/find.texi (Option -ignore_readdir_race): Document the change.
|
||||
(Action -delete): Likewise.
|
||||
* find/find.1: Likewise.
|
||||
* NEWS (Bug Fixes): Mention the fix.
|
||||
|
||||
For now, it seems a bit hard to add a proper test for this,
|
||||
so the following shell snippet demonstrates the race:
|
||||
|
||||
$ seq 10 | xargs touch
|
||||
$ env time -f 'find exit status: %x\nfind time: %e' \
|
||||
find -ignore_readdir_race -type f \
|
||||
-delete \
|
||||
-exec sh -c 'sleep $(basename {})' \; \
|
||||
-printf 'find deleted: %p\n' \
|
||||
& \
|
||||
sleep 20; \
|
||||
seq 10 | xargs rm -fv; \
|
||||
wait $!
|
||||
|
||||
Reported by Alexander Golubev in
|
||||
https://savannah.gnu.org/bugs/?52981
|
||||
---
|
||||
NEWS | 4 ++++
|
||||
doc/find.texi | 15 ++++++++++++++-
|
||||
find/find.1 | 22 ++++++++++++++++++++++
|
||||
find/pred.c | 6 ++++++
|
||||
4 files changed, 46 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index 3580be75..0089193e 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -1424,7 +1424,15 @@ gives a significant increase in search speed.
|
||||
If a file disappears after its name has been read from a directory but
|
||||
before @code{find} gets around to examining the file with @code{stat},
|
||||
don't issue an error message. If you don't specify this option, an
|
||||
-error message will be issued. This option can be useful in system
|
||||
+error message will be issued.
|
||||
+
|
||||
+Furthermore, @code{find} with the @samp{-ignore_readdir_race} option
|
||||
+will ignore errors of the @samp{-delete} action in the case the file
|
||||
+has disappeared since the parent directory was read: it will not output
|
||||
+an error diagnostic, and the return code of the @samp{-delete} action
|
||||
+will be true.
|
||||
+
|
||||
+This option can be useful in system
|
||||
scripts (cron scripts, for example) that examine areas of the
|
||||
filesystem that change frequently (mail queues, temporary directories,
|
||||
and so forth), because this scenario is common for those sorts of
|
||||
@@ -2787,6 +2795,11 @@ explicitly.
|
||||
|
||||
If @samp{-delete} fails, @code{find}'s exit status will be nonzero
|
||||
(when it eventually exits).
|
||||
+
|
||||
+Together with the @samp{-ignore_readdir_race} option, @code{find} will
|
||||
+ignore errors of the @samp{-delete} action in the case the file has disappeared
|
||||
+since the parent directory was read: it will not output an error diagnostic, and
|
||||
+the return code of the @samp{-delete} action will be true.
|
||||
@end deffn
|
||||
|
||||
@node Adding Tests
|
||||
diff --git a/find/pred.c b/find/pred.c
|
||||
index 7e2a7bde..af3bacbc 100644
|
||||
--- a/find/pred.c
|
||||
+++ b/find/pred.c
|
||||
@@ -316,6 +316,12 @@ pred_delete (const char *pathname, struct stat *stat_buf, struct predicate *pred
|
||||
}
|
||||
else
|
||||
{
|
||||
+ if (ENOENT == errno && options.ignore_readdir_race)
|
||||
+ {
|
||||
+ /* Ignore unlink() error for vanished files. */
|
||||
+ errno = 0;
|
||||
+ return true;
|
||||
+ }
|
||||
if (EISDIR == errno)
|
||||
{
|
||||
if ((flags & AT_REMOVEDIR) == 0)
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
From 235f21673cd8e3458795cdadca6e78a3423ab024 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Sat, 9 Feb 2019 15:57:19 +0100
|
||||
Subject: [PATCH 224/224] find: make pred_empty safer and avoid fd leaks
|
||||
|
||||
There is a small race condition between the previous stat call
|
||||
and openat/fdopendir (which cannot be avoided): if the directory
|
||||
got replaced by another file type, then openat would succeed but the
|
||||
subsequent fdopendir would fail with ENOTDIR. Detect this earlier
|
||||
by passing the O_DIRECTORY flag.
|
||||
Furthermore, the opened file descriptor was leaked in that case
|
||||
(bug introduced in FINDUTILS_4_3_2-1-80-gb46b0d89 in 2007).
|
||||
Later on, after a readdir error, also the directory stream was leaked
|
||||
(bug introduced by myself in commit 7a6e548690b1).
|
||||
|
||||
* find/pred.c (pred_empty): Add more flags to the openat call,
|
||||
especially O_DIRECTORY; inspired by gnulib's opendirat module.
|
||||
Close the file descriptor when fdopendir failed.
|
||||
Close the directory stream when readdir failed.
|
||||
---
|
||||
find/pred.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/find/pred.c b/find/pred.c
|
||||
index e34a41dc..688103d6 100644
|
||||
--- a/find/pred.c
|
||||
+++ b/find/pred.c
|
||||
@@ -363,9 +363,9 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
|
||||
errno = 0;
|
||||
if ((fd = openat (state.cwd_dir_fd, state.rel_pathname, O_RDONLY
|
||||
#if defined O_LARGEFILE
|
||||
- |O_LARGEFILE
|
||||
+ | O_LARGEFILE
|
||||
#endif
|
||||
- )) < 0)
|
||||
+ | O_CLOEXEC | O_DIRECTORY | O_NOCTTY | O_NONBLOCK)) < 0)
|
||||
{
|
||||
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
|
||||
state.exit_status = 1;
|
||||
@@ -376,6 +376,7 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
|
||||
{
|
||||
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
|
||||
state.exit_status = 1;
|
||||
+ close (fd);
|
||||
return false;
|
||||
}
|
||||
/* errno is not touched in the loop body, so initializing it here
|
||||
@@ -396,6 +397,7 @@ pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_
|
||||
/* Handle errors from readdir(3). */
|
||||
error (0, errno, "%s", safely_quote_err_filename (0, pathname));
|
||||
state.exit_status = 1;
|
||||
+ CLOSEDIR (d);
|
||||
return false;
|
||||
}
|
||||
if (CLOSEDIR (d))
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,74 +0,0 @@
|
||||
From ba6be2889642010c8f30affe403981aa2cc39631 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 24 Jul 2018 08:34:38 +0200
|
||||
Subject: [PATCH 184/224] find -printf %Y: handle ENOTDIR also as broken
|
||||
symlink
|
||||
|
||||
The above command should output 'N' (for broken symlinks) not only in
|
||||
the ENOENT case, but also when an intermediate part of the symlink target
|
||||
file name is a file (ENOTDIR):
|
||||
|
||||
$ touch file
|
||||
$ ln -s file/ENOTDIR link
|
||||
$ find link -printf '%Y %p\n'
|
||||
N link
|
||||
|
||||
Previously, find output 'l' as for a resolvable symlink.
|
||||
|
||||
* find/print.c (do_fprintf): Treat ENOTDIR the same as ENOENT to detect
|
||||
broken symlinks.
|
||||
* find/testsuite/find.gnu/printf-symlink.exp: Extend the test, and ...
|
||||
* find/testsuite/find.gnu/printf-symlink.xo: ... the expected output.
|
||||
* NEWS (Bug fixes, #54262): Explicitly mention that both ENOENT and ENOTDIR
|
||||
are used to detect broken symlinks.
|
||||
|
||||
Suggested by Tavian Barnes.
|
||||
---
|
||||
NEWS | 4 ++--
|
||||
find/print.c | 2 +-
|
||||
find/testsuite/find.gnu/printf-symlink.exp | 3 ++-
|
||||
find/testsuite/find.gnu/printf-symlink.xo | 2 ++
|
||||
4 files changed, 7 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index 24bd9692..1bfccbfc 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -1182,7 +1182,7 @@ do_fprintf (struct format_val *dest,
|
||||
*/
|
||||
if (fstatat (state.cwd_dir_fd, state.rel_pathname, &sbuf, 0) != 0)
|
||||
{
|
||||
- if ( errno == ENOENT )
|
||||
+ if ( (errno == ENOENT) || (errno == ENOTDIR) )
|
||||
{
|
||||
checked_fprintf (dest, segment->text, "N");
|
||||
break;
|
||||
diff --git a/find/testsuite/find.gnu/printf-symlink.exp b/find/testsuite/find.gnu/printf-symlink.exp
|
||||
index 453f07fc..077f18b5 100644
|
||||
--- a/find/testsuite/find.gnu/printf-symlink.exp
|
||||
+++ b/find/testsuite/find.gnu/printf-symlink.exp
|
||||
@@ -3,7 +3,8 @@ exec mkdir tmp
|
||||
exec touch tmp/file
|
||||
exec ln -s file tmp/LINK
|
||||
exec ln -s ENOENT tmp/DANGLE
|
||||
+exec ln -s file/ENOTDIR tmp/ENOTDIR
|
||||
exec ln -s SELF tmp/SELF
|
||||
exec ls -ls tmp
|
||||
-find_start p {tmp/LINK tmp/DANGLE tmp/SELF -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
|
||||
+find_start p {tmp/LINK tmp/DANGLE tmp/ENOTDIR tmp/SELF -printf "RESULT: %y %Y %p\n" -printf "RESULT2: %Y %y %p\n" }
|
||||
exec rm -rf tmp
|
||||
diff --git a/find/testsuite/find.gnu/printf-symlink.xo b/find/testsuite/find.gnu/printf-symlink.xo
|
||||
index 08eb83c6..978c6673 100644
|
||||
--- a/find/testsuite/find.gnu/printf-symlink.xo
|
||||
+++ b/find/testsuite/find.gnu/printf-symlink.xo
|
||||
@@ -2,5 +2,7 @@ RESULT: l f tmp/LINK
|
||||
RESULT2: f l tmp/LINK
|
||||
RESULT: l N tmp/DANGLE
|
||||
RESULT2: N l tmp/DANGLE
|
||||
+RESULT: l N tmp/ENOTDIR
|
||||
+RESULT2: N l tmp/ENOTDIR
|
||||
RESULT: l L tmp/SELF
|
||||
RESULT2: L l tmp/SELF
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
From 22ff99e150faa82980361e577cff643cc17e7fac Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Sun, 8 Jul 2018 00:17:27 +0200
|
||||
Subject: [PATCH 176/224] find: process unreadable directories with -depth
|
||||
|
||||
* find/ftsfind.c (consider_visiting): Split the FTS_ERR and FTS_DNR
|
||||
cases to be able to continue processing that entry in the latter case
|
||||
(unreadable directory) when the -depth option is given.
|
||||
* NEWS (Bug Fixes): Mention the fix.
|
||||
|
||||
Reported by Tavian Barnes in https://savannah.gnu.org/bugs/?54171.
|
||||
---
|
||||
NEWS | 4 ++++
|
||||
find/ftsfind.c | 15 +++++++++++++--
|
||||
2 files changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/find/ftsfind.c b/find/ftsfind.c
|
||||
index 0e2aca33..607ea8d3 100644
|
||||
--- a/find/ftsfind.c
|
||||
+++ b/find/ftsfind.c
|
||||
@@ -342,12 +342,23 @@ consider_visiting (FTS *p, FTSENT *ent)
|
||||
statbuf.st_ino = ent->fts_statp->st_ino;
|
||||
|
||||
/* Cope with various error conditions. */
|
||||
- if (ent->fts_info == FTS_ERR
|
||||
- || ent->fts_info == FTS_DNR)
|
||||
+ if (ent->fts_info == FTS_ERR)
|
||||
{
|
||||
nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
|
||||
return;
|
||||
}
|
||||
+ if (ent->fts_info == FTS_DNR)
|
||||
+ {
|
||||
+ nonfatal_target_file_error (ent->fts_errno, ent->fts_path);
|
||||
+ if (options.do_dir_first)
|
||||
+ {
|
||||
+ /* Return for unreadable directories without -depth.
|
||||
+ * With -depth, the directory itself has to be processed, yet the
|
||||
+ * error message above has to be output.
|
||||
+ */
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
else if (ent->fts_info == FTS_DC)
|
||||
{
|
||||
issue_loop_warning (ent);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
From 17e470dc1acca4824b70328d733d5f99c12d0d65 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Wed, 11 May 2011 16:46:45 +0200
|
||||
Subject: [PATCH 3/4] findutils-4.4.2-xautofs.patch
|
||||
Subject: [PATCH] findutils-4.4.2-xautofs.patch
|
||||
|
||||
---
|
||||
doc/find.texi | 4 ++++
|
||||
find/defs.h | 3 +++
|
||||
find/find.1 | 3 +++
|
||||
find/ftsfind.c | 6 ++++++
|
||||
find/parser.c | 11 ++++++++++-
|
||||
find/util.c | 1 +
|
||||
find/parser.c | 9 +++++++++
|
||||
find/util.c | 3 ++-
|
||||
6 files changed, 27 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index c584298..9731b71 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -1446,6 +1446,10 @@ them.
|
||||
@@ -1474,6 +1474,10 @@ them.
|
||||
There are two ways to avoid searching certain filesystems. One way is
|
||||
to tell @code{find} to only search one filesystem:
|
||||
|
||||
|
||||
+@deffn Option -xautofs
|
||||
+Don't descend directories on autofs filesystems.
|
||||
+@end deffn
|
||||
@ -31,10 +31,10 @@ diff --git a/find/defs.h b/find/defs.h
|
||||
index 11d1d00..f95ce72 100644
|
||||
--- a/find/defs.h
|
||||
+++ b/find/defs.h
|
||||
@@ -557,6 +557,9 @@ struct options
|
||||
@@ -574,6 +574,9 @@ struct options
|
||||
/* If true, don't cross filesystem boundaries. */
|
||||
bool stay_on_filesystem;
|
||||
|
||||
|
||||
+ /* If true, don't descend directories on autofs filesystems. */
|
||||
+ bool bypass_autofs;
|
||||
+
|
||||
@ -45,24 +45,24 @@ diff --git a/find/find.1 b/find/find.1
|
||||
index e851f82..a4799ff 100644
|
||||
--- a/find/find.1
|
||||
+++ b/find/find.1
|
||||
@@ -520,6 +520,9 @@ to stat them; this gives a significant increase in search speed.
|
||||
@@ -567,6 +567,9 @@ to stat them; this gives a significant increase in search speed.
|
||||
.IP "\-version, \-\-version"
|
||||
Print the \fBfind\fR version number and exit.
|
||||
|
||||
|
||||
+.IP \-xautofs
|
||||
+Don't descend directories on autofs filesystems.
|
||||
+
|
||||
.IP \-xdev
|
||||
Don't descend directories on other filesystems.
|
||||
|
||||
|
||||
diff --git a/find/ftsfind.c b/find/ftsfind.c
|
||||
index 9fdb8ef..bd7cc37 100644
|
||||
--- a/find/ftsfind.c
|
||||
+++ b/find/ftsfind.c
|
||||
@@ -485,6 +485,12 @@ consider_visiting (FTS *p, FTSENT *ent)
|
||||
}
|
||||
@@ -479,6 +479,12 @@ consider_visiting (FTS *p, FTSENT *ent)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+ if (options.bypass_autofs &&
|
||||
+ 0 == strcmp ("autofs", filesystem_type (&statbuf, ent->fts_name)))
|
||||
+ {
|
||||
@ -76,57 +76,56 @@ diff --git a/find/parser.c b/find/parser.c
|
||||
index 52a1ef6..995aec3 100644
|
||||
--- a/find/parser.c
|
||||
+++ b/find/parser.c
|
||||
@@ -146,6 +146,7 @@ static bool parse_user (const struct parser_table*, char *argv[], int *
|
||||
static bool parse_version (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
@@ -138,6 +138,7 @@ static bool parse_used (const struct parser_table*, char *argv[], int *
|
||||
static bool parse_user (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
static bool parse_wholename (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
static bool parse_xdev (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
+static bool parse_xautofs (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
static bool parse_ignore_race (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
static bool parse_noignore_race (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
static bool parse_warn (const struct parser_table*, char *argv[], int *arg_ptr);
|
||||
@@ -306,6 +307,7 @@ static struct parser_table const parse_table[] =
|
||||
PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced -path, but anyway -path will soon be in POSIX */
|
||||
@@ -302,6 +303,7 @@ static struct parser_table const parse_table[] =
|
||||
PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced -path, but now -path is standardized since POSIX 2008 */
|
||||
{ARG_TEST, "writable", parse_accesscheck, pred_writable}, /* GNU, 4.3.0+ */
|
||||
PARSE_OPTION ("xdev", xdev), /* POSIX */
|
||||
+ PARSE_OPTION ("xautofs", xautofs),
|
||||
PARSE_TEST ("xtype", xtype), /* GNU */
|
||||
PARSE_TEST ("xtype", xtype), /* GNU */
|
||||
#ifdef UNIMPLEMENTED_UNIX
|
||||
/* It's pretty ugly for find to know about archive formats.
|
||||
@@ -1239,7 +1241,7 @@ operators (decreasing precedence; -and is implicit where no others are given):\n
|
||||
positional options (always true): -daystart -follow -regextype\n\n\
|
||||
normal options (always true, specified before other expressions):\n\
|
||||
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
|
||||
- --version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
|
||||
+ --version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race\n"));
|
||||
puts (_("\
|
||||
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
|
||||
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
|
||||
@@ -2683,6 +2685,13 @@ parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
@@ -2603,6 +2605,13 @@ parse_xdev (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
return parse_noop (entry, argv, arg_ptr);
|
||||
}
|
||||
|
||||
static bool
|
||||
|
||||
+static bool
|
||||
+parse_xautofs (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
+{
|
||||
+ options.bypass_autofs = true;
|
||||
+ return parse_noop (entry, argv, arg_ptr);
|
||||
+}
|
||||
+
|
||||
+static bool
|
||||
static bool
|
||||
parse_ignore_race (const struct parser_table* entry, char **argv, int *arg_ptr)
|
||||
{
|
||||
options.ignore_readdir_race = true;
|
||||
diff --git a/find/util.c b/find/util.c
|
||||
index 8577396..4d45f84 100644
|
||||
--- a/find/util.c
|
||||
+++ b/find/util.c
|
||||
@@ -1017,6 +1017,7 @@ set_option_defaults (struct options *p)
|
||||
|
||||
@@ -181,7 +181,7 @@ operators (decreasing precedence; -and is implicit where no others are given):\n
|
||||
positional options (always true): -daystart -follow -regextype\n\n\
|
||||
normal options (always true, specified before other expressions):\n\
|
||||
-depth --help -maxdepth LEVELS -mindepth LEVELS -mount -noleaf\n\
|
||||
- --version -xdev -ignore_readdir_race -noignore_readdir_race\n"));
|
||||
+ --version -xautofs -xdev -ignore_readdir_race -noignore_readdir_race\n"));
|
||||
HTL (_("\
|
||||
tests (N can be +N or -N or N): -amin N -anewer FILE -atime N -cmin N\n\
|
||||
-cnewer FILE -ctime N -empty -false -fstype TYPE -gid N -group NAME\n\
|
||||
@@ -1044,6 +1044,7 @@ set_option_defaults (struct options *p)
|
||||
|
||||
p->full_days = false;
|
||||
p->stay_on_filesystem = false;
|
||||
+ p->bypass_autofs = false;
|
||||
p->ignore_readdir_race = false;
|
||||
|
||||
if (p->posixly_correct)
|
||||
--
|
||||
1.7.4.4
|
||||
|
||||
if (p->posixly_correct)
|
||||
--
|
||||
1.7.4.4
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
From 690d4bd9f29a805999a3ce4651dac9585ccc9917 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Wed, 11 May 2011 16:46:57 +0200
|
||||
Subject: [PATCH 1/2] findutils-4.5.7-warnings.patch
|
||||
|
||||
---
|
||||
xargs/xargs.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/xargs/xargs.c b/xargs/xargs.c
|
||||
index 5e373f2..c0a8676 100644
|
||||
--- a/xargs/xargs.c
|
||||
+++ b/xargs/xargs.c
|
||||
@@ -1289,7 +1289,8 @@ xargs_do_exec (struct buildcmd_control *ctl, void *usercontext, int argc, char *
|
||||
* utility if we run it, for POSIX compliance on the
|
||||
* handling of exit values.
|
||||
*/
|
||||
- write (fd[1], &errno, sizeof (int));
|
||||
+ int sink = write (fd[1], &errno, sizeof (int));
|
||||
+ (void) sink;
|
||||
}
|
||||
|
||||
close (fd[1]);
|
||||
--
|
||||
1.7.1
|
||||
|
||||
|
||||
From c5654b9ca5f50daa1ca406ebd7b4546f24d00db6 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 23 Sep 2013 15:04:03 +0200
|
||||
Subject: [PATCH 2/2] parser: silence a [-Wmaybe-uninitialized] GCC warning
|
||||
|
||||
... caused by a missing model of error()
|
||||
---
|
||||
find/parser.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/parser.c b/find/parser.c
|
||||
index 89d8bcf..8c399d7 100644
|
||||
--- a/find/parser.c
|
||||
+++ b/find/parser.c
|
||||
@@ -2723,7 +2723,7 @@ insert_type (char **argv, int *arg_ptr,
|
||||
const struct parser_table *entry,
|
||||
PRED_FUNC which_pred)
|
||||
{
|
||||
- mode_t type_cell;
|
||||
+ mode_t type_cell /* to silence GCC warning */ = 0;
|
||||
struct predicate *our_pred;
|
||||
float rate = 0.5;
|
||||
const char *typeletter;
|
||||
--
|
||||
1.9.3
|
||||
|
||||
@ -1,185 +0,0 @@
|
||||
From 3e5e311d23ac0a5bd5930ddb4094f7555b886329 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Sat, 19 Dec 2015 22:56:40 +0100
|
||||
Subject: [PATCH 1/2] Revert "Don't include dblocation.texi from original spot,
|
||||
symlink it."
|
||||
|
||||
This reverts commit f59d88e456553dfe0b5185caf75e4041285fd595.
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
doc/Makefile.am | 8 +-------
|
||||
doc/find.texi | 2 +-
|
||||
3 files changed, 3 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 7962719..ce0e768 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -70,7 +70,7 @@ AC_PROG_CPP
|
||||
|
||||
dnl for gnulib
|
||||
gl_EARLY
|
||||
-AC_PROG_LN_S
|
||||
+
|
||||
AC_PROG_INSTALL
|
||||
AC_CHECK_TOOLS([AR], [ar])
|
||||
AC_CHECK_TOOLS([RANLIB], [ranlib], [:])
|
||||
diff --git a/doc/Makefile.am b/doc/Makefile.am
|
||||
index f6f7443..6fbf57b 100644
|
||||
--- a/doc/Makefile.am
|
||||
+++ b/doc/Makefile.am
|
||||
@@ -16,11 +16,9 @@ AM_CFLAGS = $(WARN_CFLAGS)
|
||||
|
||||
info_TEXINFOS = find.texi find-maint.texi
|
||||
find_TEXINFOS = perm.texi parse-datetime.texi regexprops.texi fdl.texi
|
||||
-BUILT_SOURCES = dblocation.texi
|
||||
-nodist_find_TEXINFOS = dblocation.texi
|
||||
find_maint_TEXINFOS = fdl.texi
|
||||
MOSTLYCLEANFILES = find.cps
|
||||
-CLEANFILES = find.txt find_mono.html findutils.texi_html_node.tar.gz dblocation.texi
|
||||
+CLEANFILES = find.txt find_mono.html findutils.texi_html_node.tar.gz
|
||||
|
||||
MAKEINFOTXT = $(MAKEINFO) --plaintext
|
||||
|
||||
@@ -69,7 +67,3 @@ find_mono.html: find.texi
|
||||
# for "make all" or "make install" (or even "make check").
|
||||
findutils.texi_html_node.tar.gz: find.html
|
||||
tar zcf $@ $<
|
||||
-
|
||||
-
|
||||
-dblocation.texi: ../locate/dblocation.texi
|
||||
- $(LN_S) ../locate/dblocation.texi $@
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index a83a645..c2714dd 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -7,7 +7,7 @@
|
||||
@c %**end of header
|
||||
|
||||
@include version.texi
|
||||
-@include dblocation.texi
|
||||
+@include ../locate/dblocation.texi
|
||||
|
||||
@iftex
|
||||
@finalout
|
||||
--
|
||||
2.5.0
|
||||
|
||||
|
||||
From d5473caa86f689ebcadacc593f5a71781c99e829 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Wed, 11 May 2011 16:46:13 +0200
|
||||
Subject: [PATCH 2/2] findutils-4.4.0-no-locate.patch
|
||||
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
configure.ac | 2 --
|
||||
doc/find.texi | 24 ++++++++----------------
|
||||
3 files changed, 9 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index af82d54..6ad453b 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -9,7 +9,7 @@ DISTCLEANFILES = tool-versions.txt
|
||||
|
||||
|
||||
# "tests" is the gnulib unit test dir.
|
||||
-SUBDIRS = gl tests build-aux lib find xargs locate doc po m4
|
||||
+SUBDIRS = gl tests build-aux lib find xargs doc po m4
|
||||
|
||||
ACLOCAL_AMFLAGS = -I gl/m4 -I m4
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index ce0e768..521e665 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -248,8 +248,6 @@ find/testsuite/Makefile
|
||||
gl/Makefile
|
||||
gl/lib/Makefile
|
||||
lib/Makefile
|
||||
-locate/Makefile
|
||||
-locate/testsuite/Makefile
|
||||
m4/Makefile
|
||||
po/Makefile.in
|
||||
po/Makefile
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index c2714dd..01367a4 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -7,7 +7,6 @@
|
||||
@c %**end of header
|
||||
|
||||
@include version.texi
|
||||
-@include ../locate/dblocation.texi
|
||||
|
||||
@iftex
|
||||
@finalout
|
||||
@@ -571,8 +570,7 @@ the databases are updated, and the directories for which they contain
|
||||
entries.
|
||||
|
||||
Here is how to select which file name databases @code{locate}
|
||||
-searches. The default is system-dependent. At the time this document
|
||||
-was generated, the default was @file{@value{LOCATE_DB}}.
|
||||
+searches. The default is system-dependent.
|
||||
|
||||
@table @code
|
||||
@item --database=@var{path}
|
||||
@@ -2892,13 +2890,9 @@ thrashing the network.
|
||||
directories are indexed by each database file.
|
||||
|
||||
The default location for the locate database depends on how findutils
|
||||
-is built, but the findutils installation accompanying this manual uses
|
||||
-the default location @file{@value{LOCATE_DB}}.
|
||||
-
|
||||
-If no database exists at @file{@value{LOCATE_DB}} but the user did not
|
||||
-specify where to look (by using @samp{-d} or setting
|
||||
-@code{LOCATE_PATH}), then @code{locate} will also check for a
|
||||
-``secure'' database in @file{/var/lib/slocate/slocate.db}.
|
||||
+is built. If user did not specify where to look (by using @samp{-d}
|
||||
+or setting @code{LOCATE_PATH}), then @code{locate} will also check for
|
||||
+a ``secure'' database in @file{/var/lib/slocate/slocate.db}.
|
||||
|
||||
@node Database Formats
|
||||
@section Database Formats
|
||||
@@ -3438,8 +3432,7 @@ present.
|
||||
|
||||
@item --database=@var{path}
|
||||
@itemx -d @var{path}
|
||||
-Instead of searching the default @code{locate} database
|
||||
-@file{@value{LOCATE_DB}}, @code{locate} searches the file
|
||||
+@code{locate} searches the file
|
||||
name databases in @var{path}, which is a colon-separated list of
|
||||
database file names. You can also use the environment variable
|
||||
@code{LOCATE_PATH} to set the list of database files to search. The
|
||||
@@ -3614,8 +3607,7 @@ The environment variable @code{PRUNEFS} also sets this value. Default
|
||||
is @file{nfs NFS proc}.
|
||||
|
||||
@item --output=@var{dbfile}
|
||||
-The database file to build. The default is system-dependent, but
|
||||
-when this document was formatted it was @file{@value{LOCATE_DB}}.
|
||||
+The database file to build.
|
||||
|
||||
@item --localuser=@var{user}
|
||||
The user to search the non-network directories as, using @code{su}.
|
||||
@@ -5635,7 +5627,7 @@ why @code{xargs} is confused by your operating system).
|
||||
@section Error Messages From @code{locate}
|
||||
|
||||
@table @samp
|
||||
-@item warning: database @file{@value{LOCATE_DB}} is more than 8 days old
|
||||
+@item warning: database @file{LOCATE_DB} is more than 8 days old
|
||||
The @code{locate} program relies on a database which is periodically
|
||||
built by the @code{updatedb} program. That hasn't happened in a long
|
||||
time. To fix this problem, run @code{updatedb} manually. This can
|
||||
@@ -5643,7 +5635,7 @@ often happen on systems that are generally not left on, so the
|
||||
periodic ``cron'' task which normally does this doesn't get a chance
|
||||
to run.
|
||||
|
||||
-@item locate database @file{@value{LOCATE_DB}} is corrupt or invalid
|
||||
+@item locate database @file{LOCATE_DB} is corrupt or invalid
|
||||
This should not happen. Re-run @code{updatedb}. If that works, but
|
||||
@code{locate} still produces this error, run @code{locate --version}
|
||||
and @code{updatedb --version}. These should produce the same output.
|
||||
--
|
||||
2.5.0
|
||||
|
||||
@ -1,226 +0,0 @@
|
||||
From 443166adaf1c8b91e16a716f3b13f47493b895cc Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 31 May 2016 10:38:52 +0200
|
||||
Subject: [PATCH] Fix bug #48030: find: -exec + does not pass all arguments in
|
||||
certain cases
|
||||
|
||||
When the -exec arguments buffer (usually 128k) is full and the given
|
||||
command has been executed with all that arguments, find(1) missed to
|
||||
execute the command yet another time if only 1 another file would have
|
||||
to be processed.
|
||||
Both find(1), i.e., nowadays FTS-version, and oldfind are affected.
|
||||
This bug was present since the implementation of '-exec +' in 2005,
|
||||
see commit FINDUTILS_4_2_11-1-25-gf0a6ac6.
|
||||
|
||||
* lib/buildcmd.c (bc_push_arg): Move the assignment to set 'state->todo'
|
||||
to 1 down after the immediate execution which resets that flag.
|
||||
* find/testsuite/sv-48030-exec-plus-bug.sh: Add a test.
|
||||
* find/testsuite/Makefile.am (test_shell_progs): Reference the test.
|
||||
* NEWS (Bug Fixes): Mention the fix.
|
||||
|
||||
Reported by Joe Philip Ninan <indiajoe@gmail.com> in
|
||||
https://savannah.gnu.org/bugs/?48030
|
||||
|
||||
Upstream-commit: 8cdc9767e305c9566f537af9d1acf71d1bc6ee8e
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
find/testsuite/Makefile.am | 3 +-
|
||||
find/testsuite/sv-48030-exec-plus-bug.sh | 143 +++++++++++++++++++++++++++++++
|
||||
lib/buildcmd.c | 10 +--
|
||||
3 files changed, 150 insertions(+), 6 deletions(-)
|
||||
create mode 100644 find/testsuite/sv-48030-exec-plus-bug.sh
|
||||
|
||||
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
|
||||
index c1369c3..ab5dbe8 100644
|
||||
--- a/find/testsuite/Makefile.am
|
||||
+++ b/find/testsuite/Makefile.am
|
||||
@@ -258,7 +258,8 @@ test_escapechars.sh \
|
||||
test_escape_c.sh \
|
||||
test_inode.sh \
|
||||
sv-34079.sh \
|
||||
-sv-34976-execdir-fd-leak.sh
|
||||
+sv-34976-execdir-fd-leak.sh \
|
||||
+sv-48030-exec-plus-bug.sh
|
||||
|
||||
EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
|
||||
$(test_shell_progs) binary_locations.sh checklists.py
|
||||
diff --git a/find/testsuite/sv-48030-exec-plus-bug.sh b/find/testsuite/sv-48030-exec-plus-bug.sh
|
||||
new file mode 100755
|
||||
index 0000000..4dbf149
|
||||
--- /dev/null
|
||||
+++ b/find/testsuite/sv-48030-exec-plus-bug.sh
|
||||
@@ -0,0 +1,143 @@
|
||||
+#! /bin/sh
|
||||
+# Copyright (C) 2016 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
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+
|
||||
+# This test verifies that find invokes the given command for the
|
||||
+# multiple-argument sytax '-exec CMD {} +'. Between FINDUTILS-4.2.12
|
||||
+# and v4.6.0, find(1) would have failed to execute CMD another time
|
||||
+# if there was only one last single file argument.
|
||||
+
|
||||
+testname="$(basename $0)"
|
||||
+
|
||||
+. "${srcdir}"/binary_locations.sh
|
||||
+
|
||||
+die() {
|
||||
+ echo "$@" >&2
|
||||
+ exit 1
|
||||
+}
|
||||
+
|
||||
+# This is used to simplify checking of the return value
|
||||
+# which is useful when ensuring a command fails as desired.
|
||||
+# I.e., just doing `command ... &&fail=1` will not catch
|
||||
+# a segfault in command for example. With this helper you
|
||||
+# instead check an explicit exit code like
|
||||
+# returns_ 1 command ... || fail
|
||||
+returns_ () {
|
||||
+ # Disable tracing so it doesn't interfere with stderr of the wrapped command
|
||||
+ { set +x; } 2>/dev/null
|
||||
+
|
||||
+ local exp_exit="$1"
|
||||
+ shift
|
||||
+ "$@"
|
||||
+ test $? -eq $exp_exit && ret_=0 || ret_=1
|
||||
+
|
||||
+ set -x
|
||||
+ { return $ret_; } 2>/dev/null
|
||||
+}
|
||||
+
|
||||
+# Define the nicest compare available (borrowed from gnulib).
|
||||
+if diff_out_=`exec 2>/dev/null; diff -u "$0" "$0" < /dev/null` \
|
||||
+ && diff -u Makefile "$0" 2>/dev/null | grep '^[+]#!' >/dev/null; then
|
||||
+ # diff accepts the -u option and does not (like AIX 7 'diff') produce an
|
||||
+ # extra space on column 1 of every content line.
|
||||
+ if test -z "$diff_out_"; then
|
||||
+ compare () { diff -u "$@"; }
|
||||
+ else
|
||||
+ compare ()
|
||||
+ {
|
||||
+ if diff -u "$@" > diff.out; then
|
||||
+ # No differences were found, but Solaris 'diff' produces output
|
||||
+ # "No differences encountered". Hide this output.
|
||||
+ rm -f diff.out
|
||||
+ true
|
||||
+ else
|
||||
+ cat diff.out
|
||||
+ rm -f diff.out
|
||||
+ false
|
||||
+ fi
|
||||
+ }
|
||||
+ fi
|
||||
+elif diff_out_=`exec 2>/dev/null; diff -c "$0" "$0" < /dev/null`; then
|
||||
+ if test -z "$diff_out_"; then
|
||||
+ compare () { diff -c "$@"; }
|
||||
+ else
|
||||
+ compare ()
|
||||
+ {
|
||||
+ if diff -c "$@" > diff.out; then
|
||||
+ # No differences were found, but AIX and HP-UX 'diff' produce output
|
||||
+ # "No differences encountered" or "There are no differences between the
|
||||
+ # files.". Hide this output.
|
||||
+ rm -f diff.out
|
||||
+ true
|
||||
+ else
|
||||
+ cat diff.out
|
||||
+ rm -f diff.out
|
||||
+ false
|
||||
+ fi
|
||||
+ }
|
||||
+ fi
|
||||
+elif cmp -s /dev/null /dev/null 2>/dev/null; then
|
||||
+ compare () { cmp -s "$@"; }
|
||||
+else
|
||||
+ compare () { cmp "$@"; }
|
||||
+fi
|
||||
+
|
||||
+DIR='RashuBug'
|
||||
+# Name of the CMD to execute: the file name must be 6 characters long
|
||||
+# (to trigger the bug in combination with the test files).
|
||||
+CMD='tstcmd'
|
||||
+
|
||||
+# Create test files.
|
||||
+make_test_data() {
|
||||
+ # Create the CMD script and check that it works.
|
||||
+ mkdir "$DIR" 'bin' \
|
||||
+ && echo 'printf "%s\n" "$@"' > "bin/$CMD" \
|
||||
+ && chmod +x "bin/$CMD" \
|
||||
+ && PATH="$PWD/bin:$PATH" \
|
||||
+ && [ $( "${ftsfind}" bin -maxdepth 0 -exec "$CMD" '{}' + ) = 'bin' ] \
|
||||
+ || return 1
|
||||
+
|
||||
+ # Create expected output file - also used for creating the test data.
|
||||
+ { seq -f "${DIR}/abcdefghijklmnopqrstuv%04g" 901 &&
|
||||
+ seq -f "${DIR}/abcdefghijklmnopqrstu%04g" 902 3719
|
||||
+ } > exp2 \
|
||||
+ && LC_ALL=C sort exp2 > exp \
|
||||
+ && rm exp2 \
|
||||
+ || return 1
|
||||
+
|
||||
+ # Create test files, and check if test data has been created correctly.
|
||||
+ xargs touch < exp \
|
||||
+ && [ -f "${DIR}/abcdefghijklmnopqrstu3719" ] \
|
||||
+ && [ 3719 = $( "${ftsfind}" "$DIR" -type f | wc -l ) ] \
|
||||
+ || return 1
|
||||
+}
|
||||
+
|
||||
+set -x
|
||||
+tmpdir="$(mktemp -d)" \
|
||||
+ && cd "$tmpdir" \
|
||||
+ && make_test_data "${tmpdir}" \
|
||||
+ || die "FAIL: failed to set up the test in ${tmpdir}"
|
||||
+
|
||||
+fail=0
|
||||
+for exe in "${ftsfind}" "${oldfind}"; do
|
||||
+ "$exe" "$DIR" -type f -exec "$CMD" '{}' + > out || fail=1
|
||||
+ LC_ALL=C sort out > out2 || fail=1
|
||||
+ compare exp out2 || fail=1
|
||||
+done
|
||||
+
|
||||
+cd ..
|
||||
+rm -rf "${tmpdir}" || exit 1
|
||||
+exit $fail
|
||||
diff --git a/lib/buildcmd.c b/lib/buildcmd.c
|
||||
index a58f67e..27e9ce5 100644
|
||||
--- a/lib/buildcmd.c
|
||||
+++ b/lib/buildcmd.c
|
||||
@@ -356,11 +356,6 @@ bc_push_arg (struct buildcmd_control *ctl,
|
||||
|
||||
assert (arg != NULL);
|
||||
|
||||
- if (!initial_args)
|
||||
- {
|
||||
- state->todo = 1;
|
||||
- }
|
||||
-
|
||||
if (!terminate)
|
||||
{
|
||||
if (state->cmd_argv_chars + len + pfxlen > ctl->arg_max)
|
||||
@@ -380,6 +375,11 @@ bc_push_arg (struct buildcmd_control *ctl,
|
||||
bc_do_exec (ctl, state);
|
||||
}
|
||||
|
||||
+ if (!initial_args)
|
||||
+ {
|
||||
+ state->todo = 1;
|
||||
+ }
|
||||
+
|
||||
if (state->cmd_argc >= state->cmd_argv_alloc)
|
||||
{
|
||||
/* XXX: we could use extendbuf() here. */
|
||||
--
|
||||
2.5.5
|
||||
|
||||
@ -1,990 +0,0 @@
|
||||
From f3337786e55909538aacfd7c29b1cf58ff444fbf Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Mon, 12 Feb 2018 12:45:36 +0100
|
||||
Subject: [PATCH 1/4] import gnulib's FTS module from upstream commit 281b825e
|
||||
|
||||
---
|
||||
gl/lib/fts.c | 424 +++++++++++++++++++++++++++++-----------------------------
|
||||
gl/lib/fts_.h | 10 +-
|
||||
2 files changed, 221 insertions(+), 213 deletions(-)
|
||||
|
||||
diff --git a/gl/lib/fts.c b/gl/lib/fts.c
|
||||
index c91d7a1..bfa73e3 100644
|
||||
--- a/gl/lib/fts.c
|
||||
+++ b/gl/lib/fts.c
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Traverse a file hierarchy.
|
||||
|
||||
- Copyright (C) 2004-2015 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2004-2018 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
|
||||
@@ -13,7 +13,7 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993, 1994
|
||||
@@ -46,9 +46,9 @@
|
||||
|
||||
#include <config.h>
|
||||
|
||||
-#if defined(LIBC_SCCS) && !defined(lint)
|
||||
+#if defined LIBC_SCCS && !defined GCC_LINT && !defined lint
|
||||
static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||
-#endif /* LIBC_SCCS and not lint */
|
||||
+#endif
|
||||
|
||||
#include "fts_.h"
|
||||
|
||||
@@ -71,11 +71,7 @@ static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||
|
||||
#if ! _LIBC
|
||||
# include "fcntl--.h"
|
||||
-# include "dirent--.h"
|
||||
-# include "unistd--.h"
|
||||
-/* FIXME - use fcntl(F_DUPFD_CLOEXEC)/openat(O_CLOEXEC) once they are
|
||||
- supported. */
|
||||
-# include "cloexec.h"
|
||||
+# include "flexmember.h"
|
||||
# include "openat.h"
|
||||
# include "same-inode.h"
|
||||
#endif
|
||||
@@ -202,6 +198,14 @@ enum Fts_stat
|
||||
while (false)
|
||||
#endif
|
||||
|
||||
+#ifndef FALLTHROUGH
|
||||
+# if __GNUC__ < 7
|
||||
+# define FALLTHROUGH ((void) 0)
|
||||
+# else
|
||||
+# define FALLTHROUGH __attribute__ ((__fallthrough__))
|
||||
+# endif
|
||||
+#endif
|
||||
+
|
||||
static FTSENT *fts_alloc (FTS *, const char *, size_t) internal_function;
|
||||
static FTSENT *fts_build (FTS *, int) internal_function;
|
||||
static void fts_lfree (FTSENT *) internal_function;
|
||||
@@ -296,14 +300,13 @@ static DIR *
|
||||
internal_function
|
||||
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
|
||||
- | extra_flags));
|
||||
+ int open_flags = (O_RDONLY | O_CLOEXEC | O_DIRECTORY | O_NOCTTY
|
||||
+ | O_NONBLOCK | extra_flags);
|
||||
+ int new_fd = openat (fd, dir, open_flags);
|
||||
DIR *dirp;
|
||||
|
||||
if (new_fd < 0)
|
||||
return NULL;
|
||||
- set_cloexec_flag (new_fd, true);
|
||||
dirp = fdopendir (new_fd);
|
||||
if (dirp)
|
||||
*pdir_fd = new_fd;
|
||||
@@ -366,15 +369,13 @@ static int
|
||||
internal_function
|
||||
diropen (FTS const *sp, char const *dir)
|
||||
{
|
||||
- int open_flags = (O_SEARCH | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
|
||||
+ int open_flags = (O_SEARCH | O_CLOEXEC | O_DIRECTORY | O_NOCTTY | O_NONBLOCK
|
||||
| (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)
|
||||
: open (dir, open_flags));
|
||||
- if (0 <= fd)
|
||||
- set_cloexec_flag (fd, true);
|
||||
return fd;
|
||||
}
|
||||
|
||||
@@ -470,6 +471,7 @@ fts_open (char * const *argv,
|
||||
if ((parent = fts_alloc(sp, "", 0)) == NULL)
|
||||
goto mem2;
|
||||
parent->fts_level = FTS_ROOTPARENTLEVEL;
|
||||
+ parent->fts_n_dirs_remaining = -1;
|
||||
}
|
||||
|
||||
/* The classic fts implementation would call fts_stat with
|
||||
@@ -656,39 +658,139 @@ fts_close (FTS *sp)
|
||||
return (0);
|
||||
}
|
||||
|
||||
+/* Minimum link count of a traditional Unix directory. When leaf
|
||||
+ optimization is OK and MIN_DIR_NLINK <= st_nlink, then st_nlink is
|
||||
+ an upper bound on the number of subdirectories (counting "." and
|
||||
+ ".."). */
|
||||
+enum { MIN_DIR_NLINK = 2 };
|
||||
+
|
||||
+/* Whether leaf optimization is OK for a directory. */
|
||||
+enum leaf_optimization
|
||||
+ {
|
||||
+ /* st_nlink is not reliable for this directory's subdirectories. */
|
||||
+ NO_LEAF_OPTIMIZATION,
|
||||
+
|
||||
+ /* Leaf optimization is OK, but is not useful for avoiding stat calls. */
|
||||
+ OK_LEAF_OPTIMIZATION,
|
||||
+
|
||||
+ /* Leaf optimization is not only OK: it is useful for avoiding
|
||||
+ stat calls, because dirent.d_type does not work. */
|
||||
+ NOSTAT_LEAF_OPTIMIZATION
|
||||
+ };
|
||||
+
|
||||
#if defined __linux__ \
|
||||
&& HAVE_SYS_VFS_H && HAVE_FSTATFS && HAVE_STRUCT_STATFS_F_TYPE
|
||||
|
||||
# include <sys/vfs.h>
|
||||
|
||||
/* Linux-specific constants from coreutils' src/fs.h */
|
||||
-# define S_MAGIC_TMPFS 0x1021994
|
||||
+# define S_MAGIC_AFS 0x5346414F
|
||||
# define S_MAGIC_NFS 0x6969
|
||||
+# define S_MAGIC_PROC 0x9FA0
|
||||
# define S_MAGIC_REISERFS 0x52654973
|
||||
+# define S_MAGIC_TMPFS 0x1021994
|
||||
# define S_MAGIC_XFS 0x58465342
|
||||
-# define S_MAGIC_PROC 0x9FA0
|
||||
|
||||
-/* Return false if it is easy to determine the file system type of
|
||||
- the directory on which DIR_FD is open, and sorting dirents on
|
||||
- inode numbers is known not to improve traversal performance with
|
||||
- that type of file system. Otherwise, return true. */
|
||||
+# ifdef HAVE___FSWORD_T
|
||||
+typedef __fsword_t fsword;
|
||||
+# else
|
||||
+typedef long int fsword;
|
||||
+# endif
|
||||
+
|
||||
+/* Map a stat.st_dev number to a file system type number f_ftype. */
|
||||
+struct dev_type
|
||||
+{
|
||||
+ dev_t st_dev;
|
||||
+ fsword f_type;
|
||||
+};
|
||||
+
|
||||
+/* Use a tiny initial size. If a traversal encounters more than
|
||||
+ a few devices, the cost of growing/rehashing this table will be
|
||||
+ rendered negligible by the number of inodes processed. */
|
||||
+enum { DEV_TYPE_HT_INITIAL_SIZE = 13 };
|
||||
+
|
||||
+static size_t
|
||||
+dev_type_hash (void const *x, size_t table_size)
|
||||
+{
|
||||
+ struct dev_type const *ax = x;
|
||||
+ uintmax_t dev = ax->st_dev;
|
||||
+ return dev % table_size;
|
||||
+}
|
||||
+
|
||||
static bool
|
||||
-dirent_inode_sort_may_be_useful (int dir_fd)
|
||||
+dev_type_compare (void const *x, void const *y)
|
||||
+{
|
||||
+ struct dev_type const *ax = x;
|
||||
+ struct dev_type const *ay = y;
|
||||
+ return ax->st_dev == ay->st_dev;
|
||||
+}
|
||||
+
|
||||
+/* Return the file system type of P, or 0 if not known.
|
||||
+ Try to cache known values. */
|
||||
+
|
||||
+static fsword
|
||||
+filesystem_type (FTSENT const *p)
|
||||
+{
|
||||
+ FTS *sp = p->fts_fts;
|
||||
+ Hash_table *h = sp->fts_leaf_optimization_works_ht;
|
||||
+ struct dev_type *ent;
|
||||
+ struct statfs fs_buf;
|
||||
+
|
||||
+ /* 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))
|
||||
+ return 0;
|
||||
+
|
||||
+ if (! h)
|
||||
+ h = sp->fts_leaf_optimization_works_ht
|
||||
+ = hash_initialize (DEV_TYPE_HT_INITIAL_SIZE, NULL, dev_type_hash,
|
||||
+ dev_type_compare, free);
|
||||
+ if (h)
|
||||
+ {
|
||||
+ struct dev_type tmp;
|
||||
+ tmp.st_dev = p->fts_statp->st_dev;
|
||||
+ ent = hash_lookup (h, &tmp);
|
||||
+ if (ent)
|
||||
+ return ent->f_type;
|
||||
+ }
|
||||
+
|
||||
+ /* Look-up failed. Query directly and cache the result. */
|
||||
+ if (fstatfs (p->fts_fts->fts_cwd_fd, &fs_buf) != 0)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (h)
|
||||
+ {
|
||||
+ struct dev_type *t2 = malloc (sizeof *t2);
|
||||
+ if (t2)
|
||||
+ {
|
||||
+ t2->st_dev = p->fts_statp->st_dev;
|
||||
+ t2->f_type = fs_buf.f_type;
|
||||
+
|
||||
+ ent = hash_insert (h, t2);
|
||||
+ if (ent)
|
||||
+ fts_assert (ent == t2);
|
||||
+ else
|
||||
+ free (t2);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return fs_buf.f_type;
|
||||
+}
|
||||
+
|
||||
+/* Return false if it is easy to determine the file system type of the
|
||||
+ directory P, and sorting dirents on inode numbers is known not to
|
||||
+ improve traversal performance with that type of file system.
|
||||
+ Otherwise, return true. */
|
||||
+static bool
|
||||
+dirent_inode_sort_may_be_useful (FTSENT const *p)
|
||||
{
|
||||
/* Skip the sort only if we can determine efficiently
|
||||
that skipping it is the right thing to do.
|
||||
The cost of performing an unnecessary sort is negligible,
|
||||
while the cost of *not* performing it can be O(N^2) with
|
||||
a very large constant. */
|
||||
- struct statfs fs_buf;
|
||||
-
|
||||
- /* If fstatfs fails, assume sorting would be useful. */
|
||||
- if (fstatfs (dir_fd, &fs_buf) != 0)
|
||||
- return true;
|
||||
|
||||
- /* FIXME: what about when f_type is not an integral type?
|
||||
- deal with that if/when it's encountered. */
|
||||
- switch (fs_buf.f_type)
|
||||
+ switch (filesystem_type (p))
|
||||
{
|
||||
case S_MAGIC_TMPFS:
|
||||
case S_MAGIC_NFS:
|
||||
@@ -701,133 +803,58 @@ dirent_inode_sort_may_be_useful (int dir_fd)
|
||||
}
|
||||
}
|
||||
|
||||
-/* Given a file descriptor DIR_FD open on a directory D,
|
||||
- return true if it is valid to apply the leaf-optimization
|
||||
- technique of counting directories in D via stat.st_nlink. */
|
||||
-static bool
|
||||
-leaf_optimization_applies (int dir_fd)
|
||||
+/* Given an FTS entry P for a directory D,
|
||||
+ return true if it is both useful and valid to apply leaf optimization.
|
||||
+ The optimization is useful only for file systems that lack usable
|
||||
+ dirent.d_type info. The optimization is valid if an st_nlink value
|
||||
+ of at least MIN_DIR_NLINK is an upper bound on the number of
|
||||
+ subdirectories of D, counting "." and ".." as subdirectories. */
|
||||
+static enum leaf_optimization
|
||||
+leaf_optimization (FTSENT const *p)
|
||||
{
|
||||
- struct statfs fs_buf;
|
||||
-
|
||||
- /* If fstatfs fails, assume we can't use the optimization. */
|
||||
- if (fstatfs (dir_fd, &fs_buf) != 0)
|
||||
- return false;
|
||||
-
|
||||
- /* FIXME: do we need to detect AFS mount points? I doubt it,
|
||||
- unless fstatfs can report S_MAGIC_REISERFS for such a directory. */
|
||||
-
|
||||
- switch (fs_buf.f_type)
|
||||
+ switch (filesystem_type (p))
|
||||
{
|
||||
- case S_MAGIC_NFS:
|
||||
- /* NFS provides usable dirent.d_type but not necessarily for all entries
|
||||
- of large directories. See <https://bugzilla.redhat.com/1252549>. */
|
||||
- return true;
|
||||
-
|
||||
- /* List here the file system types that lack usable dirent.d_type
|
||||
+ /* List here the file system types that may lack usable dirent.d_type
|
||||
info, yet for which the optimization does apply. */
|
||||
case S_MAGIC_REISERFS:
|
||||
- case S_MAGIC_XFS:
|
||||
- return true;
|
||||
-
|
||||
+ case S_MAGIC_XFS: /* XFS lacked it until 2013-08-22 commit. */
|
||||
+ return NOSTAT_LEAF_OPTIMIZATION;
|
||||
+
|
||||
+ case 0:
|
||||
+ /* Leaf optimization is unsafe if the file system type is unknown. */
|
||||
+ FALLTHROUGH;
|
||||
+ case S_MAGIC_AFS:
|
||||
+ /* Although AFS mount points are not counted in st_nlink, they
|
||||
+ act like directories. See <https://bugs.debian.org/143111>. */
|
||||
+ FALLTHROUGH;
|
||||
+ case S_MAGIC_NFS:
|
||||
+ /* NFS provides usable dirent.d_type but not necessarily for all entries
|
||||
+ of large directories, so as per <https://bugzilla.redhat.com/1252549>
|
||||
+ NFS should return true. However st_nlink values are not accurate on
|
||||
+ all implementations as per <https://bugzilla.redhat.com/1299169>. */
|
||||
+ FALLTHROUGH;
|
||||
case S_MAGIC_PROC:
|
||||
- /* Explicitly listing this or any other file system type for which
|
||||
- the optimization is not applicable is not necessary, but we leave
|
||||
- it here to document the risk. Per http://bugs.debian.org/143111,
|
||||
- /proc may have bogus stat.st_nlink values. */
|
||||
- /* fall through */
|
||||
+ /* Per <https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=143111> /proc
|
||||
+ may have bogus stat.st_nlink values. */
|
||||
+ return NO_LEAF_OPTIMIZATION;
|
||||
+
|
||||
default:
|
||||
- return false;
|
||||
+ return OK_LEAF_OPTIMIZATION;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
static bool
|
||||
-dirent_inode_sort_may_be_useful (int dir_fd _GL_UNUSED) { return true; }
|
||||
-static bool
|
||||
-leaf_optimization_applies (int dir_fd _GL_UNUSED) { return false; }
|
||||
-#endif
|
||||
-
|
||||
-/* link-count-optimization entry:
|
||||
- map a stat.st_dev number to a boolean: leaf_optimization_works */
|
||||
-struct LCO_ent
|
||||
-{
|
||||
- dev_t st_dev;
|
||||
- bool opt_ok;
|
||||
-};
|
||||
-
|
||||
-/* Use a tiny initial size. If a traversal encounters more than
|
||||
- a few devices, the cost of growing/rehashing this table will be
|
||||
- rendered negligible by the number of inodes processed. */
|
||||
-enum { LCO_HT_INITIAL_SIZE = 13 };
|
||||
-
|
||||
-static size_t
|
||||
-LCO_hash (void const *x, size_t table_size)
|
||||
-{
|
||||
- struct LCO_ent const *ax = x;
|
||||
- return (uintmax_t) ax->st_dev % table_size;
|
||||
-}
|
||||
-
|
||||
-static bool
|
||||
-LCO_compare (void const *x, void const *y)
|
||||
+dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED)
|
||||
{
|
||||
- struct LCO_ent const *ax = x;
|
||||
- struct LCO_ent const *ay = y;
|
||||
- return ax->st_dev == ay->st_dev;
|
||||
+ return true;
|
||||
}
|
||||
-
|
||||
-/* Ask the same question as leaf_optimization_applies, but query
|
||||
- the cache first (FTS.fts_leaf_optimization_works_ht), and if necessary,
|
||||
- update that cache. */
|
||||
-static bool
|
||||
-link_count_optimize_ok (FTSENT const *p)
|
||||
+static enum leaf_optimization
|
||||
+leaf_optimization (FTSENT const *p _GL_UNUSED)
|
||||
{
|
||||
- FTS *sp = p->fts_fts;
|
||||
- Hash_table *h = sp->fts_leaf_optimization_works_ht;
|
||||
- struct LCO_ent tmp;
|
||||
- struct LCO_ent *ent;
|
||||
- bool opt_ok;
|
||||
- struct LCO_ent *t2;
|
||||
-
|
||||
- /* 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))
|
||||
- return false;
|
||||
-
|
||||
- /* map st_dev to the boolean, leaf_optimization_works */
|
||||
- if (h == NULL)
|
||||
- {
|
||||
- h = sp->fts_leaf_optimization_works_ht
|
||||
- = hash_initialize (LCO_HT_INITIAL_SIZE, NULL, LCO_hash,
|
||||
- LCO_compare, free);
|
||||
- if (h == NULL)
|
||||
- return false;
|
||||
- }
|
||||
- tmp.st_dev = p->fts_statp->st_dev;
|
||||
- ent = hash_lookup (h, &tmp);
|
||||
- if (ent)
|
||||
- return ent->opt_ok;
|
||||
-
|
||||
- /* Look-up failed. Query directly and cache the result. */
|
||||
- t2 = malloc (sizeof *t2);
|
||||
- if (t2 == NULL)
|
||||
- return false;
|
||||
-
|
||||
- /* Is it ok to perform the optimization in the dir, FTS_CWD_FD? */
|
||||
- opt_ok = leaf_optimization_applies (sp->fts_cwd_fd);
|
||||
- t2->opt_ok = opt_ok;
|
||||
- t2->st_dev = p->fts_statp->st_dev;
|
||||
-
|
||||
- ent = hash_insert (h, t2);
|
||||
- if (ent == NULL)
|
||||
- {
|
||||
- /* insertion failed */
|
||||
- free (t2);
|
||||
- return false;
|
||||
- }
|
||||
- fts_assert (ent == t2);
|
||||
-
|
||||
- return opt_ok;
|
||||
+ return NO_LEAF_OPTIMIZATION;
|
||||
}
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Special case of "/" at the end of the file name so that slashes aren't
|
||||
@@ -1014,13 +1041,11 @@ check_for_dir:
|
||||
if (p->fts_statp->st_size == FTS_STAT_REQUIRED)
|
||||
{
|
||||
FTSENT *parent = p->fts_parent;
|
||||
- if (FTS_ROOTLEVEL < p->fts_level
|
||||
- /* ->fts_n_dirs_remaining is not valid
|
||||
- for command-line-specified names. */
|
||||
- && parent->fts_n_dirs_remaining == 0
|
||||
+ if (parent->fts_n_dirs_remaining == 0
|
||||
&& ISSET(FTS_NOSTAT)
|
||||
&& ISSET(FTS_PHYSICAL)
|
||||
- && link_count_optimize_ok (parent))
|
||||
+ && (leaf_optimization (parent)
|
||||
+ == NOSTAT_LEAF_OPTIMIZATION))
|
||||
{
|
||||
/* nothing more needed */
|
||||
}
|
||||
@@ -1029,7 +1054,8 @@ check_for_dir:
|
||||
p->fts_info = fts_stat(sp, p, false);
|
||||
if (S_ISDIR(p->fts_statp->st_mode)
|
||||
&& p->fts_level != FTS_ROOTLEVEL
|
||||
- && parent->fts_n_dirs_remaining)
|
||||
+ && 0 < parent->fts_n_dirs_remaining
|
||||
+ && parent->fts_n_dirs_remaining != (nlink_t) -1)
|
||||
parent->fts_n_dirs_remaining--;
|
||||
}
|
||||
}
|
||||
@@ -1298,8 +1324,6 @@ fts_build (register FTS *sp, int type)
|
||||
bool descend;
|
||||
bool doadjust;
|
||||
ptrdiff_t level;
|
||||
- nlink_t nlinks;
|
||||
- bool nostat;
|
||||
size_t len, maxlen, new_len;
|
||||
char *cp;
|
||||
int dir_fd;
|
||||
@@ -1369,24 +1393,6 @@ fts_build (register FTS *sp, int type)
|
||||
sorting, yet not so large that we risk exhausting memory. */
|
||||
max_entries = sp->fts_compar ? SIZE_MAX : FTS_MAX_READDIR_ENTRIES;
|
||||
|
||||
- /*
|
||||
- * Nlinks is the number of possible entries of type directory in the
|
||||
- * directory if we're cheating on stat calls, 0 if we're not doing
|
||||
- * any stat calls at all, (nlink_t) -1 if we're statting everything.
|
||||
- */
|
||||
- if (type == BNAMES) {
|
||||
- nlinks = 0;
|
||||
- /* Be quiet about nostat, GCC. */
|
||||
- nostat = false;
|
||||
- } else if (ISSET(FTS_NOSTAT) && ISSET(FTS_PHYSICAL)) {
|
||||
- nlinks = (cur->fts_statp->st_nlink
|
||||
- - (ISSET(FTS_SEEDOT) ? 0 : 2));
|
||||
- nostat = true;
|
||||
- } else {
|
||||
- nlinks = -1;
|
||||
- nostat = false;
|
||||
- }
|
||||
-
|
||||
/*
|
||||
* If we're going to need to stat anything or we want to descend
|
||||
* and stay in the directory, chdir. If this fails we keep going,
|
||||
@@ -1408,15 +1414,22 @@ fts_build (register FTS *sp, int type)
|
||||
the required dirp and dir_fd. */
|
||||
descend = true;
|
||||
}
|
||||
- else if (nlinks || type == BREAD) {
|
||||
+ else
|
||||
+ {
|
||||
+ /* Try to descend unless it is a names-only fts_children,
|
||||
+ or the directory is known to lack subdirectories. */
|
||||
+ descend = (type != BNAMES
|
||||
+ && ! (ISSET (FTS_NOSTAT) && ISSET (FTS_PHYSICAL)
|
||||
+ && ! ISSET (FTS_SEEDOT)
|
||||
+ && cur->fts_statp->st_nlink == MIN_DIR_NLINK
|
||||
+ && (leaf_optimization (cur)
|
||||
+ != NO_LEAF_OPTIMIZATION)));
|
||||
+ if (descend || type == BREAD)
|
||||
+ {
|
||||
if (ISSET(FTS_CWDFD))
|
||||
- {
|
||||
- dir_fd = dup (dir_fd);
|
||||
- if (0 <= dir_fd)
|
||||
- set_cloexec_flag (dir_fd, true);
|
||||
- }
|
||||
+ dir_fd = fcntl (dir_fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
|
||||
if (dir_fd < 0 || fts_safe_changedir(sp, cur, dir_fd, NULL)) {
|
||||
- if (nlinks && type == BREAD)
|
||||
+ if (descend && type == BREAD)
|
||||
cur->fts_errno = errno;
|
||||
cur->fts_flags |= FTS_DONTCHDIR;
|
||||
descend = false;
|
||||
@@ -1426,8 +1439,8 @@ fts_build (register FTS *sp, int type)
|
||||
cur->fts_dirp = NULL;
|
||||
} else
|
||||
descend = true;
|
||||
- } else
|
||||
- descend = false;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/*
|
||||
* Figure out the max file name length that can be stored in the
|
||||
@@ -1458,11 +1471,19 @@ fts_build (register FTS *sp, int type)
|
||||
tail = NULL;
|
||||
nitems = 0;
|
||||
while (cur->fts_dirp) {
|
||||
- bool is_dir;
|
||||
size_t d_namelen;
|
||||
+ __set_errno (0);
|
||||
struct dirent *dp = readdir(cur->fts_dirp);
|
||||
- if (dp == NULL)
|
||||
+ if (dp == NULL) {
|
||||
+ if (errno) {
|
||||
+ cur->fts_errno = errno;
|
||||
+ /* If we've not read any items yet, treat
|
||||
+ the error as if we can't access the dir. */
|
||||
+ cur->fts_info = (continue_readdir || nitems)
|
||||
+ ? FTS_ERR : FTS_DNR;
|
||||
+ }
|
||||
break;
|
||||
+ }
|
||||
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
|
||||
continue;
|
||||
|
||||
@@ -1550,19 +1571,10 @@ mem1: saved_errno = errno;
|
||||
to caller, when possible. */
|
||||
set_stat_type (p->fts_statp, D_TYPE (dp));
|
||||
fts_set_stat_required(p, !skip_stat);
|
||||
- is_dir = (ISSET(FTS_PHYSICAL)
|
||||
- && DT_MUST_BE(dp, DT_DIR));
|
||||
} else {
|
||||
p->fts_info = fts_stat(sp, p, false);
|
||||
- is_dir = (p->fts_info == FTS_D
|
||||
- || p->fts_info == FTS_DC
|
||||
- || p->fts_info == FTS_DOT);
|
||||
}
|
||||
|
||||
- /* Decrement link count if applicable. */
|
||||
- if (nlinks > 0 && is_dir)
|
||||
- nlinks -= nostat;
|
||||
-
|
||||
/* We walk in directory order so "ls -f" doesn't get upset. */
|
||||
p->fts_link = NULL;
|
||||
if (head == NULL)
|
||||
@@ -1621,7 +1633,8 @@ mem1: saved_errno = errno;
|
||||
|
||||
/* If didn't find anything, return NULL. */
|
||||
if (!nitems) {
|
||||
- if (type == BREAD)
|
||||
+ if (type == BREAD
|
||||
+ && cur->fts_info != FTS_DNR && cur->fts_info != FTS_ERR)
|
||||
cur->fts_info = FTS_DP;
|
||||
fts_lfree(head);
|
||||
return (NULL);
|
||||
@@ -1633,8 +1646,7 @@ mem1: saved_errno = errno;
|
||||
inode numbers. */
|
||||
if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
|
||||
&& !sp->fts_compar
|
||||
- && ISSET (FTS_CWDFD)
|
||||
- && dirent_inode_sort_may_be_useful (sp->fts_cwd_fd)) {
|
||||
+ && dirent_inode_sort_may_be_useful (cur)) {
|
||||
sp->fts_compar = fts_compare_ino;
|
||||
head = fts_sort (sp, head, nitems);
|
||||
sp->fts_compar = NULL;
|
||||
@@ -1757,7 +1769,7 @@ fd_ring_check (FTS const *sp)
|
||||
I_ring fd_w = sp->fts_fd_ring;
|
||||
|
||||
int cwd_fd = sp->fts_cwd_fd;
|
||||
- cwd_fd = dup (cwd_fd);
|
||||
+ cwd_fd = fcntl (cwd_fd, F_DUPFD_CLOEXEC, STDERR_FILENO + 1);
|
||||
char *dot = getcwdat (cwd_fd, NULL, 0);
|
||||
error (0, 0, "===== check ===== cwd: %s", dot);
|
||||
free (dot);
|
||||
@@ -1766,7 +1778,8 @@ fd_ring_check (FTS const *sp)
|
||||
int fd = i_ring_pop (&fd_w);
|
||||
if (0 <= fd)
|
||||
{
|
||||
- int parent_fd = openat (cwd_fd, "..", O_SEARCH | O_NOATIME);
|
||||
+ int open_flags = O_SEARCH | O_CLOEXEC | O_NOATIME;
|
||||
+ int parent_fd = openat (cwd_fd, "..", open_flags);
|
||||
if (parent_fd < 0)
|
||||
{
|
||||
// Warn?
|
||||
@@ -1795,7 +1808,6 @@ internal_function
|
||||
fts_stat(FTS *sp, register FTSENT *p, bool follow)
|
||||
{
|
||||
struct stat *sbp = p->fts_statp;
|
||||
- int saved_errno;
|
||||
|
||||
if (p->fts_level == FTS_ROOTLEVEL && ISSET(FTS_COMFOLLOW))
|
||||
follow = true;
|
||||
@@ -1807,13 +1819,12 @@ fts_stat(FTS *sp, register FTSENT *p, bool follow)
|
||||
*/
|
||||
if (ISSET(FTS_LOGICAL) || follow) {
|
||||
if (stat(p->fts_accpath, sbp)) {
|
||||
- saved_errno = errno;
|
||||
if (errno == ENOENT
|
||||
&& lstat(p->fts_accpath, sbp) == 0) {
|
||||
__set_errno (0);
|
||||
return (FTS_SLNONE);
|
||||
}
|
||||
- p->fts_errno = saved_errno;
|
||||
+ p->fts_errno = errno;
|
||||
goto err;
|
||||
}
|
||||
} else if (fstatat(sp->fts_cwd_fd, p->fts_accpath, sbp,
|
||||
@@ -1824,8 +1835,11 @@ err: memset(sbp, 0, sizeof(struct stat));
|
||||
}
|
||||
|
||||
if (S_ISDIR(sbp->st_mode)) {
|
||||
- p->fts_n_dirs_remaining = (sbp->st_nlink
|
||||
- - (ISSET(FTS_SEEDOT) ? 0 : 2));
|
||||
+ p->fts_n_dirs_remaining
|
||||
+ = ((sbp->st_nlink < MIN_DIR_NLINK
|
||||
+ || p->fts_level <= FTS_ROOTLEVEL)
|
||||
+ ? -1
|
||||
+ : sbp->st_nlink - (ISSET (FTS_SEEDOT) ? 0 : MIN_DIR_NLINK));
|
||||
if (ISDOT(p->fts_name)) {
|
||||
/* Command-line "." and ".." are real directories. */
|
||||
return (p->fts_level == FTS_ROOTLEVEL ? FTS_D : FTS_DOT);
|
||||
@@ -1914,17 +1928,7 @@ fts_alloc (FTS *sp, const char *name, register size_t namelen)
|
||||
* The file name is a variable length array. Allocate the FTSENT
|
||||
* structure and the file name in one chunk.
|
||||
*/
|
||||
- len = offsetof(FTSENT, fts_name) + namelen + 1;
|
||||
- /* Align the allocation size so that it works for FTSENT,
|
||||
- so that trailing padding may be referenced by direct access
|
||||
- to the flexible array members, without triggering undefined behavior
|
||||
- by accessing bytes beyond the heap allocation. This implicit access
|
||||
- was seen for example with ISDOT() and GCC 5.1.1 at -O2.
|
||||
- Do not use alignof (FTSENT) here, since C11 prohibits
|
||||
- taking the alignment of a structure containing a flexible
|
||||
- array member. */
|
||||
- len += alignof (max_align_t) - 1;
|
||||
- len &= ~ (alignof (max_align_t) - 1);
|
||||
+ len = FLEXSIZEOF(FTSENT, fts_name, namelen + 1);
|
||||
if ((p = malloc(len)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
diff --git a/gl/lib/fts_.h b/gl/lib/fts_.h
|
||||
index b9a3f12..70cc9e3 100644
|
||||
--- a/gl/lib/fts_.h
|
||||
+++ b/gl/lib/fts_.h
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Traverse a file hierarchy.
|
||||
|
||||
- Copyright (C) 2004-2015 Free Software Foundation, Inc.
|
||||
+ Copyright (C) 2004-2018 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
|
||||
@@ -13,7 +13,7 @@
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
@@ -220,7 +220,11 @@ typedef struct _ftsent {
|
||||
ptrdiff_t fts_level; /* depth (-1 to N) */
|
||||
|
||||
size_t fts_namelen; /* strlen(fts_name) */
|
||||
- nlink_t fts_n_dirs_remaining; /* count down from st_nlink */
|
||||
+
|
||||
+ /* If not (nlink_t) -1, an upper bound on the number of
|
||||
+ remaining subdirectories of interest. If this becomes
|
||||
+ zero, some work can be avoided. */
|
||||
+ nlink_t fts_n_dirs_remaining;
|
||||
|
||||
# define FTS_D 1 /* preorder directory */
|
||||
# define FTS_DC 2 /* directory that causes cycles */
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
||||
From ea88dd373c60feab541fe037369805f326dc3494 Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
Date: Mon, 12 Feb 2018 18:58:30 +0100
|
||||
Subject: [PATCH 2/4] fts: remove dependency on gnulib's fleximember.h
|
||||
|
||||
... by reverting upstream commit edb9d82948cb23f67a19e1b435047a0570225df3
|
||||
---
|
||||
gl/lib/fts.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/gl/lib/fts.c b/gl/lib/fts.c
|
||||
index bfa73e3..c37ebe2 100644
|
||||
--- a/gl/lib/fts.c
|
||||
+++ b/gl/lib/fts.c
|
||||
@@ -71,7 +71,6 @@ static char sccsid[] = "@(#)fts.c 8.6 (Berkeley) 8/14/94";
|
||||
|
||||
#if ! _LIBC
|
||||
# include "fcntl--.h"
|
||||
-# include "flexmember.h"
|
||||
# include "openat.h"
|
||||
# include "same-inode.h"
|
||||
#endif
|
||||
@@ -1928,7 +1927,17 @@ fts_alloc (FTS *sp, const char *name, register size_t namelen)
|
||||
* The file name is a variable length array. Allocate the FTSENT
|
||||
* structure and the file name in one chunk.
|
||||
*/
|
||||
- len = FLEXSIZEOF(FTSENT, fts_name, namelen + 1);
|
||||
+ len = offsetof(FTSENT, fts_name) + namelen + 1;
|
||||
+ /* Align the allocation size so that it works for FTSENT,
|
||||
+ so that trailing padding may be referenced by direct access
|
||||
+ to the flexible array members, without triggering undefined behavior
|
||||
+ by accessing bytes beyond the heap allocation. This implicit access
|
||||
+ was seen for example with ISDOT() and GCC 5.1.1 at -O2.
|
||||
+ Do not use alignof (FTSENT) here, since C11 prohibits
|
||||
+ taking the alignment of a structure containing a flexible
|
||||
+ array member. */
|
||||
+ len += alignof (max_align_t) - 1;
|
||||
+ len &= ~ (alignof (max_align_t) - 1);
|
||||
if ((p = malloc(len)) == NULL)
|
||||
return (NULL);
|
||||
|
||||
--
|
||||
2.13.6
|
||||
|
||||
|
||||
From 9c1720c99bbf8998dfdaa5976bca8bdc6d93f8e7 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Thu, 5 Apr 2018 08:48:01 -0700
|
||||
Subject: [PATCH 3/4] fts: treat CIFS like NFS
|
||||
|
||||
Problem reported by Kamil Dudka in:
|
||||
https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html
|
||||
* lib/fts.c (S_MAGIC_CIFS): New macro.
|
||||
(dirent_inode_sort_may_be_useful, leaf_optimization):
|
||||
Treat CIFS like NFS.
|
||||
|
||||
Upstream-commit: 2e53df541a30d438859087ed4b5a396e04697b9b
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
gl/lib/fts.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gl/lib/fts.c b/gl/lib/fts.c
|
||||
index c37ebe2..508ceac 100644
|
||||
--- a/gl/lib/fts.c
|
||||
+++ b/gl/lib/fts.c
|
||||
@@ -684,6 +684,7 @@ enum leaf_optimization
|
||||
|
||||
/* Linux-specific constants from coreutils' src/fs.h */
|
||||
# define S_MAGIC_AFS 0x5346414F
|
||||
+# define S_MAGIC_CIFS 0xFF534D42
|
||||
# define S_MAGIC_NFS 0x6969
|
||||
# define S_MAGIC_PROC 0x9FA0
|
||||
# define S_MAGIC_REISERFS 0x52654973
|
||||
@@ -791,8 +792,9 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
||||
|
||||
switch (filesystem_type (p))
|
||||
{
|
||||
- case S_MAGIC_TMPFS:
|
||||
+ case S_MAGIC_CIFS:
|
||||
case S_MAGIC_NFS:
|
||||
+ case S_MAGIC_TMPFS:
|
||||
/* On a file system of any of these types, sorting
|
||||
is unnecessary, and hence wasteful. */
|
||||
return false;
|
||||
@@ -826,6 +828,10 @@ leaf_optimization (FTSENT const *p)
|
||||
/* Although AFS mount points are not counted in st_nlink, they
|
||||
act like directories. See <https://bugs.debian.org/143111>. */
|
||||
FALLTHROUGH;
|
||||
+ case S_MAGIC_CIFS:
|
||||
+ /* Leaf optimization causes 'find' to abort. See
|
||||
+ <https://lists.gnu.org/r/bug-gnulib/2018-04/msg00015.html>. */
|
||||
+ FALLTHROUGH;
|
||||
case S_MAGIC_NFS:
|
||||
/* NFS provides usable dirent.d_type but not necessarily for all entries
|
||||
of large directories, so as per <https://bugzilla.redhat.com/1252549>
|
||||
--
|
||||
2.14.3
|
||||
|
||||
|
||||
From ff64329a046e76ba553c15373ed61bbed814d286 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Wed, 11 Apr 2018 12:50:35 -0700
|
||||
Subject: [PATCH 4/4] fts: fix bug in find across filesystems
|
||||
|
||||
This fixes a bug I introduced last summer.
|
||||
Problem reported by Kamil Dudka in:
|
||||
https://lists.gnu.org/r/bug-gnulib/2018-04/msg00033.html
|
||||
* lib/fts.c (filesystem_type, dirent_inode_sort_may_be_useful)
|
||||
(leaf_optimization):
|
||||
New arg for file descriptor. All callers changed.
|
||||
(fts_build): Check for whether inodes should be sorted
|
||||
before closing the directory.
|
||||
|
||||
Upstream-commit: 81b8c0d3be98f5a77403599de3d06329b3e7673e
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
gl/lib/fts.c | 55 +++++++++++++++++++++++++++++++------------------------
|
||||
1 file changed, 31 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/gl/lib/fts.c b/gl/lib/fts.c
|
||||
index 508ceac..175f12a 100644
|
||||
--- a/gl/lib/fts.c
|
||||
+++ b/gl/lib/fts.c
|
||||
@@ -725,11 +725,12 @@ dev_type_compare (void const *x, void const *y)
|
||||
return ax->st_dev == ay->st_dev;
|
||||
}
|
||||
|
||||
-/* Return the file system type of P, or 0 if not known.
|
||||
+/* Return the file system type of P with file descriptor FD, or 0 if not known.
|
||||
+ If FD is negative, P's file descriptor is unavailable.
|
||||
Try to cache known values. */
|
||||
|
||||
static fsword
|
||||
-filesystem_type (FTSENT const *p)
|
||||
+filesystem_type (FTSENT const *p, int fd)
|
||||
{
|
||||
FTS *sp = p->fts_fts;
|
||||
Hash_table *h = sp->fts_leaf_optimization_works_ht;
|
||||
@@ -755,7 +756,7 @@ filesystem_type (FTSENT const *p)
|
||||
}
|
||||
|
||||
/* Look-up failed. Query directly and cache the result. */
|
||||
- if (fstatfs (p->fts_fts->fts_cwd_fd, &fs_buf) != 0)
|
||||
+ if (fd < 0 || fstatfs (fd, &fs_buf) != 0)
|
||||
return 0;
|
||||
|
||||
if (h)
|
||||
@@ -777,12 +778,12 @@ filesystem_type (FTSENT const *p)
|
||||
return fs_buf.f_type;
|
||||
}
|
||||
|
||||
-/* Return false if it is easy to determine the file system type of the
|
||||
- directory P, and sorting dirents on inode numbers is known not to
|
||||
- improve traversal performance with that type of file system.
|
||||
- Otherwise, return true. */
|
||||
+/* Return true if sorting dirents on inode numbers is known to improve
|
||||
+ traversal performance for the directory P with descriptor DIR_FD.
|
||||
+ Return false otherwise. When in doubt, return true.
|
||||
+ DIR_FD is negative if unavailable. */
|
||||
static bool
|
||||
-dirent_inode_sort_may_be_useful (FTSENT const *p)
|
||||
+dirent_inode_sort_may_be_useful (FTSENT const *p, int dir_fd)
|
||||
{
|
||||
/* Skip the sort only if we can determine efficiently
|
||||
that skipping it is the right thing to do.
|
||||
@@ -790,7 +791,7 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
||||
while the cost of *not* performing it can be O(N^2) with
|
||||
a very large constant. */
|
||||
|
||||
- switch (filesystem_type (p))
|
||||
+ switch (filesystem_type (p, dir_fd))
|
||||
{
|
||||
case S_MAGIC_CIFS:
|
||||
case S_MAGIC_NFS:
|
||||
@@ -804,16 +805,17 @@ dirent_inode_sort_may_be_useful (FTSENT const *p)
|
||||
}
|
||||
}
|
||||
|
||||
-/* Given an FTS entry P for a directory D,
|
||||
+/* Given an FTS entry P for a directory with descriptor DIR_FD,
|
||||
return true if it is both useful and valid to apply leaf optimization.
|
||||
The optimization is useful only for file systems that lack usable
|
||||
dirent.d_type info. The optimization is valid if an st_nlink value
|
||||
of at least MIN_DIR_NLINK is an upper bound on the number of
|
||||
- subdirectories of D, counting "." and ".." as subdirectories. */
|
||||
+ subdirectories of D, counting "." and ".." as subdirectories.
|
||||
+ DIR_FD is negative if unavailable. */
|
||||
static enum leaf_optimization
|
||||
-leaf_optimization (FTSENT const *p)
|
||||
+leaf_optimization (FTSENT const *p, int dir_fd)
|
||||
{
|
||||
- switch (filesystem_type (p))
|
||||
+ switch (filesystem_type (p, dir_fd))
|
||||
{
|
||||
/* List here the file system types that may lack usable dirent.d_type
|
||||
info, yet for which the optimization does apply. */
|
||||
@@ -850,12 +852,13 @@ leaf_optimization (FTSENT const *p)
|
||||
|
||||
#else
|
||||
static bool
|
||||
-dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED)
|
||||
+dirent_inode_sort_may_be_useful (FTSENT const *p _GL_UNUSED,
|
||||
+ int dir_fd _GL_UNUSED)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
static enum leaf_optimization
|
||||
-leaf_optimization (FTSENT const *p _GL_UNUSED)
|
||||
+leaf_optimization (FTSENT const *p _GL_UNUSED, int dir_fd _GL_UNUSED)
|
||||
{
|
||||
return NO_LEAF_OPTIMIZATION;
|
||||
}
|
||||
@@ -1049,7 +1052,7 @@ check_for_dir:
|
||||
if (parent->fts_n_dirs_remaining == 0
|
||||
&& ISSET(FTS_NOSTAT)
|
||||
&& ISSET(FTS_PHYSICAL)
|
||||
- && (leaf_optimization (parent)
|
||||
+ && (leaf_optimization (parent, sp->fts_cwd_fd)
|
||||
== NOSTAT_LEAF_OPTIMIZATION))
|
||||
{
|
||||
/* nothing more needed */
|
||||
@@ -1334,6 +1337,7 @@ fts_build (register FTS *sp, int type)
|
||||
int dir_fd;
|
||||
FTSENT *cur = sp->fts_cur;
|
||||
bool continue_readdir = !!cur->fts_dirp;
|
||||
+ bool sort_by_inode = false;
|
||||
size_t max_entries;
|
||||
|
||||
/* When cur->fts_dirp is non-NULL, that means we should
|
||||
@@ -1427,7 +1431,7 @@ fts_build (register FTS *sp, int type)
|
||||
&& ! (ISSET (FTS_NOSTAT) && ISSET (FTS_PHYSICAL)
|
||||
&& ! ISSET (FTS_SEEDOT)
|
||||
&& cur->fts_statp->st_nlink == MIN_DIR_NLINK
|
||||
- && (leaf_optimization (cur)
|
||||
+ && (leaf_optimization (cur, dir_fd)
|
||||
!= NO_LEAF_OPTIMIZATION)));
|
||||
if (descend || type == BREAD)
|
||||
{
|
||||
@@ -1588,6 +1592,15 @@ mem1: saved_errno = errno;
|
||||
tail->fts_link = p;
|
||||
tail = p;
|
||||
}
|
||||
+
|
||||
+ /* If there are many entries, no sorting function has been
|
||||
+ specified, and this file system is of a type that may be
|
||||
+ slow with a large number of entries, arrange to sort the
|
||||
+ directory entries on increasing inode numbers. */
|
||||
+ if (nitems == _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
|
||||
+ && !sp->fts_compar)
|
||||
+ sort_by_inode = dirent_inode_sort_may_be_useful (cur, dir_fd);
|
||||
+
|
||||
++nitems;
|
||||
if (max_entries <= nitems) {
|
||||
/* When there are too many dir entries, leave
|
||||
@@ -1645,13 +1658,7 @@ mem1: saved_errno = errno;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
- /* If there are many entries, no sorting function has been specified,
|
||||
- and this file system is of a type that may be slow with a large
|
||||
- number of entries, then sort the directory entries on increasing
|
||||
- inode numbers. */
|
||||
- if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
|
||||
- && !sp->fts_compar
|
||||
- && dirent_inode_sort_may_be_useful (cur)) {
|
||||
+ if (sort_by_inode) {
|
||||
sp->fts_compar = fts_compare_ino;
|
||||
head = fts_sort (sp, head, nitems);
|
||||
sp->fts_compar = NULL;
|
||||
--
|
||||
2.14.3
|
||||
|
||||
@ -1,142 +0,0 @@
|
||||
From 80cdfba079627e15129a926a133825b961d41e36 Mon Sep 17 00:00:00 2001
|
||||
From: Paul Eggert <eggert@cs.ucla.edu>
|
||||
Date: Mon, 5 Mar 2018 10:56:29 -0800
|
||||
Subject: [PATCH] fflush: adjust to glibc 2.28 libio.h removal
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Problem reported by Daniel P. Berrangé in:
|
||||
https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html
|
||||
* lib/fflush.c (clear_ungetc_buffer_preserving_position)
|
||||
(disable_seek_optimization, rpl_fflush):
|
||||
* lib/fpurge.c (fpurge):
|
||||
* lib/freadahead.c (freadahead):
|
||||
* lib/freading.c (freading):
|
||||
* lib/fseeko.c (fseeko):
|
||||
* lib/stdio-impl.h (_IO_IN_BACKUP) [_IO_EOF_SEEN]:
|
||||
Define if not already defined.
|
||||
|
||||
Upstream-commit: 4af4a4a71827c0bc5e0ec67af23edef4f15cee8e
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
gl/lib/fflush.c | 6 +++---
|
||||
gl/lib/fpurge.c | 2 +-
|
||||
gl/lib/freadahead.c | 2 +-
|
||||
gl/lib/freading.c | 2 +-
|
||||
gl/lib/fseeko.c | 4 ++--
|
||||
gl/lib/stdio-impl.h | 6 ++++++
|
||||
6 files changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/gl/lib/fflush.c b/gl/lib/fflush.c
|
||||
index 5ae3e41..7a82470 100644
|
||||
--- a/gl/lib/fflush.c
|
||||
+++ b/gl/lib/fflush.c
|
||||
@@ -33,7 +33,7 @@
|
||||
#undef fflush
|
||||
|
||||
|
||||
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
|
||||
/* Clear the stream's ungetc buffer, preserving the value of ftello (fp). */
|
||||
static void
|
||||
@@ -72,7 +72,7 @@ clear_ungetc_buffer (FILE *fp)
|
||||
|
||||
#endif
|
||||
|
||||
-#if ! (defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
|
||||
+#if ! (defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */)
|
||||
|
||||
# if (defined __sferror || defined __DragonFly__ || defined __ANDROID__) && defined __SNPT
|
||||
/* FreeBSD, NetBSD, OpenBSD, DragonFly, Mac OS X, Cygwin, Android */
|
||||
@@ -148,7 +148,7 @@ rpl_fflush (FILE *stream)
|
||||
if (stream == NULL || ! freading (stream))
|
||||
return fflush (stream);
|
||||
|
||||
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
|
||||
clear_ungetc_buffer_preserving_position (stream);
|
||||
|
||||
diff --git a/gl/lib/fpurge.c b/gl/lib/fpurge.c
|
||||
index f313b22..ecdf82d 100644
|
||||
--- a/gl/lib/fpurge.c
|
||||
+++ b/gl/lib/fpurge.c
|
||||
@@ -62,7 +62,7 @@ fpurge (FILE *fp)
|
||||
/* Most systems provide FILE as a struct and the necessary bitmask in
|
||||
<stdio.h>, because they need it for implementing getc() and putc() as
|
||||
fast macros. */
|
||||
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
fp->_IO_read_end = fp->_IO_read_ptr;
|
||||
fp->_IO_write_ptr = fp->_IO_write_base;
|
||||
/* Avoid memory leak when there is an active ungetc buffer. */
|
||||
diff --git a/gl/lib/freadahead.c b/gl/lib/freadahead.c
|
||||
index 094daab..3f8101e 100644
|
||||
--- a/gl/lib/freadahead.c
|
||||
+++ b/gl/lib/freadahead.c
|
||||
@@ -25,7 +25,7 @@
|
||||
size_t
|
||||
freadahead (FILE *fp)
|
||||
{
|
||||
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
if (fp->_IO_write_ptr > fp->_IO_write_base)
|
||||
return 0;
|
||||
return (fp->_IO_read_end - fp->_IO_read_ptr)
|
||||
diff --git a/gl/lib/freading.c b/gl/lib/freading.c
|
||||
index 0512b19..8c48fe4 100644
|
||||
--- a/gl/lib/freading.c
|
||||
+++ b/gl/lib/freading.c
|
||||
@@ -31,7 +31,7 @@ freading (FILE *fp)
|
||||
/* Most systems provide FILE as a struct and the necessary bitmask in
|
||||
<stdio.h>, because they need it for implementing getc() and putc() as
|
||||
fast macros. */
|
||||
-# if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+# if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
return ((fp->_flags & _IO_NO_WRITES) != 0
|
||||
|| ((fp->_flags & (_IO_NO_READS | _IO_CURRENTLY_PUTTING)) == 0
|
||||
&& fp->_IO_read_base != NULL));
|
||||
diff --git a/gl/lib/fseeko.c b/gl/lib/fseeko.c
|
||||
index 1c65d2a..9026408 100644
|
||||
--- a/gl/lib/fseeko.c
|
||||
+++ b/gl/lib/fseeko.c
|
||||
@@ -47,7 +47,7 @@ fseeko (FILE *fp, off_t offset, int whence)
|
||||
#endif
|
||||
|
||||
/* These tests are based on fpurge.c. */
|
||||
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
if (fp->_IO_read_end == fp->_IO_read_ptr
|
||||
&& fp->_IO_write_ptr == fp->_IO_write_base
|
||||
&& fp->_IO_save_base == NULL)
|
||||
@@ -123,7 +123,7 @@ fseeko (FILE *fp, off_t offset, int whence)
|
||||
return -1;
|
||||
}
|
||||
|
||||
-#if defined _IO_ftrylockfile || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
+#if defined _IO_EOF_SEEN || __GNU_LIBRARY__ == 1 /* GNU libc, BeOS, Haiku, Linux libc5 */
|
||||
fp->_flags &= ~_IO_EOF_SEEN;
|
||||
fp->_offset = pos;
|
||||
#elif defined __sferror || defined __DragonFly__ || defined __ANDROID__
|
||||
diff --git a/gl/lib/stdio-impl.h b/gl/lib/stdio-impl.h
|
||||
index 502d891..ea38ee2 100644
|
||||
--- a/gl/lib/stdio-impl.h
|
||||
+++ b/gl/lib/stdio-impl.h
|
||||
@@ -18,6 +18,12 @@
|
||||
the same implementation of stdio extension API, except that some fields
|
||||
have different naming conventions, or their access requires some casts. */
|
||||
|
||||
+/* Glibc 2.28 made _IO_IN_BACKUP private. For now, work around this
|
||||
+ problem by defining it ourselves. FIXME: Do not rely on glibc
|
||||
+ internals. */
|
||||
+#if !defined _IO_IN_BACKUP && defined _IO_EOF_SEEN
|
||||
+# define _IO_IN_BACKUP 0x100
|
||||
+#endif
|
||||
|
||||
/* BSD stdio derived implementations. */
|
||||
|
||||
--
|
||||
2.16.2
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
From 80628047a6cc83f82e0c410a82b8f7facd9d50f2 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Blake <eblake@redhat.com>
|
||||
Date: Wed, 14 Sep 2016 19:21:42 -0500
|
||||
Subject: [PATCH] mountlist: include sysmacros.h for glibc
|
||||
|
||||
On Fedora rawhide (glibc 2.25), './gnulib-tool --test mountlist'
|
||||
reports:
|
||||
../../gllib/mountlist.c: In function 'read_file_system_list':
|
||||
../../gllib/mountlist.c:534:13: warning: '__makedev_from_sys_types' is deprecated:
|
||||
In the GNU C Library, `makedev' is defined by <sys/sysmacros.h>.
|
||||
For historical compatibility, it is currently defined by
|
||||
<sys/types.h> as well, but we plan to remove this soon.
|
||||
To use `makedev', include <sys/sysmacros.h> directly.
|
||||
If you did not intend to use a system-defined macro `makedev',
|
||||
you should #undef it after including <sys/types.h>.
|
||||
[-Wdeprecated-declarations]
|
||||
me->me_dev = makedev (devmaj, devmin);
|
||||
^~
|
||||
In file included from /usr/include/features.h:397:0,
|
||||
from /usr/include/sys/types.h:25,
|
||||
from ./sys/types.h:28,
|
||||
from ../../gllib/mountlist.h:23,
|
||||
from ../../gllib/mountlist.c:20:
|
||||
/usr/include/sys/sysmacros.h:89:1: note: declared here
|
||||
__SYSMACROS_DEFINE_MAKEDEV (__SYSMACROS_FST_IMPL_TEMPL)
|
||||
^
|
||||
|
||||
Fix it by including the right headers. We also need a fix to
|
||||
autoconf's AC_HEADER_MAJOR, but that's a separate patch.
|
||||
|
||||
* m4/mountlist.m4 (gl_PREREQ_MOUTLIST_EXTRA): Include
|
||||
AC_HEADER_MAJOR.
|
||||
* lib/mountlist.c (includes): Use correct headers.
|
||||
|
||||
Signed-off-by: Eric Blake <eblake@redhat.com>
|
||||
|
||||
Upstream-commit: 4da63c5881f60f71999a943612da9112232b9161
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
gl/lib/mountlist.c | 6 ++++++
|
||||
gl/m4/mountlist.m4 | 3 ++-
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gl/lib/mountlist.c b/gl/lib/mountlist.c
|
||||
index c3d2852..0b6f92e 100644
|
||||
--- a/gl/lib/mountlist.c
|
||||
+++ b/gl/lib/mountlist.c
|
||||
@@ -37,6 +37,12 @@
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
|
||||
+#if MAJOR_IN_MKDEV
|
||||
+# include <sys/mkdev.h>
|
||||
+#elif MAJOR_IN_SYSMACROS
|
||||
+# include <sys/sysmacros.h>
|
||||
+#endif
|
||||
+
|
||||
#if defined MOUNTED_GETFSSTAT /* OSF_1 and Darwin1.3.x */
|
||||
# if HAVE_SYS_UCRED_H
|
||||
# include <grp.h> /* needed on OSF V4.0 for definition of NGROUPS,
|
||||
diff --git a/gl/m4/mountlist.m4 b/gl/m4/mountlist.m4
|
||||
index ec58dc8..82b2dcb 100644
|
||||
--- a/gl/m4/mountlist.m4
|
||||
+++ b/gl/m4/mountlist.m4
|
||||
@@ -1,4 +1,4 @@
|
||||
-# serial 11
|
||||
+# serial 12
|
||||
dnl Copyright (C) 2002-2006, 2009-2015 Free Software Foundation, Inc.
|
||||
dnl This file is free software; the Free Software Foundation
|
||||
dnl gives unlimited permission to copy and/or distribute it,
|
||||
@@ -15,5 +15,6 @@ AC_DEFUN([gl_PREREQ_MOUNTLIST_EXTRA],
|
||||
[
|
||||
dnl Note gl_LIST_MOUNTED_FILE_SYSTEMS checks for mntent.h, not sys/mntent.h.
|
||||
AC_CHECK_HEADERS([sys/mntent.h])
|
||||
+ AC_HEADER_MAJOR()dnl for use of makedev ()
|
||||
gl_FSTYPENAME
|
||||
])
|
||||
--
|
||||
2.16.2
|
||||
|
||||
@ -1,195 +0,0 @@
|
||||
From d844b7bbf3952998a906f21ba432aa62a3b9c7c6 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 14 Jun 2016 20:49:42 +0200
|
||||
Subject: [PATCH] Fix bug #48180: find: avoid segfault for internal '-noop'
|
||||
option
|
||||
|
||||
The pseudo-option '-noop' was never meant to be exposed to the user
|
||||
interface. If specified by the user, find(1) segfaulted.
|
||||
Bug introduced in commit FINDUTILS_4_3_0-1-12-g6b8a4db.
|
||||
|
||||
* find/parser.c (struct parser_table): Rename the parser_name element of
|
||||
the ARG_NOOP entry from 'noop' to '--noop', thus indicating its pure
|
||||
internal character.
|
||||
(found_parser): Return NULL when the user has passed the '---noop' option;
|
||||
the caller does the error handling.
|
||||
* find/testsuite/sv-48180-refuse-noop.sh: Add test.
|
||||
* find/testsuite/Makefile.am (test_shell_progs): Reference the test.
|
||||
* NEWS (Bug fixes): Document the fix.
|
||||
|
||||
Reported by Tavian Barnes <tavianator@tavianator.com> in
|
||||
https://savannah.gnu.org/bugs/?48180
|
||||
|
||||
Upstream-commit: 595060f28eb5f658fa8d98970959c617fab0f078
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
find/parser.c | 6 +-
|
||||
find/testsuite/Makefile.am | 3 +-
|
||||
find/testsuite/sv-48180-refuse-noop.sh | 117 +++++++++++++++++++++++++++++++++
|
||||
3 files changed, 124 insertions(+), 2 deletions(-)
|
||||
create mode 100644 find/testsuite/sv-48180-refuse-noop.sh
|
||||
|
||||
diff --git a/find/parser.c b/find/parser.c
|
||||
index 2d45349..697b2a2 100644
|
||||
--- a/find/parser.c
|
||||
+++ b/find/parser.c
|
||||
@@ -321,7 +321,8 @@ static struct parser_table const parse_table[] =
|
||||
*/
|
||||
{ARG_TEST, "false", parse_false, pred_false}, /* GNU */
|
||||
{ARG_TEST, "true", parse_true, pred_true }, /* GNU */
|
||||
- {ARG_NOOP, "noop", NULL, pred_true }, /* GNU, internal use only */
|
||||
+ /* Internal pseudo-option, therefore 3 minus: ---noop. */
|
||||
+ {ARG_NOOP, "--noop", NULL, pred_true }, /* GNU, internal use only */
|
||||
|
||||
/* Various other cases that don't fit neatly into our macro scheme. */
|
||||
{ARG_TEST, "help", parse_help, NULL}, /* GNU */
|
||||
@@ -596,6 +597,9 @@ found_parser (const char *original_arg, const struct parser_table *entry)
|
||||
*/
|
||||
if (entry->type != ARG_POSITIONAL_OPTION)
|
||||
{
|
||||
+ if (entry->type == ARG_NOOP)
|
||||
+ return NULL; /* internal use only, trap -noop here. */
|
||||
+
|
||||
/* Something other than -follow/-daystart.
|
||||
* If this is an option, check if it followed
|
||||
* a non-option and if so, issue a warning.
|
||||
diff --git a/find/testsuite/Makefile.am b/find/testsuite/Makefile.am
|
||||
index ab5dbe8..1371c70 100644
|
||||
--- a/find/testsuite/Makefile.am
|
||||
+++ b/find/testsuite/Makefile.am
|
||||
@@ -259,7 +259,8 @@ test_escape_c.sh \
|
||||
test_inode.sh \
|
||||
sv-34079.sh \
|
||||
sv-34976-execdir-fd-leak.sh \
|
||||
-sv-48030-exec-plus-bug.sh
|
||||
+sv-48030-exec-plus-bug.sh \
|
||||
+sv-48180-refuse-noop.sh
|
||||
|
||||
EXTRA_DIST = $(EXTRA_DIST_EXP) $(EXTRA_DIST_XO) $(EXTRA_DIST_GOLDEN) \
|
||||
$(test_shell_progs) binary_locations.sh checklists.py
|
||||
diff --git a/find/testsuite/sv-48180-refuse-noop.sh b/find/testsuite/sv-48180-refuse-noop.sh
|
||||
new file mode 100755
|
||||
index 0000000..974f0f0
|
||||
--- /dev/null
|
||||
+++ b/find/testsuite/sv-48180-refuse-noop.sh
|
||||
@@ -0,0 +1,117 @@
|
||||
+#! /bin/sh
|
||||
+# Copyright (C) 2016 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
|
||||
+# the Free Software Foundation, either version 3 of the License, or
|
||||
+# (at your option) any later version.
|
||||
+#
|
||||
+# This program is distributed in the hope that it will be useful,
|
||||
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
+# GNU General Public License for more details.
|
||||
+#
|
||||
+# You should have received a copy of the GNU General Public License
|
||||
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
+#
|
||||
+
|
||||
+# This test verifies that find refuses the internal -noop, ---noop option.
|
||||
+# Between findutils-4.3.1 and 4.6, find dumped core ($? = 139).
|
||||
+
|
||||
+testname="$(basename $0)"
|
||||
+
|
||||
+. "${srcdir}"/binary_locations.sh
|
||||
+
|
||||
+die() {
|
||||
+ echo "$@" >&2
|
||||
+ exit 1
|
||||
+}
|
||||
+
|
||||
+# This is used to simplify checking of the return value
|
||||
+# which is useful when ensuring a command fails as desired.
|
||||
+# I.e., just doing `command ... &&fail=1` will not catch
|
||||
+# a segfault in command for example. With this helper you
|
||||
+# instead check an explicit exit code like
|
||||
+# returns_ 1 command ... || fail
|
||||
+returns_ () {
|
||||
+ # Disable tracing so it doesn't interfere with stderr of the wrapped command
|
||||
+ { set +x; } 2>/dev/null
|
||||
+
|
||||
+ local exp_exit="$1"
|
||||
+ shift
|
||||
+ "$@"
|
||||
+ test $? -eq $exp_exit && ret_=0 || ret_=1
|
||||
+
|
||||
+ set -x
|
||||
+ { return $ret_; } 2>/dev/null
|
||||
+}
|
||||
+
|
||||
+# Define the nicest compare available (borrowed from gnulib).
|
||||
+if diff_out_=`exec 2>/dev/null; diff -u "$0" "$0" < /dev/null` \
|
||||
+ && diff -u Makefile "$0" 2>/dev/null | grep '^[+]#!' >/dev/null; then
|
||||
+ # diff accepts the -u option and does not (like AIX 7 'diff') produce an
|
||||
+ # extra space on column 1 of every content line.
|
||||
+ if test -z "$diff_out_"; then
|
||||
+ compare () { diff -u "$@"; }
|
||||
+ else
|
||||
+ compare ()
|
||||
+ {
|
||||
+ if diff -u "$@" > diff.out; then
|
||||
+ # No differences were found, but Solaris 'diff' produces output
|
||||
+ # "No differences encountered". Hide this output.
|
||||
+ rm -f diff.out
|
||||
+ true
|
||||
+ else
|
||||
+ cat diff.out
|
||||
+ rm -f diff.out
|
||||
+ false
|
||||
+ fi
|
||||
+ }
|
||||
+ fi
|
||||
+elif diff_out_=`exec 2>/dev/null; diff -c "$0" "$0" < /dev/null`; then
|
||||
+ if test -z "$diff_out_"; then
|
||||
+ compare () { diff -c "$@"; }
|
||||
+ else
|
||||
+ compare ()
|
||||
+ {
|
||||
+ if diff -c "$@" > diff.out; then
|
||||
+ # No differences were found, but AIX and HP-UX 'diff' produce output
|
||||
+ # "No differences encountered" or "There are no differences between the
|
||||
+ # files.". Hide this output.
|
||||
+ rm -f diff.out
|
||||
+ true
|
||||
+ else
|
||||
+ cat diff.out
|
||||
+ rm -f diff.out
|
||||
+ false
|
||||
+ fi
|
||||
+ }
|
||||
+ fi
|
||||
+elif cmp -s /dev/null /dev/null 2>/dev/null; then
|
||||
+ compare () { cmp -s "$@"; }
|
||||
+else
|
||||
+ compare () { cmp "$@"; }
|
||||
+fi
|
||||
+
|
||||
+set -x
|
||||
+tmpdir="$(mktemp -d)" \
|
||||
+ && cd "$tmpdir" \
|
||||
+ || die "FAIL: failed to set up the test in ${tmpdir}"
|
||||
+
|
||||
+fail=0
|
||||
+# Exercise both the previous name of the pseudo-option '-noop',
|
||||
+# and the now renamed '---noop' option for both find executables.
|
||||
+for exe in "${ftsfind}" "${oldfind}"; do
|
||||
+ for opt in 'noop' '--noop'; do
|
||||
+ out="${exe}${opt}.out"
|
||||
+ err="${exe}${opt}.err"
|
||||
+ returns_ 1 "$exe" "-${opt}" >"$out" 2> "$err" || fail=1
|
||||
+ compare /dev/null "$out" || fail=1
|
||||
+ grep "find: unknown predicate .-${opt}." "$err" \
|
||||
+ || { cat "$err"; fail=1; }
|
||||
+ done
|
||||
+done
|
||||
+
|
||||
+cd ..
|
||||
+rm -rf "$tmpdir" || exit 1
|
||||
+exit $fail
|
||||
--
|
||||
2.5.5
|
||||
|
||||
@ -1,83 +0,0 @@
|
||||
From 1328926a705fdb4728c1f255dd368de928736d39 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Fri, 25 Sep 2015 16:09:39 +0200
|
||||
Subject: [PATCH 1/2] fts: introduce the FTS_NOLEAF flag
|
||||
|
||||
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.
|
||||
---
|
||||
gl/lib/fts.c | 4 ++++
|
||||
gl/lib/fts_.h | 12 +++++++++---
|
||||
2 files changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/gl/lib/fts.c b/gl/lib/fts.c
|
||||
index d2d404f..808466f 100644
|
||||
--- a/gl/lib/fts.c
|
||||
+++ b/gl/lib/fts.c
|
||||
@@ -736,6 +736,10 @@ filesystem_type (FTSENT const *p)
|
||||
struct dev_type *ent;
|
||||
struct statfs fs_buf;
|
||||
|
||||
+ if (ISSET(FTS_NOLEAF))
|
||||
+ /* leaf optimization explicitly disabled by the FTS_NOLEAF flag */
|
||||
+ return 0;
|
||||
+
|
||||
/* 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/gl/lib/fts_.h b/gl/lib/fts_.h
|
||||
index 63d4b74..f1d519b 100644
|
||||
--- a/gl/lib/fts_.h
|
||||
+++ b/gl/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.5.0
|
||||
|
||||
|
||||
From c186934e6e37ddadf7511abb9b1045192757618e Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Fri, 25 Sep 2015 19:13:15 +0200
|
||||
Subject: [PATCH 2/2] ftsfind: propagate the -noleaf option to FTS
|
||||
|
||||
* find/ftsfind.c (find): Propagate the -noleaf option to FTS.
|
||||
---
|
||||
find/ftsfind.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/find/ftsfind.c b/find/ftsfind.c
|
||||
index 5159470..e34b672 100644
|
||||
--- a/find/ftsfind.c
|
||||
+++ b/find/ftsfind.c
|
||||
@@ -559,6 +559,9 @@ find (char *arg)
|
||||
if (options.stay_on_filesystem)
|
||||
ftsoptions |= FTS_XDEV;
|
||||
|
||||
+ if (options.no_leaf_check)
|
||||
+ ftsoptions |= FTS_NOLEAF;
|
||||
+
|
||||
p = fts_open (arglist, ftsoptions, NULL);
|
||||
if (NULL == p)
|
||||
{
|
||||
--
|
||||
2.5.0
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
From a8ff1e964b2b8cd0b60362c76bd92795cee6b3c3 Mon Sep 17 00:00:00 2001
|
||||
From: Kamil Dudka <kdudka@redhat.com>
|
||||
Date: Sun, 17 Apr 2016 22:36:13 +0200
|
||||
Subject: [PATCH] doc: clarify exit status handling of -exec command {} +
|
||||
|
||||
* find/find.1 (-exec): Explain how exit status is propagated if the
|
||||
-exec command {} + syntax is used.
|
||||
(-execdir): Likewise.
|
||||
|
||||
Reported at https://bugzilla.redhat.com/1325049
|
||||
|
||||
Upstream-commit: ae424b959c5e9bd23f9f686cb34653bc4cd1270e
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
find/find.1 | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/find/find.1 b/find/find.1
|
||||
index a36a0bc..c4aaf17 100644
|
||||
--- a/find/find.1
|
||||
+++ b/find/find.1
|
||||
@@ -1069,6 +1069,9 @@ command line is built in much the same way that
|
||||
.B xargs
|
||||
builds its command lines. Only one instance of `{}' is allowed within
|
||||
the command. The command is executed in the starting directory. If
|
||||
+any invocation returns a non-zero value as exit status, then
|
||||
+.B find
|
||||
+returns a non-zero exit status. If
|
||||
.B find
|
||||
encounters an error, this can sometimes cause an
|
||||
immediate exit, so some pending commands may not be run
|
||||
@@ -1104,6 +1107,9 @@ appropriately-named file in a directory in which you will run
|
||||
The same applies to having entries in
|
||||
.B $PATH
|
||||
which are empty or which are not absolute directory names. If
|
||||
+any invocation returns a non-zero value as exit status, then
|
||||
+.B find
|
||||
+returns a non-zero exit status. If
|
||||
.B find
|
||||
encounters an error, this can sometimes cause an
|
||||
immediate exit, so some pending commands may not be run
|
||||
--
|
||||
2.5.5
|
||||
|
||||
@ -1,35 +0,0 @@
|
||||
From 06a46ba755195810f2aeda01b12d1ccfe7c2dcfd Mon Sep 17 00:00:00 2001
|
||||
From: Daiki Ueno <ueno@gnu.org>
|
||||
Date: Mon, 28 Dec 2015 06:27:42 +0900
|
||||
Subject: [PATCH] maint: fix operator precedence in mbrtowc test
|
||||
|
||||
This is a fix for test breakage introduced by commit 45228d96; the
|
||||
equality expression must be parenthesized when negated with '!',
|
||||
otherwise we always get:
|
||||
|
||||
test-mbrtowc.c:49: assertion 'ret == (size_t)(-2)' failed
|
||||
|
||||
* m4/mbrtowc.m4 (gl_MBRTOWC_EMPTY_INPUT): Negate the entire expression.
|
||||
|
||||
Upstream-commit: 1f63650823cebf52044df840c81062ccb52163a2
|
||||
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
||||
---
|
||||
gl/m4/mbrtowc.m4 | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/gl/m4/mbrtowc.m4 b/gl/m4/mbrtowc.m4
|
||||
index deb9f06..be2e9d6 100644
|
||||
--- a/gl/m4/mbrtowc.m4
|
||||
+++ b/gl/m4/mbrtowc.m4
|
||||
@@ -569,7 +569,7 @@ changequote([,])dnl
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
- return ! mbrtowc (&wc, "", 0, &mbs) == (size_t) -2;
|
||||
+ return mbrtowc (&wc, "", 0, &mbs) != (size_t) -2;
|
||||
}]])],
|
||||
[gl_cv_func_mbrtowc_empty_input=yes],
|
||||
[gl_cv_func_mbrtowc_empty_input=no],
|
||||
--
|
||||
2.5.0
|
||||
|
||||
@ -1,29 +0,0 @@
|
||||
From 129f23ce758620fade812baab811379ce8454048 Mon Sep 17 00:00:00 2001
|
||||
From: rpm-build <rpm-build>
|
||||
Date: Fri, 27 Jan 2017 11:44:41 +0100
|
||||
Subject: [PATCH] test-lock: disable the rwlock test
|
||||
|
||||
It hangs indefinitely if the system rwlock implementation does not
|
||||
prevent writer starvation (and glibc does not implement it).
|
||||
|
||||
Bug: http://www.mail-archive.com/bug-gnulib@gnu.org/msg33017.html
|
||||
---
|
||||
tests/test-lock.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/tests/test-lock.c b/tests/test-lock.c
|
||||
index a992f64..fd9c014 100644
|
||||
--- a/tests/test-lock.c
|
||||
+++ b/tests/test-lock.c
|
||||
@@ -42,7 +42,7 @@
|
||||
Uncomment some of these, to verify that all tests crash if no locking
|
||||
is enabled. */
|
||||
#define DO_TEST_LOCK 1
|
||||
-#define DO_TEST_RWLOCK 1
|
||||
+#define DO_TEST_RWLOCK 0
|
||||
#define DO_TEST_RECURSIVE_LOCK 1
|
||||
#define DO_TEST_ONCE 1
|
||||
|
||||
--
|
||||
2.7.4
|
||||
|
||||
Binary file not shown.
BIN
findutils-4.7.0.tar.xz
Normal file
BIN
findutils-4.7.0.tar.xz
Normal file
Binary file not shown.
@ -1,75 +1,13 @@
|
||||
Name: findutils
|
||||
Epoch: 2
|
||||
Version: 4.6.0
|
||||
Release: 5
|
||||
Version: 4.7.0
|
||||
Release: 1
|
||||
Summary: The GNU Find Utilities
|
||||
License: GPLv3+
|
||||
URL: http://www.gnu.org/software/findutils/
|
||||
Source0: https://ftp.gnu.org/pub/gnu/findutils/%{name}-%{version}.tar.gz
|
||||
Source0: https://ftp.gnu.org/pub/gnu/findutils/%{name}-%{version}.tar.xz
|
||||
|
||||
# prevent mbrtowc tests from failing (#1294016)
|
||||
Patch0: findutils-4.6.0-mbrtowc-tests.patch
|
||||
|
||||
# do not build locate
|
||||
Patch1: findutils-4.5.15-no-locate.patch
|
||||
|
||||
# fix build failure with glibc-2.28
|
||||
# https://lists.gnu.org/r/bug-gnulib/2018-03/msg00000.html
|
||||
Patch2: findutils-4.6.0-gnulib-fflush.patch
|
||||
|
||||
# add a new option -xautofs to find to not descend into directories on autofs
|
||||
# file systems
|
||||
Patch3: findutils-4.4.2-xautofs.patch
|
||||
|
||||
# eliminate compile-time warnings
|
||||
Patch4: findutils-4.5.13-warnings.patch
|
||||
|
||||
# clarify exit status handling of -exec cmd {} + in find(1) man page (#1325049)
|
||||
Patch5: findutils-4.6.0-man-exec.patch
|
||||
|
||||
# make sure that find -exec + passes all arguments (upstream bug #48030)
|
||||
Patch6: findutils-4.6.0-exec-args.patch
|
||||
|
||||
# fix build failure with glibc-2.25+
|
||||
Patch7: findutils-4.6.0-gnulib-makedev.patch
|
||||
|
||||
# avoid SIGSEGV in case the internal -noop option is used (#1346471)
|
||||
Patch9: findutils-4.6.0-internal-noop.patch
|
||||
|
||||
# test-lock: disable the rwlock test
|
||||
Patch10: findutils-4.6.0-test-lock.patch
|
||||
|
||||
# import gnulib's FTS module from upstream commit 281b825e (#1544429)
|
||||
Patch11: findutils-4.6.0-fts-update.patch
|
||||
|
||||
# implement the -noleaf option of find (#1252549)
|
||||
Patch12: findutils-4.6.0-leaf-opt.patch
|
||||
|
||||
#upstream patches
|
||||
Patch6000: Remove-the-enable-id-cache-configure-option.patch
|
||||
Patch6001: find-Fix-a-number-of-compiler-warnings-mostly-const-.patch
|
||||
Patch6002: lib-Update-the-width-of-the-st_nlink-field-and-fix-s.patch
|
||||
Patch6003: regexprops-Fix-compiler-warnings-and-update-copyrigh.patch
|
||||
Patch6004: Fix-bug-48314-find-fix-type-option-regression-on-som.patch
|
||||
Patch6005: maint-remove-ChangeLog-2013-from-distribution-tarbal.patch
|
||||
Patch6006: find-handle-more-readdir-3-errors.patch
|
||||
Patch6007: find-fix-memory-leak-in-mount-list-handling.patch
|
||||
Patch6008: find-fix-printf-h-for-arguments-with-one-or-more-tra.patch
|
||||
Patch6009: xargs-add-o-open-tty-option.patch
|
||||
Patch6010: find-avoid-strftime-s-non-portable-F-specifier.patch
|
||||
Patch6011: find-avoid-usage-in-more-error-cases.patch
|
||||
Patch6012: find-give-helpful-hint-for-unquoted-patterns-errors.patch
|
||||
Patch6013: find-avoid-buffer-overflow-with-printf-T.patch
|
||||
Patch6014: regexprops-fix-dangling-reference-to-the-ed-regular-.patch
|
||||
Patch6015: find-make-delete-honour-the-ignore_readdir_race-opti.patch
|
||||
Patch6016: Shorten-output-of-qmark_chars-after-replacing-a-mult.patch
|
||||
Patch6017: find-process-unreadable-directories-with-depth.patch
|
||||
Patch6018: ftsfind.c-avoid-buffer-overflow-in-D-code.patch
|
||||
Patch6019: find-fix-printf-Y-output-to-N-for-broken-links.patch
|
||||
Patch6020: print.c-move-else-into-ifdef-S_ISLNK.patch
|
||||
Patch6021: find-printf-Y-handle-ENOTDIR-also-as-broken-symlink.patch
|
||||
Patch6022: find-improve-warning-diagnostic-for-the-name-iname-w.patch
|
||||
Patch6023: find-make-pred_empty-safer-and-avoid-fd-leaks.patch
|
||||
Patch: findutils-4.4.2-xautofs.patch
|
||||
|
||||
Buildrequires: gcc autoconf gettext-devel texinfo libselinux-devel dejagnu
|
||||
|
||||
@ -80,9 +18,9 @@ Provides: /bin/find
|
||||
Provides: bundled(gnulib)
|
||||
|
||||
%description
|
||||
The GNU Find Utilities are the basic directory searching utilities of
|
||||
the GNU operating system. These programs are typically used in
|
||||
conjunction with other programs to provide modular and powerful
|
||||
The GNU Find Utilities are the basic directory searching utilities of
|
||||
the GNU operating system. These programs are typically used in
|
||||
conjunction with other programs to provide modular and powerful
|
||||
directory search and file locating capabilities to other commands.
|
||||
|
||||
The tools supplied with this package are:
|
||||
@ -97,7 +35,6 @@ xargs - build and execute command lines from standard input
|
||||
%prep
|
||||
%autosetup -n %{name}-%{version} -p1
|
||||
|
||||
# needed because of findutils-4.5.15-no-locate.patch
|
||||
autoreconf -fiv
|
||||
|
||||
%build
|
||||
@ -106,7 +43,7 @@ autoreconf -fiv
|
||||
%make_build
|
||||
|
||||
%check
|
||||
make check
|
||||
make check
|
||||
|
||||
%install
|
||||
%make_install
|
||||
@ -136,15 +73,27 @@ fi
|
||||
%license COPYING
|
||||
%{_bindir}/find
|
||||
%{_bindir}/xargs
|
||||
%exclude %{_bindir}/{locate,updatedb}
|
||||
%exclude %{_prefix}/libexec/frcode
|
||||
%exclude %{_libdir}/find
|
||||
%exclude %{_prefix}/lib/debug/usr/bin/locate*.debug
|
||||
%exclude %{_prefix}/lib/debug/usr/libexec/frcode*.debug
|
||||
|
||||
%files help
|
||||
%{_mandir}/man1/find.1*
|
||||
%{_mandir}/man1/xargs.1*
|
||||
%{_infodir}/find.info*
|
||||
%{_infodir}/find-maint.info.gz
|
||||
|
||||
%exclude %{_mandir}/man1/{locate.1*,updatedb.1*}
|
||||
%exclude %{_mandir}/man5/locatedb.5*
|
||||
|
||||
%changelog
|
||||
* Tue Dec 31 2019 openEuler Buildteam <buildteam@openeuler.org> - 2:4.7.0-1
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:update to 4.7.0
|
||||
|
||||
* Fri Dec 20 2019 openEuler Buildteam <buildteam@openeuler.org> - 2:4.6.0-5
|
||||
- Type:enhancement
|
||||
- ID:NA
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
From c7344d33587bc5b781b958315c643284e2e9cf18 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Sun, 8 Jul 2018 00:18:03 +0200
|
||||
Subject: [PATCH 178/224] ftsfind.c: avoid buffer overflow in -D code
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Reported by GCC 8.1.1:
|
||||
|
||||
ftsfind.c: In function ‘get_fts_info_name’:
|
||||
ftsfind.c:164:23: warning: ‘%d’ directive writing between 1 and 11 bytes into a region of size 9 [-Wformat-overflow=]
|
||||
sprintf (buf, "[%d]", info);
|
||||
^~
|
||||
ftsfind.c:164:7: note: ‘sprintf’ output between 4 and 14 bytes into a destination of size 10
|
||||
sprintf (buf, "[%d]", info);
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
* find/ftsfind.c (get_fts_info_name): Increase buffer from 10 to 14
|
||||
to be able to hold the 11-char string representation of the %d format,
|
||||
the surrounding '[' and ']', plus the terminating NULL character.
|
||||
---
|
||||
find/ftsfind.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/ftsfind.c b/find/ftsfind.c
|
||||
index 607ea8d3..57804950 100644
|
||||
--- a/find/ftsfind.c
|
||||
+++ b/find/ftsfind.c
|
||||
@@ -143,7 +143,7 @@ static void init_mounted_dev_list (void);
|
||||
static const char *
|
||||
get_fts_info_name (int info)
|
||||
{
|
||||
- static char buf[10];
|
||||
+ static char buf[14];
|
||||
switch (info)
|
||||
{
|
||||
HANDLECASE(FTS_D);
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,89 +0,0 @@
|
||||
From 7ce6b131573accf4fbc4b2c26794fb90f6b1a44e Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Sat, 2 Jan 2016 22:58:59 +0000
|
||||
Subject: [PATCH 025/224] lib: Update the width of the st_nlink field and fix
|
||||
some compiler warnings.
|
||||
|
||||
* lib/listfile.h (list_file): Make the relname parameter const.
|
||||
* lib/listfile.c (list_file): Make the relname parameter const.
|
||||
Remove the unused local variable inode_field_width. Update
|
||||
nlink_width with the greatest width of the st_nlink field, and
|
||||
print the field using the maximum width (as we do for other
|
||||
fields).
|
||||
---
|
||||
lib/listfile.c | 27 ++++++++++++++++++++++++---
|
||||
lib/listfile.h | 2 +-
|
||||
2 files changed, 25 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/lib/listfile.c b/lib/listfile.c
|
||||
index 4b7d4b22..c6c86091 100644
|
||||
--- a/lib/listfile.c
|
||||
+++ b/lib/listfile.c
|
||||
@@ -111,7 +111,7 @@ static bool print_num(FILE *stream, unsigned long num, int *width)
|
||||
void
|
||||
list_file (const char *name,
|
||||
int dir_fd,
|
||||
- char *relname,
|
||||
+ const char *relname,
|
||||
const struct stat *statp,
|
||||
time_t current_time,
|
||||
int output_block_size,
|
||||
@@ -126,7 +126,6 @@ list_file (const char *name,
|
||||
bool output_good = true;
|
||||
int chars_out;
|
||||
int failed_at = 000;
|
||||
- int inode_field_width;
|
||||
|
||||
#if HAVE_ST_DM_MODE
|
||||
/* Cray DMF: look at the file's migrated, not real, status */
|
||||
@@ -179,13 +178,35 @@ list_file (const char *name,
|
||||
output_good = false;
|
||||
failed_at = 250;
|
||||
}
|
||||
+ }
|
||||
+ if (output_good)
|
||||
+ {
|
||||
/* modebuf includes the space between the mode and the number of links,
|
||||
as the POSIX "optional alternate access method flag". */
|
||||
- if (fprintf (stream, "%s%3lu ", modebuf, (unsigned long) statp->st_nlink) < 0)
|
||||
+ if (fputs (modebuf, stream) < 0)
|
||||
+ {
|
||||
+ output_good = false;
|
||||
+ failed_at = 275;
|
||||
+ }
|
||||
+ }
|
||||
+ if (output_good)
|
||||
+ {
|
||||
+ /* This format used to end in a space, but the output of "ls"
|
||||
+ has only one space between the link count and the owner name,
|
||||
+ so we removed the trailing space. Happily this also makes it
|
||||
+ easier to update nlink_width. */
|
||||
+ chars_out = fprintf (stream, "%*lu",
|
||||
+ nlink_width, (unsigned long) statp->st_nlink);
|
||||
+ if (chars_out < 0)
|
||||
{
|
||||
output_good = false;
|
||||
failed_at = 300;
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ if (chars_out > nlink_width)
|
||||
+ nlink_width = chars_out;
|
||||
+ }
|
||||
}
|
||||
|
||||
if (output_good)
|
||||
diff --git a/lib/listfile.h b/lib/listfile.h
|
||||
index 9ee71a2d..2e151659 100644
|
||||
--- a/lib/listfile.h
|
||||
+++ b/lib/listfile.h
|
||||
@@ -19,5 +19,5 @@
|
||||
|
||||
#if !defined LISTFILE_H
|
||||
# define LISTFILE_H
|
||||
-void list_file (const char *name, int dir_fd, char *relname, const struct stat *statp, time_t current_time, int output_block_size, int literal_control_chars, FILE *stream);
|
||||
+void list_file (const char *name, int dir_fd, const char *relname, const struct stat *statp, time_t current_time, int output_block_size, int literal_control_chars, FILE *stream);
|
||||
#endif
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From f70469712165524b6ba92bf5dc60ad9be70546cb Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 1 Nov 2016 16:34:31 +0100
|
||||
Subject: [PATCH 078/224] maint: remove ChangeLog-2013 from distribution
|
||||
tarball
|
||||
|
||||
* Makefile.am (EXTRA_DIST): Remove ChangeLog-2013, as its content is
|
||||
shipped in the generated ChangeLog file.
|
||||
|
||||
Reported by Steve in
|
||||
http://lists.gnu.org/archive/html/bug-findutils/2016-10/msg00000.html
|
||||
---
|
||||
Makefile.am | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/Makefile.am b/Makefile.am
|
||||
index 410ee3d5..c31e7f03 100644
|
||||
--- a/Makefile.am
|
||||
+++ b/Makefile.am
|
||||
@@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS=gnits
|
||||
# readme-alpha
|
||||
AM_CFLAGS = $(WARN_CFLAGS)
|
||||
|
||||
-EXTRA_DIST = COPYING ChangeLog ChangeLog-2013 TODO config.h.in stamp-h.in \
|
||||
+EXTRA_DIST = COPYING ChangeLog TODO config.h.in stamp-h.in \
|
||||
THANKS bootstrap \
|
||||
tool-versions.txt README-hacking
|
||||
DISTCLEANFILES = tool-versions.txt
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,31 +0,0 @@
|
||||
From 88fc3a464476721c3f3631d56d441dff7c9e2479 Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Fri, 20 Jul 2018 10:27:56 +0200
|
||||
Subject: [PATCH 183/224] print.c: move 'else' into #ifdef S_ISLNK
|
||||
|
||||
* find/print.c (do_fprintf): Move the 'else' statment into the #ifdef'ed
|
||||
block to avoid compilation failure on systems without S_ISLNK (although
|
||||
it seems nobody tried to build on such a platform since 2005).
|
||||
|
||||
Bug introduced in commit 'FINDUTILS_4_2_23-1-63-g238d9547'.
|
||||
---
|
||||
find/print.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/find/print.c b/find/print.c
|
||||
index 545df96a..24bd9692 100644
|
||||
--- a/find/print.c
|
||||
+++ b/find/print.c
|
||||
@@ -1205,8 +1205,8 @@ do_fprintf (struct format_val *dest,
|
||||
checked_fprintf (dest, segment->text,
|
||||
mode_to_filetype (sbuf.st_mode & S_IFMT));
|
||||
}
|
||||
-#endif /* S_ISLNK */
|
||||
else
|
||||
+#endif /* S_ISLNK */
|
||||
{
|
||||
checked_fprintf (dest, segment->text,
|
||||
mode_to_filetype (stat_buf->st_mode & S_IFMT));
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,87 +0,0 @@
|
||||
From c83e75f548369e38e8f4c369717000552a8a1cdf Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Sun, 3 Jan 2016 23:20:54 +0000
|
||||
Subject: [PATCH 030/224] regexprops: Fix compiler warnings and update
|
||||
copyright years.
|
||||
|
||||
* lib/regexprops.c (newpara): Function parameter list should be
|
||||
declared as void in the function definition, instead of leaving it
|
||||
blank (C++ style). This fixes a GCC warning controlled by
|
||||
-Wstrict-prototypes.
|
||||
(beginenum): Likewise.
|
||||
(endenum): Likewise.
|
||||
(endtable): Likewise.
|
||||
(copying): Update copyright years.
|
||||
* doc/regexprops.texi: Update copyright years to match the output
|
||||
of regexprops.c.
|
||||
---
|
||||
doc/regexprops.texi | 4 ++--
|
||||
lib/regexprops.c | 12 ++++++------
|
||||
2 files changed, 8 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/doc/regexprops.texi b/doc/regexprops.texi
|
||||
index 537b64e0..897a492d 100644
|
||||
--- a/doc/regexprops.texi
|
||||
+++ b/doc/regexprops.texi
|
||||
@@ -1,5 +1,5 @@
|
||||
-@c Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003, 2004, 2005, 2006,
|
||||
-@c 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
+@c Copyright (C) 1994, 1996, 1998, 2000-2007, 2009-2011,
|
||||
+@c 2015-2016 Free Software Foundation, Inc.
|
||||
@c
|
||||
@c Permission is granted to copy, distribute and/or modify this document
|
||||
@c under the terms of the GNU Free Documentation License, Version 1.3 or
|
||||
diff --git a/lib/regexprops.c b/lib/regexprops.c
|
||||
index 3409b4c4..2327a646 100644
|
||||
--- a/lib/regexprops.c
|
||||
+++ b/lib/regexprops.c
|
||||
@@ -127,7 +127,7 @@ begintable_markup (char const *markup)
|
||||
}
|
||||
|
||||
static void
|
||||
-endtable ()
|
||||
+endtable (void)
|
||||
{
|
||||
newline ();
|
||||
directive ("@end table");
|
||||
@@ -135,7 +135,7 @@ endtable ()
|
||||
}
|
||||
|
||||
static void
|
||||
-beginenum ()
|
||||
+beginenum (void)
|
||||
{
|
||||
newline ();
|
||||
directive ("@enumerate");
|
||||
@@ -143,7 +143,7 @@ beginenum ()
|
||||
}
|
||||
|
||||
static void
|
||||
-endenum ()
|
||||
+endenum (void)
|
||||
{
|
||||
newline ();
|
||||
directive ("@end enumerate");
|
||||
@@ -151,7 +151,7 @@ endenum ()
|
||||
}
|
||||
|
||||
static void
|
||||
-newpara ()
|
||||
+newpara (void)
|
||||
{
|
||||
content ("\n\n");
|
||||
}
|
||||
@@ -453,8 +453,8 @@ copying (void)
|
||||
{
|
||||
static const char *copy_para[]=
|
||||
{
|
||||
- "Copyright (C) 1994, 1996, 1998, 2000, 2001, 2003, 2004, 2005, 2006,"
|
||||
- ,"2007, 2009, 2010, 2011 Free Software Foundation, Inc."
|
||||
+ "Copyright (C) 1994, 1996, 1998, 2000-2007, 2009-2011,"
|
||||
+ ,"2015-2016 Free Software Foundation, Inc."
|
||||
,""
|
||||
,"Permission is granted to copy, distribute and/or modify this document"
|
||||
,"under the terms of the GNU Free Documentation License, Version 1.3 or"
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,970 +0,0 @@
|
||||
From e2c673cbcdc325a3a2e9dd02169bb4a42c61bc48 Mon Sep 17 00:00:00 2001
|
||||
From: James Youngman <jay@gnu.org>
|
||||
Date: Mon, 13 Nov 2017 22:37:55 +0000
|
||||
Subject: [PATCH 144/224] regexprops: fix dangling reference to the `ed'
|
||||
regular expression dialect.
|
||||
|
||||
* lib/regextype.c (regex_map): Permute the entries to list POSIX
|
||||
dialects before other ones, so that we don't end up with a
|
||||
dangling reference to `ed' regular expressions when
|
||||
context=findutils. Remove trailing white space from the output.
|
||||
* doc/regexprops.texi: Regenerate this file, so that we no longer
|
||||
have a dangling reference to the `ed' dialect.
|
||||
* doc/find.texi (Regular Expressions): Point out the difference
|
||||
between Emacs regular expressions and findutils regular
|
||||
expressions: in findutils "." will match newline.
|
||||
* find/find.1: Likewise.
|
||||
* locate/locate.1: Likewise. Also document the --regextype option.
|
||||
---
|
||||
doc/find.texi | 7 +-
|
||||
doc/regexprops.texi | 376 ++++++++++++++++++++++++++++----------------
|
||||
find/find.1 | 4 +-
|
||||
lib/regexprops.c | 74 ++++-----
|
||||
lib/regextype.c | 14 +-
|
||||
locate/locate.1 | 14 +-
|
||||
6 files changed, 306 insertions(+), 183 deletions(-)
|
||||
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index 2731f0af..5573d29b 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -3917,8 +3917,11 @@ your locale setup affects the interpretation of regular expressions.
|
||||
|
||||
There are also several different types of regular expression, and
|
||||
these are interpreted differently. Normally, the type of regular
|
||||
-expression used by @code{find} and @code{locate} is the same as is
|
||||
-used in GNU Emacs. Both programs provide an option which allows you
|
||||
+expression used by @code{find} and @code{locate} is almost identical to
|
||||
+that used in GNU Emacs. The single difference is that in @code{find}
|
||||
+and @code{locate}, a @samp{.} will match a newline character.
|
||||
+
|
||||
+Both @code{find} and @code{locate} provide an option which allows you
|
||||
to select an alternative regular expression syntax; for @code{find}
|
||||
this is the @samp{-regextype} option, and for @code{locate} this is
|
||||
the @samp{--regextype} option.
|
||||
diff --git a/doc/regexprops.texi b/doc/regexprops.texi
|
||||
index 8fee88ae..0229460e 100644
|
||||
--- a/doc/regexprops.texi
|
||||
+++ b/doc/regexprops.texi
|
||||
@@ -11,15 +11,15 @@
|
||||
|
||||
@menu
|
||||
* findutils-default regular expression syntax::
|
||||
+* posix-awk regular expression syntax::
|
||||
+* posix-basic regular expression syntax::
|
||||
+* posix-egrep regular expression syntax::
|
||||
+* posix-extended regular expression syntax::
|
||||
* awk regular expression syntax::
|
||||
* egrep regular expression syntax::
|
||||
* emacs regular expression syntax::
|
||||
* gnu-awk regular expression syntax::
|
||||
* grep regular expression syntax::
|
||||
-* posix-awk regular expression syntax::
|
||||
-* posix-basic regular expression syntax::
|
||||
-* posix-egrep regular expression syntax::
|
||||
-* posix-extended regular expression syntax::
|
||||
@end menu
|
||||
|
||||
@node findutils-default regular expression syntax
|
||||
@@ -44,6 +44,7 @@ matches a @samp{?}.
|
||||
|
||||
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
|
||||
|
||||
+
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
|
||||
@@ -73,11 +74,10 @@ The alternation operator is @samp{\|}.
|
||||
The character @samp{^} only represents the beginning of a string when it appears:
|
||||
@enumerate
|
||||
|
||||
-@item
|
||||
-At the beginning of a regular expression
|
||||
+@item At the beginning of a regular expression
|
||||
+
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
|
||||
@item After the alternation operator @samp{\|}
|
||||
|
||||
@@ -89,8 +89,8 @@ The character @samp{$} only represents the end of a string when it appears:
|
||||
|
||||
@item At the end of a regular expression
|
||||
|
||||
-@item Before a close-group, signified by
|
||||
-@samp{\)}
|
||||
+@item Before a close-group, signified by @samp{\)}
|
||||
+
|
||||
@item Before the alternation operator @samp{\|}
|
||||
|
||||
@end enumerate
|
||||
@@ -101,8 +101,8 @@ The character @samp{$} only represents the end of a string when it appears:
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
+
|
||||
@item After the alternation operator @samp{\|}
|
||||
|
||||
@end enumerate
|
||||
@@ -113,8 +113,8 @@ The character @samp{$} only represents the end of a string when it appears:
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node awk regular expression syntax
|
||||
-@subsection @samp{awk} regular expression syntax
|
||||
+@node posix-awk regular expression syntax
|
||||
+@subsection @samp{posix-awk} regular expression syntax
|
||||
|
||||
|
||||
The character @samp{.} matches any single character except the null character.
|
||||
@@ -135,53 +135,57 @@ matches a @samp{?}.
|
||||
|
||||
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
|
||||
+
|
||||
GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
|
||||
|
||||
-Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit matches that digit.
|
||||
+
|
||||
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
|
||||
|
||||
The alternation operator is @samp{|}.
|
||||
|
||||
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
|
||||
-@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
+
|
||||
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
|
||||
@enumerate
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{(}
|
||||
+@item After an open-group, signified by @samp{(}
|
||||
+
|
||||
@item After the alternation operator @samp{|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-
|
||||
+Intervals are specified by @samp{@{} and @samp{@}}.
|
||||
+Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node egrep regular expression syntax
|
||||
-@subsection @samp{egrep} regular expression syntax
|
||||
+@node posix-basic regular expression syntax
|
||||
+@subsection @samp{posix-basic} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character.
|
||||
+The character @samp{.} matches any single character except the null character.
|
||||
|
||||
|
||||
@table @samp
|
||||
|
||||
-@item +
|
||||
-indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
-@item ?
|
||||
-indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
@item \+
|
||||
-matches a @samp{+}
|
||||
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
@item \?
|
||||
-matches a @samp{?}.
|
||||
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
+@item + and ?
|
||||
+match themselves.
|
||||
+
|
||||
@end table
|
||||
|
||||
|
||||
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
|
||||
+
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
|
||||
@@ -204,24 +208,59 @@ GNU extensions are supported:
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
|
||||
+Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
|
||||
|
||||
-The alternation operator is @samp{|}.
|
||||
+The alternation operator is @samp{\|}.
|
||||
|
||||
-The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
+The character @samp{^} only represents the beginning of a string when it appears:
|
||||
+@enumerate
|
||||
|
||||
-The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.
|
||||
+@item At the beginning of a regular expression
|
||||
+
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
+
|
||||
+
|
||||
+@item After the alternation operator @samp{\|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+The character @samp{$} only represents the end of a string when it appears:
|
||||
+@enumerate
|
||||
+
|
||||
+@item At the end of a regular expression
|
||||
+
|
||||
+@item Before a close-group, signified by @samp{\)}
|
||||
+
|
||||
+@item Before the alternation operator @samp{\|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+@samp{\*}, @samp{\+} and @samp{\?} are special at any point in a regular expression except:
|
||||
+@enumerate
|
||||
+
|
||||
+@item At the beginning of a regular expression
|
||||
+
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
+
|
||||
+@item After the alternation operator @samp{\|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+Intervals are specified by @samp{\@{} and @samp{\@}}.
|
||||
+Invalid intervals such as @samp{a\@{1z} are not accepted.
|
||||
|
||||
-Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node emacs regular expression syntax
|
||||
-@subsection @samp{emacs} regular expression syntax
|
||||
+@node posix-egrep regular expression syntax
|
||||
+@subsection @samp{posix-egrep} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character except newline.
|
||||
+The character @samp{.} matches any single character.
|
||||
|
||||
|
||||
@table @samp
|
||||
@@ -237,7 +276,8 @@ matches a @samp{?}.
|
||||
@end table
|
||||
|
||||
|
||||
-Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
|
||||
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
+
|
||||
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
@@ -261,58 +301,27 @@ GNU extensions are supported:
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
|
||||
-
|
||||
-The alternation operator is @samp{\|}.
|
||||
-
|
||||
-The character @samp{^} only represents the beginning of a string when it appears:
|
||||
-@enumerate
|
||||
-
|
||||
-@item
|
||||
-At the beginning of a regular expression
|
||||
-
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
-
|
||||
-@item After the alternation operator @samp{\|}
|
||||
-
|
||||
-@end enumerate
|
||||
-
|
||||
-
|
||||
-The character @samp{$} only represents the end of a string when it appears:
|
||||
-@enumerate
|
||||
-
|
||||
-@item At the end of a regular expression
|
||||
-
|
||||
-@item Before a close-group, signified by
|
||||
-@samp{\)}
|
||||
-@item Before the alternation operator @samp{\|}
|
||||
-
|
||||
-@end enumerate
|
||||
-
|
||||
-
|
||||
-@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
-@enumerate
|
||||
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
|
||||
|
||||
-@item At the beginning of a regular expression
|
||||
+The alternation operator is @samp{|}.
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
-@item After the alternation operator @samp{\|}
|
||||
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
|
||||
-@end enumerate
|
||||
|
||||
+The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.
|
||||
|
||||
|
||||
+Intervals are specified by @samp{@{} and @samp{@}}.
|
||||
+Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node gnu-awk regular expression syntax
|
||||
-@subsection @samp{gnu-awk} regular expression syntax
|
||||
+@node posix-extended regular expression syntax
|
||||
+@subsection @samp{posix-extended} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character.
|
||||
+The character @samp{.} matches any single character except the null character.
|
||||
|
||||
|
||||
@table @samp
|
||||
@@ -328,7 +337,8 @@ matches a @samp{?}.
|
||||
@end table
|
||||
|
||||
|
||||
-Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
+
|
||||
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
@@ -358,42 +368,101 @@ The alternation operator is @samp{|}.
|
||||
|
||||
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
|
||||
-@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
+
|
||||
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
|
||||
@enumerate
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{(}
|
||||
+@item After an open-group, signified by @samp{(}
|
||||
+
|
||||
@item After the alternation operator @samp{|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
+Intervals are specified by @samp{@{} and @samp{@}}.
|
||||
+Invalid intervals such as @samp{a@{1z} are not accepted.
|
||||
+
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node grep regular expression syntax
|
||||
-@subsection @samp{grep} regular expression syntax
|
||||
+@node awk regular expression syntax
|
||||
+@subsection @samp{awk} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character.
|
||||
+The character @samp{.} matches any single character except the null character.
|
||||
|
||||
|
||||
@table @samp
|
||||
|
||||
-@item \+
|
||||
+@item +
|
||||
indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
+@item ?
|
||||
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
+@item \+
|
||||
+matches a @samp{+}
|
||||
@item \?
|
||||
+matches a @samp{?}.
|
||||
+@end table
|
||||
+
|
||||
+
|
||||
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
+
|
||||
+
|
||||
+GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
|
||||
+
|
||||
+
|
||||
+Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit matches that digit.
|
||||
+
|
||||
+The alternation operator is @samp{|}.
|
||||
+
|
||||
+The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
+
|
||||
+
|
||||
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
+@enumerate
|
||||
+
|
||||
+@item At the beginning of a regular expression
|
||||
+
|
||||
+@item After an open-group, signified by @samp{(}
|
||||
+
|
||||
+@item After the alternation operator @samp{|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+
|
||||
+
|
||||
+The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
+
|
||||
+
|
||||
+@node egrep regular expression syntax
|
||||
+@subsection @samp{egrep} regular expression syntax
|
||||
+This is a synonym for posix-egrep.
|
||||
+@node emacs regular expression syntax
|
||||
+@subsection @samp{emacs} regular expression syntax
|
||||
+
|
||||
+
|
||||
+The character @samp{.} matches any single character except newline.
|
||||
+
|
||||
+
|
||||
+@table @samp
|
||||
+
|
||||
+@item +
|
||||
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
+@item ?
|
||||
indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
-@item + and ?
|
||||
-match themselves.
|
||||
+@item \+
|
||||
+matches a @samp{+}
|
||||
+@item \?
|
||||
+matches a @samp{?}.
|
||||
@end table
|
||||
|
||||
|
||||
-Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
+Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are ignored. Within square brackets, @samp{\} is taken literally. Character classes are not supported, so for example you would need to use @samp{[0-9]} instead of @samp{[[:digit:]]}.
|
||||
+
|
||||
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
@@ -424,13 +493,10 @@ The alternation operator is @samp{\|}.
|
||||
The character @samp{^} only represents the beginning of a string when it appears:
|
||||
@enumerate
|
||||
|
||||
-@item
|
||||
-At the beginning of a regular expression
|
||||
+@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
|
||||
-@item After a newline
|
||||
|
||||
@item After the alternation operator @samp{\|}
|
||||
|
||||
@@ -442,39 +508,35 @@ The character @samp{$} only represents the end of a string when it appears:
|
||||
|
||||
@item At the end of a regular expression
|
||||
|
||||
-@item Before a close-group, signified by
|
||||
-@samp{\)}
|
||||
-@item Before a newline
|
||||
+@item Before a close-group, signified by @samp{\)}
|
||||
|
||||
@item Before the alternation operator @samp{\|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-@samp{\*}, @samp{\+} and @samp{\?} are special at any point in a regular expression except:
|
||||
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
@enumerate
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{\(}
|
||||
-@item After a newline
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
|
||||
@item After the alternation operator @samp{\|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Intervals are specified by @samp{\@{} and @samp{\@}}. Invalid intervals such as @samp{a\@{1z} are not accepted.
|
||||
+
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node posix-awk regular expression syntax
|
||||
-@subsection @samp{posix-awk} regular expression syntax
|
||||
+@node gnu-awk regular expression syntax
|
||||
+@subsection @samp{gnu-awk} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character except the null character.
|
||||
+The character @samp{.} matches any single character.
|
||||
|
||||
|
||||
@table @samp
|
||||
@@ -492,7 +554,28 @@ matches a @samp{?}.
|
||||
|
||||
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} can be used to quote the following character. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
|
||||
-GNU extensions are not supported and so @samp{\w}, @samp{\W}, @samp{\<}, @samp{\>}, @samp{\b}, @samp{\B}, @samp{\`}, and @samp{\'} match @samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.
|
||||
+
|
||||
+GNU extensions are supported:
|
||||
+@enumerate
|
||||
+
|
||||
+@item @samp{\w} matches a character within a word
|
||||
+
|
||||
+@item @samp{\W} matches a character which is not within a word
|
||||
+
|
||||
+@item @samp{\<} matches the beginning of a word
|
||||
+
|
||||
+@item @samp{\>} matches the end of a word
|
||||
+
|
||||
+@item @samp{\b} matches a word boundary
|
||||
+
|
||||
+@item @samp{\B} matches characters which are not a word boundary
|
||||
+
|
||||
+@item @samp{\`} matches the beginning of the whole input
|
||||
+
|
||||
+@item @samp{\'} matches the end of the whole input
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
|
||||
Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
|
||||
|
||||
@@ -500,51 +583,47 @@ The alternation operator is @samp{|}.
|
||||
|
||||
The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
|
||||
-@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
|
||||
+
|
||||
+@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except:
|
||||
@enumerate
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{(}
|
||||
+@item After an open-group, signified by @samp{(}
|
||||
+
|
||||
@item After the alternation operator @samp{|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
+Intervals are specified by @samp{@{} and @samp{@}}.
|
||||
+Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\@{1}
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
|
||||
-@node posix-basic regular expression syntax
|
||||
-@subsection @samp{posix-basic} regular expression syntax
|
||||
-This is a synonym for ed.
|
||||
-@node posix-egrep regular expression syntax
|
||||
-@subsection @samp{posix-egrep} regular expression syntax
|
||||
-This is a synonym for egrep.
|
||||
-@node posix-extended regular expression syntax
|
||||
-@subsection @samp{posix-extended} regular expression syntax
|
||||
+@node grep regular expression syntax
|
||||
+@subsection @samp{grep} regular expression syntax
|
||||
|
||||
|
||||
-The character @samp{.} matches any single character except the null character.
|
||||
+The character @samp{.} matches any single character.
|
||||
|
||||
|
||||
@table @samp
|
||||
|
||||
-@item +
|
||||
-indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
-@item ?
|
||||
-indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
@item \+
|
||||
-matches a @samp{+}
|
||||
+indicates that the regular expression should match one or more occurrences of the previous atom or regexp.
|
||||
@item \?
|
||||
-matches a @samp{?}.
|
||||
+indicates that the regular expression should match zero or one occurrence of the previous atom or regexp.
|
||||
+@item + and ?
|
||||
+match themselves.
|
||||
+
|
||||
@end table
|
||||
|
||||
|
||||
Bracket expressions are used to match ranges of characters. Bracket expressions where the range is backward, for example @samp{[z-a]}, are invalid. Within square brackets, @samp{\} is taken literally. Character classes are supported; for example @samp{[[:digit:]]} will match a single decimal digit.
|
||||
|
||||
+
|
||||
GNU extensions are supported:
|
||||
@enumerate
|
||||
|
||||
@@ -567,25 +646,56 @@ GNU extensions are supported:
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Grouping is performed with parentheses @samp{()}. An unmatched @samp{)} matches just itself. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{(}.
|
||||
+Grouping is performed with backslashes followed by parentheses @samp{\(}, @samp{\)}. A backslash followed by a digit acts as a back-reference and matches the same thing as the previous grouped expression indicated by that number. For example @samp{\2} matches the second group expression. The order of group expressions is determined by the position of their opening parenthesis @samp{\(}.
|
||||
|
||||
-The alternation operator is @samp{|}.
|
||||
+The alternation operator is @samp{\|}.
|
||||
|
||||
-The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.
|
||||
+The character @samp{^} only represents the beginning of a string when it appears:
|
||||
+@enumerate
|
||||
|
||||
-@samp{*}, @samp{+} and @samp{?} are special at any point in a regular expression except the following places, where they are not allowed:
|
||||
+@item At the beginning of a regular expression
|
||||
+
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
+
|
||||
+
|
||||
+@item After a newline
|
||||
+
|
||||
+@item After the alternation operator @samp{\|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+The character @samp{$} only represents the end of a string when it appears:
|
||||
+@enumerate
|
||||
+
|
||||
+@item At the end of a regular expression
|
||||
+
|
||||
+@item Before a close-group, signified by @samp{\)}
|
||||
+
|
||||
+@item Before a newline
|
||||
+
|
||||
+@item Before the alternation operator @samp{\|}
|
||||
+
|
||||
+@end enumerate
|
||||
+
|
||||
+
|
||||
+@samp{\*}, @samp{\+} and @samp{\?} are special at any point in a regular expression except:
|
||||
@enumerate
|
||||
|
||||
@item At the beginning of a regular expression
|
||||
|
||||
-@item After an open-group, signified by
|
||||
-@samp{(}
|
||||
-@item After the alternation operator @samp{|}
|
||||
+@item After an open-group, signified by @samp{\(}
|
||||
+
|
||||
+@item After a newline
|
||||
+
|
||||
+@item After the alternation operator @samp{\|}
|
||||
|
||||
@end enumerate
|
||||
|
||||
|
||||
-Intervals are specified by @samp{@{} and @samp{@}}. Invalid intervals such as @samp{a@{1z} are not accepted.
|
||||
+Intervals are specified by @samp{\@{} and @samp{\@}}.
|
||||
+Invalid intervals such as @samp{a\@{1z} are not accepted.
|
||||
+
|
||||
|
||||
The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.
|
||||
|
||||
diff --git a/find/find.1 b/find/find.1
|
||||
index 06ddfa5b..8b1320c1 100644
|
||||
--- a/find/find.1
|
||||
+++ b/find/find.1
|
||||
@@ -879,8 +879,8 @@ on the whole path, not a search. For example, to match a file named
|
||||
`./fubar3', you can use the regular expression `.*bar.' or `.*b.*3',
|
||||
but not `f.*r3'. The regular expressions understood by
|
||||
.B find
|
||||
-are by default Emacs Regular Expressions, but this can be
|
||||
-changed with the
|
||||
+are by default Emacs Regular Expressions (except that `.' matches
|
||||
+newline), but this can be changed with the
|
||||
.B \-regextype
|
||||
option.
|
||||
|
||||
diff --git a/lib/regexprops.c b/lib/regexprops.c
|
||||
index fcbdd5db..b20b4a38 100644
|
||||
--- a/lib/regexprops.c
|
||||
+++ b/lib/regexprops.c
|
||||
@@ -78,8 +78,12 @@ directive (const char *s)
|
||||
static void
|
||||
comment (const char *s)
|
||||
{
|
||||
- directive ("@c ");
|
||||
- literal (s);
|
||||
+ directive ("@c");
|
||||
+ if (s[0])
|
||||
+ {
|
||||
+ literal (" ");
|
||||
+ literal (s);
|
||||
+ }
|
||||
newline ();
|
||||
}
|
||||
|
||||
@@ -175,7 +179,7 @@ describe_regex_syntax (int options)
|
||||
|
||||
content (" the null character");
|
||||
}
|
||||
- content (". ");
|
||||
+ content (".");
|
||||
newpara ();
|
||||
|
||||
if (!(options & RE_LIMITED_OPS))
|
||||
@@ -185,25 +189,25 @@ describe_regex_syntax (int options)
|
||||
{
|
||||
enum_item ("\\+");
|
||||
content ("indicates that the regular expression should match one"
|
||||
- " or more occurrences of the previous atom or regexp. ");
|
||||
+ " or more occurrences of the previous atom or regexp.");
|
||||
enum_item ("\\?");
|
||||
content ("indicates that the regular expression should match zero"
|
||||
- " or one occurrence of the previous atom or regexp. ");
|
||||
- enum_item ("+ and ? ");
|
||||
- content ("match themselves. ");
|
||||
+ " or one occurrence of the previous atom or regexp.");
|
||||
+ enum_item ("+ and ?");
|
||||
+ content ("match themselves.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
enum_item ("+");
|
||||
content ("indicates that the regular expression should match one"
|
||||
- " or more occurrences of the previous atom or regexp. ");
|
||||
+ " or more occurrences of the previous atom or regexp.");
|
||||
enum_item ("?");
|
||||
content ("indicates that the regular expression should match zero"
|
||||
- " or one occurrence of the previous atom or regexp. ");
|
||||
+ " or one occurrence of the previous atom or regexp.");
|
||||
enum_item ("\\+");
|
||||
literal ("matches a @samp{+}");
|
||||
enum_item ("\\?");
|
||||
- literal ("matches a @samp{?}. ");
|
||||
+ literal ("matches a @samp{?}.");
|
||||
}
|
||||
endtable ();
|
||||
}
|
||||
@@ -226,15 +230,15 @@ describe_regex_syntax (int options)
|
||||
|
||||
if (options & RE_CHAR_CLASSES)
|
||||
content ("Character classes are supported; for example "
|
||||
- "@samp{[[:digit:]]} will match a single decimal digit. ");
|
||||
+ "@samp{[[:digit:]]} will match a single decimal digit.\n");
|
||||
else
|
||||
literal ("Character classes are not supported, so for example "
|
||||
"you would need to use @samp{[0-9]} "
|
||||
- "instead of @samp{[[:digit:]]}. ");
|
||||
+ "instead of @samp{[[:digit:]]}.\n");
|
||||
|
||||
if (options & RE_HAT_LISTS_NOT_NEWLINE)
|
||||
{
|
||||
- literal ("Non-matching lists @samp{[^@dots{}]} do not ever match newline. ");
|
||||
+ literal ("Non-matching lists @samp{[^@dots{}]} do not ever match newline.\n");
|
||||
}
|
||||
newpara ();
|
||||
if (options & RE_NO_GNU_OPS)
|
||||
@@ -242,7 +246,7 @@ describe_regex_syntax (int options)
|
||||
content ("GNU extensions are not supported and so "
|
||||
"@samp{\\w}, @samp{\\W}, @samp{\\<}, @samp{\\>}, @samp{\\b}, @samp{\\B}, @samp{\\`}, and @samp{\\'} "
|
||||
"match "
|
||||
- "@samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively. ");
|
||||
+ "@samp{w}, @samp{W}, @samp{<}, @samp{>}, @samp{b}, @samp{B}, @samp{`}, and @samp{'} respectively.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -276,7 +280,7 @@ describe_regex_syntax (int options)
|
||||
|
||||
if (options & RE_NO_BK_REFS)
|
||||
{
|
||||
- content ("A backslash followed by a digit matches that digit. ");
|
||||
+ content ("A backslash followed by a digit matches that digit.");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -285,7 +289,7 @@ describe_regex_syntax (int options)
|
||||
literal ("@samp{(}");
|
||||
else
|
||||
literal ("@samp{\\(}");
|
||||
- content (". ");
|
||||
+ content (".");
|
||||
}
|
||||
|
||||
|
||||
@@ -293,29 +297,28 @@ describe_regex_syntax (int options)
|
||||
if (!(options & RE_LIMITED_OPS))
|
||||
{
|
||||
if (options & RE_NO_BK_VBAR)
|
||||
- literal ("The alternation operator is @samp{|}. ");
|
||||
+ literal ("The alternation operator is @samp{|}.");
|
||||
else
|
||||
- literal ("The alternation operator is @samp{\\|}. ");
|
||||
+ literal ("The alternation operator is @samp{\\|}.");
|
||||
}
|
||||
newpara ();
|
||||
|
||||
if (options & RE_CONTEXT_INDEP_ANCHORS)
|
||||
{
|
||||
- literal ("The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified. ");
|
||||
+ literal ("The characters @samp{^} and @samp{$} always represent the beginning and end of a string respectively, except within square brackets. Within brackets, @samp{^} can be used to invert the membership of the character class being specified.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
literal ("The character @samp{^} only represents the beginning of a string when it appears:");
|
||||
beginenum ();
|
||||
- enum_item ("\nAt the beginning of a regular expression");
|
||||
- enum_item ("After an open-group, signified by ");
|
||||
+ enum_item ("At the beginning of a regular expression");
|
||||
if (options & RE_NO_BK_PARENS)
|
||||
{
|
||||
- literal ("@samp{(}");
|
||||
+ enum_item ("After an open-group, signified by @samp{(}");
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("@samp{\\(}");
|
||||
+ enum_item ("After an open-group, signified by @samp{\\(}");
|
||||
}
|
||||
newline ();
|
||||
if (!(options & RE_LIMITED_OPS))
|
||||
@@ -334,14 +337,13 @@ describe_regex_syntax (int options)
|
||||
literal ("The character @samp{$} only represents the end of a string when it appears:");
|
||||
beginenum ();
|
||||
enum_item ("At the end of a regular expression");
|
||||
- enum_item ("Before a close-group, signified by ");
|
||||
if (options & RE_NO_BK_PARENS)
|
||||
{
|
||||
- literal ("@samp{)}");
|
||||
+ enum_item ("Before a close-group, signified by @samp{)}");
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("@samp{\\)}");
|
||||
+ enum_item ("Before a close-group, signified by @samp{\\)}");
|
||||
}
|
||||
if (!(options & RE_LIMITED_OPS))
|
||||
{
|
||||
@@ -361,7 +363,7 @@ describe_regex_syntax (int options)
|
||||
if ((options & RE_CONTEXT_INDEP_OPS)
|
||||
&& !(options & RE_CONTEXT_INVALID_OPS))
|
||||
{
|
||||
- literal ("The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression. ");
|
||||
+ literal ("The characters @samp{*}, @samp{+} and @samp{?} are special anywhere in a regular expression.\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -381,14 +383,13 @@ describe_regex_syntax (int options)
|
||||
|
||||
beginenum ();
|
||||
enum_item ("At the beginning of a regular expression");
|
||||
- enum_item ("After an open-group, signified by ");
|
||||
if (options & RE_NO_BK_PARENS)
|
||||
{
|
||||
- literal ("@samp{(}");
|
||||
+ enum_item ("After an open-group, signified by @samp{(}");
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("@samp{\\(}");
|
||||
+ enum_item ("After an open-group, signified by @samp{\\(}");
|
||||
}
|
||||
if (!(options & RE_LIMITED_OPS))
|
||||
{
|
||||
@@ -410,39 +411,38 @@ describe_regex_syntax (int options)
|
||||
{
|
||||
if (options & RE_NO_BK_BRACES)
|
||||
{
|
||||
- literal ("Intervals are specified by @samp{@{} and @samp{@}}. ");
|
||||
+ literal ("Intervals are specified by @samp{@{} and @samp{@}}.\n");
|
||||
if (options & RE_INVALID_INTERVAL_ORD)
|
||||
{
|
||||
literal ("Invalid intervals are treated as literals, for example @samp{a@{1} is treated as @samp{a\\@{1}");
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("Invalid intervals such as @samp{a@{1z} are not accepted. ");
|
||||
+ literal ("Invalid intervals such as @samp{a@{1z} are not accepted.\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("Intervals are specified by @samp{\\@{} and @samp{\\@}}. ");
|
||||
+ literal ("Intervals are specified by @samp{\\@{} and @samp{\\@}}.\n");
|
||||
if (options & RE_INVALID_INTERVAL_ORD)
|
||||
{
|
||||
literal ("Invalid intervals are treated as literals, for example @samp{a\\@{1} is treated as @samp{a@{1}");
|
||||
}
|
||||
else
|
||||
{
|
||||
- literal ("Invalid intervals such as @samp{a\\@{1z} are not accepted. ");
|
||||
+ literal ("Invalid intervals such as @samp{a\\@{1z} are not accepted.\n");
|
||||
}
|
||||
}
|
||||
-
|
||||
}
|
||||
|
||||
newpara ();
|
||||
if (options & RE_NO_POSIX_BACKTRACKING)
|
||||
{
|
||||
- content ("Matching succeeds as soon as the whole pattern is matched, meaning that the result may not be the longest possible match. ");
|
||||
+ content ("Matching succeeds as soon as the whole pattern is matched, meaning that the result may not be the longest possible match.");
|
||||
}
|
||||
else
|
||||
{
|
||||
- content ("The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups. ");
|
||||
+ content ("The longest possible match is returned; this applies to the regular expression as a whole and (subject to this constraint) to subexpressions within groups.");
|
||||
}
|
||||
newpara ();
|
||||
}
|
||||
diff --git a/lib/regextype.c b/lib/regextype.c
|
||||
index 8a7347dc..89416ebd 100644
|
||||
--- a/lib/regextype.c
|
||||
+++ b/lib/regextype.c
|
||||
@@ -56,17 +56,19 @@ struct tagRegexTypeMap
|
||||
struct tagRegexTypeMap regex_map[] =
|
||||
{
|
||||
{ "findutils-default", CONTEXT_FINDUTILS, RE_SYNTAX_EMACS|RE_DOT_NEWLINE },
|
||||
+
|
||||
+ { "posix-awk", CONTEXT_ALL, RE_SYNTAX_POSIX_AWK },
|
||||
+ { "posix-basic", CONTEXT_ALL, RE_SYNTAX_POSIX_BASIC },
|
||||
+ { "posix-egrep", CONTEXT_ALL, RE_SYNTAX_POSIX_EGREP },
|
||||
+ { "posix-extended", CONTEXT_ALL, RE_SYNTAX_POSIX_EXTENDED },
|
||||
+ { "posix-minimal-basic", CONTEXT_GENERIC, RE_SYNTAX_POSIX_MINIMAL_BASIC },
|
||||
+
|
||||
{ "awk", CONTEXT_ALL, RE_SYNTAX_AWK },
|
||||
- { "egrep", CONTEXT_ALL, RE_SYNTAX_EGREP },
|
||||
{ "ed", CONTEXT_GENERIC, RE_SYNTAX_ED },
|
||||
+ { "egrep", CONTEXT_ALL, RE_SYNTAX_EGREP },
|
||||
{ "emacs", CONTEXT_ALL, RE_SYNTAX_EMACS },
|
||||
{ "gnu-awk", CONTEXT_ALL, RE_SYNTAX_GNU_AWK },
|
||||
{ "grep", CONTEXT_ALL, RE_SYNTAX_GREP },
|
||||
- { "posix-awk", CONTEXT_ALL, RE_SYNTAX_POSIX_AWK },
|
||||
- { "posix-basic", CONTEXT_ALL, RE_SYNTAX_POSIX_BASIC },
|
||||
- { "posix-egrep", CONTEXT_ALL, RE_SYNTAX_POSIX_EGREP },
|
||||
- { "posix-extended", CONTEXT_ALL, RE_SYNTAX_POSIX_EXTENDED },
|
||||
- { "posix-minimal-basic", CONTEXT_GENERIC, RE_SYNTAX_POSIX_MINIMAL_BASIC },
|
||||
{ "sed", CONTEXT_GENERIC, RE_SYNTAX_SED },
|
||||
/* ,{ "posix-common", CONTEXT_GENERIC, _RE_SYNTAX_POSIX_COMMON } */
|
||||
};
|
||||
--
|
||||
2.19.1
|
||||
|
||||
@ -1,250 +0,0 @@
|
||||
From 40cd25147b4461979c0d992299f2c101f9034f7a Mon Sep 17 00:00:00 2001
|
||||
From: Bernhard Voelker <mail@bernhard-voelker.de>
|
||||
Date: Tue, 6 Jun 2017 08:19:29 +0200
|
||||
Subject: [PATCH 101/224] xargs: add -o, --open-tty option
|
||||
|
||||
This option is available in the xargs implementation of FreeBSD, NetBSD,
|
||||
OpenBSD and in the Apple variant. Add it for compatibility.
|
||||
|
||||
* xargs/xargs.c (open_tty): Add static flag for the new option.
|
||||
(longopts): Add member.
|
||||
(main): Handle the 'o' case in the getopt_long() loop.
|
||||
(prep_child_for_exec): Redirect stdin of the child to /dev/tty when
|
||||
the -o option is given. Furthermore, move the just-opened file
|
||||
descriptor to STDIN_FILENO.
|
||||
(usage): Document the new option.
|
||||
* bootstrap.conf (gnulib_modules): Add dup2.
|
||||
* xargs/xargs.1 (SYNOPSIS): Replace the too-long list of options by
|
||||
"[options]" - they are listed later anyway.
|
||||
(OPTIONS): Document the new option.
|
||||
(STANDARDS CONFORMANCE): Mention that the -o option is an extension.
|
||||
* doc/find.texi (xargs options): Document the new option.
|
||||
(Invoking the shell from xargs): Amend the explanation of the
|
||||
redirection example with a note about the -o option.
|
||||
(Viewing And Editing): Likewise.
|
||||
(Error Messages From xargs): Add the message when dup2() fails.
|
||||
(NEWS): Mention the new option.
|
||||
|
||||
Fixes http://savannah.gnu.org/bugs/?51151
|
||||
---
|
||||
NEWS | 4 ++++
|
||||
bootstrap.conf | 1 +
|
||||
doc/find.texi | 24 ++++++++++++++++++++++++
|
||||
xargs/xargs.1 | 41 +++++++++++++----------------------------
|
||||
xargs/xargs.c | 33 ++++++++++++++++++++++++++-------
|
||||
5 files changed, 68 insertions(+), 35 deletions(-)
|
||||
|
||||
diff --git a/doc/find.texi b/doc/find.texi
|
||||
index 24d8ef99..4516b64c 100644
|
||||
--- a/doc/find.texi
|
||||
+++ b/doc/find.texi
|
||||
@@ -3746,6 +3746,17 @@ Use at most @var{max-args} arguments per command line. Fewer than
|
||||
option) is exceeded, unless the @samp{-x} option is given, in which
|
||||
case @code{xargs} will exit.
|
||||
|
||||
+@item --open-tty
|
||||
+@itemx -o
|
||||
+Reopen stdin as @file{/dev/tty} in the child process before executing
|
||||
+the command, thus allowing that command to be associated to the terminal
|
||||
+while @code{xargs} reads from a different stream, e.g. from a pipe.
|
||||
+This is useful if you want @code{xargs} to run an interactive application.
|
||||
+@example
|
||||
+grep -lz PATTERN * | xargs -0o vi
|
||||
+@end example
|
||||
+
|
||||
+
|
||||
@item --interactive
|
||||
@itemx -p
|
||||
Prompt the user about whether to run each command line and read a line
|
||||
@@ -3877,6 +3888,10 @@ Therefore instead of keeping a @code{sh} process around for no reason,
|
||||
we just arrange for the subshell to exec Emacs, saving an extra
|
||||
process creation.
|
||||
|
||||
+Although GNU @code{xargs} and the implementations on some other platforms
|
||||
+like BSD support the @samp{-o} option to achieve the same, the above is
|
||||
+the portable way to redirect stdin to @file{/dev/tty}.
|
||||
+
|
||||
Sometimes, though, it can be helpful to keep the shell process around:
|
||||
|
||||
@example
|
||||
@@ -4050,6 +4065,10 @@ protect the @code{$@@} against expansion by your interactive shell
|
||||
nothing). The capitalised @samp{Emacs} on the command line is used as
|
||||
@code{$0} by the shell that @code{xargs} launches.
|
||||
|
||||
+Please note that the implementations in GNU @code{xargs} and at least BSD
|
||||
+support the @samp{-o} option as extension to achieve the same, while the
|
||||
+above is the portable way to redirect stdin to @file{/dev/tty}.
|
||||
+
|
||||
@node Archiving
|
||||
@section Archiving
|
||||
|
||||
@@ -5564,6 +5583,11 @@ signals to increase or decrease the parallelism of its processing.
|
||||
If you don't plan to send it those signals, this warning can be ignored
|
||||
(though if you're a programmer, you may want to help us figure out
|
||||
why @code{xargs} is confused by your operating system).
|
||||
+
|
||||
+@item failed to redirect standard input of the child process
|
||||
+@code{xargs} redirects the stdin stream of the command to be run to either
|
||||
+@file{/dev/null} or to @file{/dev/tty} for the @samp{-o} option.
|
||||
+See the manual of the system call @code{dup2(2)}.
|
||||
@end table
|
||||
|
||||
@node Error Messages From locate
|
||||
diff --git a/xargs/xargs.1 b/xargs/xargs.1
|
||||
index 68377868..f66dbc05 100644
|
||||
--- a/xargs/xargs.1
|
||||
+++ b/xargs/xargs.1
|
||||
@@ -4,34 +4,7 @@ xargs \- build and execute command lines from standard input
|
||||
.SH SYNOPSIS
|
||||
.B xargs
|
||||
.nh
|
||||
-[\fB\-0prtx\fR]
|
||||
-[\fB\-E \fIeof-str\fR]
|
||||
-[\fB\-e\fR[\fIeof-str\fR]]
|
||||
-[\fB\-\-eof\fR[=\fIeof-str\fR]]
|
||||
-[\fB\-\-null\fR]
|
||||
-[\fB\-d \fIdelimiter\fR]
|
||||
-[\fB\-\-delimiter \fIdelimiter\fR]
|
||||
-[\fB\-I \fIreplace-str\fR]
|
||||
-[\fB\-i\fR[\fIreplace-str\fR]]
|
||||
-[\fB\-\-replace\fR[=\fIreplace-str\fR]]
|
||||
-[\fB\-l\fR[\fImax-lines\fR]]
|
||||
-[\fB\-L \fImax-lines\fR]
|
||||
-[\fB\-\-max\-lines\fR[=\fImax-lines\fR]]
|
||||
-[\fB\-n \fImax-args\fR]
|
||||
-[\fB\-\-max\-args\fR=\fImax-args\fR]
|
||||
-[\fB\-s \fImax-chars\fR]
|
||||
-[\fB\-\-max\-chars\fR=\fImax-chars\fR]
|
||||
-[\fB\-P \fImax-procs\fR]
|
||||
-[\fB\-\-max\-procs\fR=\fImax-procs\fR]
|
||||
-[\fB\-\-process\-slot\-var\fR=\fIname\fR]
|
||||
-[\fB\-\-interactive\fR]
|
||||
-[\fB\-\-verbose\fR]
|
||||
-[\fB\-\-exit\fR]
|
||||
-[\fB\-\-no\-run\-if\-empty\fR]
|
||||
-[\fB\-\-arg\-file\fR=\fIfile\fR]
|
||||
-[\fB\-\-show\-limits\fR]
|
||||
-[\fB\-\-version\fR]
|
||||
-[\fB\-\-help\fR]
|
||||
+[\fIoptions\fR]
|
||||
[\fIcommand\fR [\fIinitial-arguments\fR]]
|
||||
.hy
|
||||
.SH DESCRIPTION
|
||||
@@ -252,6 +225,15 @@ arrange for each process to produce a separate output file (or
|
||||
otherwise use separate resources).
|
||||
.TP
|
||||
.PD
|
||||
+.B \-o, \-\-open\-tty
|
||||
+Reopen stdin as
|
||||
+.I /dev/tty
|
||||
+in the child process before executing the command. This is useful if
|
||||
+you want
|
||||
+.B xargs
|
||||
+to run an interactive application.
|
||||
+.TP
|
||||
+.PD
|
||||
.B \-p, \-\-interactive
|
||||
Prompt the user about whether to run each command line and read a line
|
||||
from the terminal. Only run the command line if the response starts
|
||||
@@ -404,6 +386,9 @@ The \-l and \-i options appear in the 1997 version of the POSIX
|
||||
standard, but do not appear in the 2004 version of the standard.
|
||||
Therefore you should use \-L and \-I instead, respectively.
|
||||
.P
|
||||
+The \-o option is an extension to the POSIX standard for better
|
||||
+compatibility with BSD.
|
||||
+.P
|
||||
The POSIX standard allows implementations to have a limit on the size
|
||||
of arguments to the
|
||||
.B exec
|
||||
diff --git a/xargs/xargs.c b/xargs/xargs.c
|
||||
index 5cf8c131..a2917e48 100644
|
||||
--- a/xargs/xargs.c
|
||||
+++ b/xargs/xargs.c
|
||||
@@ -151,6 +151,9 @@ static volatile int child_error = EXIT_SUCCESS;
|
||||
|
||||
static volatile int original_exit_value;
|
||||
|
||||
+/* If true, open /dev/tty in the child process before executing the command. */
|
||||
+static bool open_tty = false; /* option -o */
|
||||
+
|
||||
/* If true, print each command on stderr before executing it. */
|
||||
static bool print_command = false; /* Option -t */
|
||||
|
||||
@@ -185,6 +188,7 @@ static struct option const longopts[] =
|
||||
{"replace", optional_argument, NULL, 'I'},
|
||||
{"max-lines", optional_argument, NULL, 'l'},
|
||||
{"max-args", required_argument, NULL, 'n'},
|
||||
+ {"open-tty", no_argument, NULL, 'o'},
|
||||
{"interactive", no_argument, NULL, 'p'},
|
||||
{"no-run-if-empty", no_argument, NULL, 'r'},
|
||||
{"max-chars", required_argument, NULL, 's'},
|
||||
@@ -509,7 +513,7 @@ main (int argc, char **argv)
|
||||
bc_use_sensible_arg_max (&bc_ctl);
|
||||
}
|
||||
|
||||
- while ((optc = getopt_long (argc, argv, "+0a:E:e::i::I:l::L:n:prs:txP:d:",
|
||||
+ while ((optc = getopt_long (argc, argv, "+0a:E:e::i::I:l::L:n:oprs:txP:d:",
|
||||
longopts, &option_index)) != -1)
|
||||
{
|
||||
switch (optc)
|
||||
@@ -608,6 +612,10 @@ main (int argc, char **argv)
|
||||
bc_ctl.exit_if_size_exceeded = true;
|
||||
break;
|
||||
|
||||
+ case 'o':
|
||||
+ open_tty = true;
|
||||
+ break;
|
||||
+
|
||||
case 'p':
|
||||
query_before_executing = true;
|
||||
print_command = true;
|
||||
@@ -1185,22 +1193,30 @@ prep_child_for_exec (void)
|
||||
unsigned int slot = add_proc (0);
|
||||
set_slot_var (slot);
|
||||
|
||||
- if (!keep_stdin)
|
||||
+ if (!keep_stdin || open_tty)
|
||||
{
|
||||
- const char inputfile[] = "/dev/null";
|
||||
- /* fprintf (stderr, "attaching stdin to /dev/null\n"); */
|
||||
+ int fd;
|
||||
+ const char *inputfile = open_tty ? "/dev/tty" : "/dev/null";
|
||||
|
||||
close (0);
|
||||
- if (open (inputfile, O_RDONLY) < 0)
|
||||
+ if ((fd = open (inputfile, O_RDONLY)) < 0)
|
||||
{
|
||||
- /* This is not entirely fatal, since
|
||||
+ /* Treat a failure to open /dev/tty as fatal.
|
||||
+ * The other case is not entirely fatal, since
|
||||
* executing the child with a closed
|
||||
* stdin is almost as good as executing it
|
||||
* with its stdin attached to /dev/null.
|
||||
*/
|
||||
- error (0, errno, "%s",
|
||||
+ error (open_tty ? EXIT_FAILURE : 0, errno, "%s",
|
||||
quotearg_n_style (0, locale_quoting_style, inputfile));
|
||||
}
|
||||
+ if (STDIN_FILENO < fd)
|
||||
+ {
|
||||
+ if (dup2(fd, STDIN_FILENO) != 0)
|
||||
+ error (EXIT_FAILURE, errno,
|
||||
+ _("failed to redirect standard input of the child process"));
|
||||
+ close(fd);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1676,6 +1692,9 @@ usage (int status)
|
||||
HTL (_(" -l[MAX-LINES] similar to -L but defaults to at most one non-\n"
|
||||
" blank input line if MAX-LINES is not specified\n"));
|
||||
HTL (_(" -n, --max-args=MAX-ARGS use at most MAX-ARGS arguments per command line\n"));
|
||||
+ HTL (_(" -o, --open-tty Reopen stdin as /dev/tty in the child process\n"
|
||||
+ " before executing the command; useful to run an\n"
|
||||
+ " interactive application.\n"));
|
||||
HTL (_(" -P, --max-procs=MAX-PROCS run at most MAX-PROCS processes at a time\n"));
|
||||
HTL (_(" -p, --interactive prompt before running commands\n"));
|
||||
HTL (_(" --process-slot-var=VAR set environment variable VAR in child processes\n"));
|
||||
--
|
||||
2.19.1
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user