From 4f344501ea14aec7446f720d4b79428f281da284 Mon Sep 17 00:00:00 2001 From: Phil Miller Date: Mon, 29 Dec 2014 17:38:24 -0600 Subject: [PATCH 2/2] Add a -sort option to use fts's sorted traversal functionality * find/defs.h (struct options): Add a 'sort' flag. * find/util.c (options_default): Disable sorting by default. * find/parser.c: Add a function parse_sort() to recognize the command-line option and set the 'sort' flag accordingly. * find/ftsfind.c (find): When the 'sort' flag is set, tell fts to sort files according to their path name * find/find.1: Document -sort option and why it would be used Signed-off-by: Phil Miller --- find/defs.h | 3 +++ find/find.1 | 9 +++++++++ find/ftsfind.c | 8 ++++++-- find/parser.c | 12 ++++++++++++ find/util.c | 1 + 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/find/defs.h b/find/defs.h index caccd2b..0bbc956 100644 --- a/find/defs.h +++ b/find/defs.h @@ -544,6 +544,9 @@ struct options */ bool explicit_depth; + /* Sort directory contents in some consistent order before processing them */ + bool sort; + /* If >=0, don't descend more than this many levels of subdirectories. */ int maxdepth; diff --git a/find/find.1 b/find/find.1 index f49218e..c9aef56 100644 --- a/find/find.1 +++ b/find/find.1 @@ -447,6 +447,15 @@ tests which occur later on the command line. Currently-implemented types are emacs (this is the default), posix-awk, posix-basic, posix-egrep and posix-extended. +.IP "\-sort" +Process each directory's contents in a consistent sorted order. This +allows incremental output, whereas piping the output of +.B find +to +.B sort +requires waiting until all files are listed and buffering the entire +list before sorting and producing any output. + .IP "\-version, \-\-version" Print the \fBfind\fR version number and exit. diff --git a/find/ftsfind.c b/find/ftsfind.c index 1cdf44c..2ddf83f 100644 --- a/find/ftsfind.c +++ b/find/ftsfind.c @@ -520,7 +520,11 @@ consider_visiting (FTS *p, FTSENT *ent) } } - +static int +strcmp_ftsname (const FTSENT **f1, const FTSENT **f2) +{ + return strcmp((*f1)->fts_name, (*f2)->fts_name); +} static bool find (char *arg) @@ -553,7 +557,7 @@ find (char *arg) if (options.stay_on_filesystem) ftsoptions |= FTS_XDEV; - p = fts_open (arglist, ftsoptions, NULL); + p = fts_open (arglist, ftsoptions, options.sort ? strcmp_ftsname : NULL); if (NULL == p) { error (0, errno, _("cannot search %s"), diff --git a/find/parser.c b/find/parser.c index dc6c47c..13ac7c5 100644 --- a/find/parser.c +++ b/find/parser.c @@ -137,6 +137,7 @@ static bool parse_regex (const struct parser_table*, char *argv[], int * static bool parse_regextype (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_samefile (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_size (const struct parser_table*, char *argv[], int *arg_ptr); +static bool parse_sort (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_time (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_true (const struct parser_table*, char *argv[], int *arg_ptr); static bool parse_type (const struct parser_table*, char *argv[], int *arg_ptr); @@ -298,6 +299,7 @@ static struct parser_table const parse_table[] = PARSE_OPTION ("show-control-chars", show_control_chars), /* GNU, 4.3.0+ */ #endif PARSE_TEST ("size", size), /* POSIX */ + PARSE_OPTION ("sort", sort), /* GNU */ PARSE_TEST ("type", type), /* POSIX */ PARSE_TEST ("uid", uid), /* GNU */ PARSE_TEST ("used", used), /* GNU */ @@ -887,6 +889,16 @@ parse_delete (const struct parser_table* entry, char *argv[], int *arg_ptr) } static bool +parse_sort (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + (void) entry; + (void) argv; + + options.sort = true; + return parse_noop (entry, argv, arg_ptr); +} + +static bool parse_depth (const struct parser_table* entry, char **argv, int *arg_ptr) { (void) entry; diff --git a/find/util.c b/find/util.c index eb5efa2..7513ea2 100644 --- a/find/util.c +++ b/find/util.c @@ -1006,6 +1006,7 @@ set_option_defaults (struct options *p) p->do_dir_first = true; p->explicit_depth = false; + p->sort = false; p->maxdepth = p->mindepth = -1; p->start_time = now (); -- 2.1.4