summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/findutils/findutils-4.4.2
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-extended/findutils/findutils-4.4.2')
-rw-r--r--meta/recipes-extended/findutils/findutils-4.4.2/01-27017.patch779
-rw-r--r--meta/recipes-extended/findutils/findutils-4.4.2/02-28824.patch292
-rw-r--r--meta/recipes-extended/findutils/findutils-4.4.2/03-28872.patch56
3 files changed, 1127 insertions, 0 deletions
diff --git a/meta/recipes-extended/findutils/findutils-4.4.2/01-27017.patch b/meta/recipes-extended/findutils/findutils-4.4.2/01-27017.patch
new file mode 100644
index 0000000000..b61f67b12d
--- /dev/null
+++ b/meta/recipes-extended/findutils/findutils-4.4.2/01-27017.patch
@@ -0,0 +1,779 @@
1commit af974034b68bf59337c7a384e488a518a77dfecd
2Author: James Youngman <jay@gnu.org>
3Date: Sat Jul 11 19:55:27 2009 +0100
4
5 Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit coredump.
6
7 Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit
8 coredumps.
9 * find/tree.c (set_new_parent): Initialise struct
10 predicate->arg_text to NULL (instead of leaving it uninitialised).
11 (get_new_pred_noarg): Likewise.
12 (get_new_pred): Initialise predicate->arg_text to
13 "ThisShouldBeSetToSomethingElse" to make it easier to notice
14 bugs.
15 (get_new_pred_chk_op): Use get_new_pred_noarg.
16 (print_predicate): Use an if statement instead of
17 two ternary operators.
18 * find/util.c (insert_primary_withpred): Accept new argument, arg,
19 being the argument (if any) of this predicate. Pass it to
20 get_new_pred_chk_op.
21 (insert_primary): Likewise (pass arg to insert_primary_withpred).
22 (insert_primary_noarg): New function; calls insert_primary with
23 arg=NULL.
24 * find/parser.c (collect_arg_stat_info): Add an output parameter;
25 the filename from which we collected the stat information.
26 (parse_closeparen, parse_delete, parse_and, parse_or,
27 parse_comma): Use get_new_pred_noarg.
28 (parse_cnewer, parse_newer, parse_anewer): Use new
29 collect_arg_stat_info and insert_primary interface.
30 (parse_print, parse_prune, parse_nouser, parse_empty): Use
31 insert_primary_noarg.
32 (parse_accesscheck, parse_false): Use insert_primary_noarg.
33 (parse_used, parse_iname, parse_fprint, insert_fprint,
34 parse_fstype, parse_ilname): Use new collect_arg and
35 insert_primary interfaces.
36 (parse_ipath, parse_lname, do_parse_xmin, parse_name, parse_path,
37 parse_perm, parse_size, parse_user, parse_time): Use new
38 collect_arg and insert_primary_withpred interface.
39 (parse_negate, parse_openparen): Use new get_new_pred_chk_op interface.
40 (parse_newerXY, parse_nogroup): Use new insert_primary interface.
41 (insert_regex, parse_samefile): Use new insert_primary_withpred
42 interface.
43 (insert_type, insert_fprintf, new_insert_exec_ok, insert_num): Use
44 new insert_primary_withpred interface.
45 * find/defs.h (struct predicate.arg_text): make const.
46 Add declarations for new function get_new_pred_noarg and
47 insert_primary_noarg. Add 'arg' parameter to get_new_pred_chk_op
48 and insert_primary_withpred.
49
50diff --git a/ChangeLog b/ChangeLog
51index 6e346b8..e8ba0f8 100644
52--- a/ChangeLog
53+++ b/ChangeLog
54@@ -1,0 +1,45 @@
55+2009-07-11 James Youngman <jay@gnu.org>
56+
57+ Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit
58+ coredumps.
59+ * find/tree.c (set_new_parent): Initialise struct
60+ predicate->arg_text to NULL (instead of leaving it uninitialised).
61+ (get_new_pred_noarg): Likewise.
62+ (get_new_pred): Initialise predicate->arg_text to
63+ "ThisShouldBeSetToSomethingElse" to make it easier to notice
64+ bugs.
65+ (get_new_pred_chk_op): Use get_new_pred_noarg.
66+ (print_predicate): Use an if statement instead of
67+ two ternary operators.
68+ * find/util.c (insert_primary_withpred): Accept new argument, arg,
69+ being the argument (if any) of this predicate. Pass it to
70+ get_new_pred_chk_op.
71+ (insert_primary): Likewise (pass arg to insert_primary_withpred).
72+ (insert_primary_noarg): New function; calls insert_primary with
73+ arg=NULL.
74+ * find/parser.c (collect_arg_stat_info): Add an output parameter;
75+ the filename from which we collected the stat information.
76+ (parse_closeparen, parse_delete, parse_and, parse_or,
77+ parse_comma): Use get_new_pred_noarg.
78+ (parse_cnewer, parse_newer, parse_anewer): Use new
79+ collect_arg_stat_info and insert_primary interface.
80+ (parse_print, parse_prune, parse_nouser, parse_empty): Use
81+ insert_primary_noarg.
82+ (parse_accesscheck, parse_false): Use insert_primary_noarg.
83+ (parse_used, parse_iname, parse_fprint, insert_fprint,
84+ parse_fstype, parse_ilname): Use new collect_arg and
85+ insert_primary interfaces.
86+ (parse_ipath, parse_lname, do_parse_xmin, parse_name, parse_path,
87+ parse_perm, parse_size, parse_user, parse_time): Use new
88+ collect_arg and insert_primary_withpred interface.
89+ (parse_negate, parse_openparen): Use new get_new_pred_chk_op interface.
90+ (parse_newerXY, parse_nogroup): Use new insert_primary interface.
91+ (insert_regex, parse_samefile): Use new insert_primary_withpred
92+ interface.
93+ (insert_type, insert_fprintf, new_insert_exec_ok, insert_num): Use
94+ new insert_primary_withpred interface.
95+ * find/defs.h (struct predicate.arg_text): make const.
96+ Add declarations for new function get_new_pred_noarg and
97+ insert_primary_noarg. Add 'arg' parameter to get_new_pred_chk_op
98+ and insert_primary_withpred.
99+
100diff --git a/find/defs.h b/find/defs.h
101index 1708d83..4539fd9 100644
102--- a/find/defs.h
103+++ b/find/defs.h
104@@ -297,7 +297,7 @@ struct predicate
105 boolean artificial;
106
107 /* The raw text of the argument of this predicate. */
108- char *arg_text;
109+ const char *arg_text;
110
111 /* Information needed by the predicate processor.
112 Next to each member are listed the predicates that use it. */
113@@ -480,13 +480,16 @@ void show_success_rates(const struct predicate *node);
114 /* tree.c */
115 struct predicate * build_expression_tree PARAMS((int argc, char *argv[], int end_of_leading_options));
116 struct predicate * get_eval_tree PARAMS((void));
117+struct predicate *get_new_pred_noarg (const struct parser_table *entry);
118 struct predicate *get_new_pred PARAMS((const struct parser_table *entry));
119-struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table *entry));
120+struct predicate *get_new_pred_chk_op PARAMS((const struct parser_table *entry,
121+ const char *arg));
122 float calculate_derived_rates PARAMS((struct predicate *p));
123
124 /* util.c */
125-struct predicate *insert_primary PARAMS((const struct parser_table *entry));
126-struct predicate *insert_primary_withpred PARAMS((const struct parser_table *entry, PRED_FUNC fptr));
127+struct predicate *insert_primary PARAMS((const struct parser_table *entry, const char *arg));
128+struct predicate *insert_primary_noarg PARAMS((const struct parser_table *entry));
129+struct predicate *insert_primary_withpred PARAMS((const struct parser_table *entry, PRED_FUNC fptr, const char *arg));
130 void usage PARAMS((FILE *fp, int status, char *msg));
131 extern boolean check_nofollow(void);
132 void complete_pending_execs(struct predicate *p);
133diff --git a/find/parser.c b/find/parser.c
134index 534b670..2e6b989 100644
135--- a/find/parser.c
136+++ b/find/parser.c
137@@ -640,11 +640,13 @@ collect_arg(char **argv, int *arg_ptr, const char **collected_arg)
138 }
139
140 static boolean
141-collect_arg_stat_info(char **argv, int *arg_ptr, struct stat *p)
142+collect_arg_stat_info(char **argv, int *arg_ptr, struct stat *p,
143+ const char **argument)
144 {
145 const char *filename;
146 if (collect_arg(argv, arg_ptr, &filename))
147 {
148+ *argument = filename;
149 if (0 == (options.xstat)(filename, p))
150 {
151 return true;
152@@ -656,6 +658,7 @@ collect_arg_stat_info(char **argv, int *arg_ptr, struct stat *p)
153 }
154 else
155 {
156+ *argument = NULL;
157 return false;
158 }
159 }
160@@ -679,7 +682,7 @@ parse_and (const struct parser_table* entry, char **argv, int *arg_ptr)
161 (void) argv;
162 (void) arg_ptr;
163
164- our_pred = get_new_pred (entry);
165+ our_pred = get_new_pred_noarg (entry);
166 our_pred->pred_func = pred_and;
167 our_pred->p_type = BI_OP;
168 our_pred->p_prec = AND_PREC;
169@@ -691,11 +694,12 @@ static boolean
170 parse_anewer (const struct parser_table* entry, char **argv, int *arg_ptr)
171 {
172 struct stat stat_newer;
173+ const char *arg;
174
175 set_stat_placeholders(&stat_newer);
176- if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
177+ if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
178 {
179- struct predicate *our_pred = insert_primary (entry);
180+ struct predicate *our_pred = insert_primary (entry, arg);
181 our_pred->args.reftime.xval = XVAL_ATIME;
182 our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
183 our_pred->args.reftime.kind = COMP_GT;
184@@ -713,7 +717,7 @@ parse_closeparen (const struct parser_table* entry, char **argv, int *arg_ptr)
185 (void) argv;
186 (void) arg_ptr;
187
188- our_pred = get_new_pred (entry);
189+ our_pred = get_new_pred_noarg (entry);
190 our_pred->pred_func = pred_closeparen;
191 our_pred->p_type = CLOSE_PAREN;
192 our_pred->p_prec = NO_PREC;
193@@ -725,11 +729,12 @@ static boolean
194 parse_cnewer (const struct parser_table* entry, char **argv, int *arg_ptr)
195 {
196 struct stat stat_newer;
197+ const char *arg;
198
199 set_stat_placeholders(&stat_newer);
200- if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
201+ if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
202 {
203- struct predicate *our_pred = insert_primary (entry);
204+ struct predicate *our_pred = insert_primary (entry, arg);
205 our_pred->args.reftime.xval = XVAL_CTIME; /* like -newercm */
206 our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
207 our_pred->args.reftime.kind = COMP_GT;
208@@ -747,7 +752,7 @@ parse_comma (const struct parser_table* entry, char **argv, int *arg_ptr)
209 (void) argv;
210 (void) arg_ptr;
211
212- our_pred = get_new_pred (entry);
213+ our_pred = get_new_pred_noarg (entry);
214 our_pred->pred_func = pred_comma;
215 our_pred->p_type = BI_OP;
216 our_pred->p_prec = COMMA_PREC;
217@@ -786,7 +791,7 @@ parse_delete (const struct parser_table* entry, char *argv[], int *arg_ptr)
218 (void) argv;
219 (void) arg_ptr;
220
221- our_pred = insert_primary (entry);
222+ our_pred = insert_primary_noarg (entry);
223 our_pred->side_effects = our_pred->no_default_print = true;
224 /* -delete implies -depth */
225 options.do_dir_first = false;
226@@ -831,7 +836,7 @@ parse_empty (const struct parser_table* entry, char **argv, int *arg_ptr)
227 (void) argv;
228 (void) arg_ptr;
229
230- our_pred = insert_primary (entry);
231+ our_pred = insert_primary_noarg (entry);
232 our_pred->est_success_rate = 0.01f; /* assume 1% of files are empty. */
233 return true;
234 }
235@@ -856,7 +861,7 @@ parse_false (const struct parser_table* entry, char **argv, int *arg_ptr)
236 (void) argv;
237 (void) arg_ptr;
238
239- our_pred = insert_primary (entry);
240+ our_pred = insert_primary_noarg (entry);
241 our_pred->need_stat = our_pred->need_type = false;
242 our_pred->side_effects = our_pred->no_default_print = false;
243 our_pred->est_success_rate = 0.0f;
244@@ -866,7 +871,7 @@ parse_false (const struct parser_table* entry, char **argv, int *arg_ptr)
245 static boolean
246 insert_fls (const struct parser_table* entry, const char *filename)
247 {
248- struct predicate *our_pred = insert_primary (entry);
249+ struct predicate *our_pred = insert_primary_noarg (entry);
250 if (filename)
251 open_output_file (filename, &our_pred->args.printf_vec);
252 else
253@@ -899,7 +904,7 @@ parse_fprint (const struct parser_table* entry, char **argv, int *arg_ptr)
254 const char *filename;
255 if (collect_arg(argv, arg_ptr, &filename))
256 {
257- our_pred = insert_primary (entry);
258+ our_pred = insert_primary (entry, filename);
259 open_output_file (filename, &our_pred->args.printf_vec);
260 our_pred->side_effects = our_pred->no_default_print = true;
261 our_pred->need_stat = our_pred->need_type = false;
262@@ -915,7 +920,7 @@ parse_fprint (const struct parser_table* entry, char **argv, int *arg_ptr)
263 static boolean
264 insert_fprint(const struct parser_table* entry, const char *filename)
265 {
266- struct predicate *our_pred = insert_primary (entry);
267+ struct predicate *our_pred = insert_primary (entry, filename);
268 if (filename)
269 open_output_file (filename, &our_pred->args.printf_vec);
270 else
271@@ -960,7 +965,7 @@ parse_fstype (const struct parser_table* entry, char **argv, int *arg_ptr)
272 const char *typename;
273 if (collect_arg(argv, arg_ptr, &typename))
274 {
275- struct predicate *our_pred = insert_primary (entry);
276+ struct predicate *our_pred = insert_primary (entry, typename);
277 our_pred->args.str = typename;
278
279 /* This is an expensive operation, so although there are
280@@ -1090,7 +1095,7 @@ parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
281 return false;
282 }
283 }
284- our_pred = insert_primary (entry);
285+ our_pred = insert_primary (entry, groupname);
286 our_pred->args.gid = gid;
287 our_pred->est_success_rate = (our_pred->args.numinfo.l_val < 100) ? 0.99 : 0.2;
288 return true;
289@@ -1160,7 +1165,7 @@ parse_ilname (const struct parser_table* entry, char **argv, int *arg_ptr)
290 const char *name;
291 if (collect_arg(argv, arg_ptr, &name))
292 {
293- struct predicate *our_pred = insert_primary (entry);
294+ struct predicate *our_pred = insert_primary (entry, name);
295 our_pred->args.str = name;
296 /* Use the generic glob pattern estimator to figure out how many
297 * links will match, but bear in mind that most files won't be links.
298@@ -1227,7 +1232,7 @@ parse_iname (const struct parser_table* entry, char **argv, int *arg_ptr)
299 {
300 if (check_name_arg("-iname", name))
301 {
302- struct predicate *our_pred = insert_primary (entry);
303+ struct predicate *our_pred = insert_primary (entry, name);
304 our_pred->need_stat = our_pred->need_type = false;
305 our_pred->args.str = name;
306 our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
307@@ -1268,7 +1273,7 @@ parse_ipath (const struct parser_table* entry, char **argv, int *arg_ptr)
308 fnmatch_sanitycheck ();
309 if (collect_arg (argv, arg_ptr, &name))
310 {
311- struct predicate *our_pred = insert_primary_withpred (entry, pred_ipath);
312+ struct predicate *our_pred = insert_primary_withpred (entry, pred_ipath, name);
313 our_pred->need_stat = our_pred->need_type = false;
314 our_pred->args.str = name;
315 our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
316@@ -1316,7 +1321,7 @@ parse_lname (const struct parser_table* entry, char **argv, int *arg_ptr)
317 fnmatch_sanitycheck();
318 if (collect_arg(argv, arg_ptr, &name))
319 {
320- struct predicate *our_pred = insert_primary (entry);
321+ struct predicate *our_pred = insert_primary (entry, name);
322 our_pred->args.str = name;
323 our_pred->est_success_rate = 0.1 * estimate_pattern_match_rate(name, 0);
324 return true;
325@@ -1391,7 +1396,7 @@ do_parse_xmin (const struct parser_table* entry,
326 "arithmetic overflow while converting %s "
327 "minutes to a number of seconds"))
328 {
329- struct predicate *our_pred = insert_primary (entry);
330+ struct predicate *our_pred = insert_primary (entry, minutes);
331 our_pred->args.reftime = tval;
332 our_pred->est_success_rate = estimate_timestamp_success_rate(tval.ts.tv_sec);
333 return true;
334@@ -1427,7 +1432,7 @@ parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
335 fnmatch_sanitycheck();
336 if (check_name_arg("-name", name))
337 {
338- struct predicate *our_pred = insert_primary (entry);
339+ struct predicate *our_pred = insert_primary (entry, name);
340 our_pred->need_stat = our_pred->need_type = false;
341 our_pred->args.str = name;
342 our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
343@@ -1445,7 +1450,7 @@ parse_negate (const struct parser_table* entry, char **argv, int *arg_ptr)
344 (void) &argv;
345 (void) &arg_ptr;
346
347- our_pred = get_new_pred_chk_op (entry);
348+ our_pred = get_new_pred_chk_op (entry, NULL);
349 our_pred->pred_func = pred_negate;
350 our_pred->p_type = UNI_OP;
351 our_pred->p_prec = NEGATE_PREC;
352@@ -1458,11 +1463,12 @@ parse_newer (const struct parser_table* entry, char **argv, int *arg_ptr)
353 {
354 struct predicate *our_pred;
355 struct stat stat_newer;
356+ const char *arg;
357
358 set_stat_placeholders(&stat_newer);
359- if (collect_arg_stat_info(argv, arg_ptr, &stat_newer))
360+ if (collect_arg_stat_info(argv, arg_ptr, &stat_newer, &arg))
361 {
362- our_pred = insert_primary (entry);
363+ our_pred = insert_primary (entry, arg);
364 our_pred->args.reftime.ts = get_stat_mtime(&stat_newer);
365 our_pred->args.reftime.xval = XVAL_MTIME;
366 our_pred->args.reftime.kind = COMP_GT;
367@@ -1530,7 +1536,7 @@ parse_newerXY (const struct parser_table* entry, char **argv, int *arg_ptr)
368 (*arg_ptr)++;
369 }
370
371- our_pred = insert_primary (entry);
372+ our_pred = insert_primary (entry, argv[*arg_ptr]);
373
374
375 switch (x)
376@@ -1623,7 +1629,7 @@ parse_nogroup (const struct parser_table* entry, char **argv, int *arg_ptr)
377 (void) &argv;
378 (void) &arg_ptr;
379
380- our_pred = insert_primary (entry);
381+ our_pred = insert_primary (entry, NULL);
382 our_pred->est_success_rate = 1e-4;
383 #ifdef CACHE_IDS
384 if (gid_unused == NULL)
385@@ -1660,7 +1666,7 @@ parse_nouser (const struct parser_table* entry, char **argv, int *arg_ptr)
386 (void) arg_ptr;
387
388
389- our_pred = insert_primary (entry);
390+ our_pred = insert_primary_noarg (entry);
391 our_pred->est_success_rate = 1e-3;
392 #ifdef CACHE_IDS
393 if (uid_unused == NULL)
394@@ -1716,7 +1722,7 @@ parse_openparen (const struct parser_table* entry, char **argv, int *arg_ptr)
395 (void) argv;
396 (void) arg_ptr;
397
398- our_pred = get_new_pred_chk_op (entry);
399+ our_pred = get_new_pred_chk_op (entry, NULL);
400 our_pred->pred_func = pred_openparen;
401 our_pred->p_type = OPEN_PAREN;
402 our_pred->p_prec = NO_PREC;
403@@ -1732,7 +1738,7 @@ parse_or (const struct parser_table* entry, char **argv, int *arg_ptr)
404 (void) argv;
405 (void) arg_ptr;
406
407- our_pred = get_new_pred (entry);
408+ our_pred = get_new_pred_noarg (entry);
409 our_pred->pred_func = pred_or;
410 our_pred->p_type = BI_OP;
411 our_pred->p_prec = OR_PREC;
412@@ -1756,7 +1762,7 @@ parse_path (const struct parser_table* entry, char **argv, int *arg_ptr)
413 const char *name;
414 if (collect_arg(argv, arg_ptr, &name))
415 {
416- struct predicate *our_pred = insert_primary_withpred (entry, pred_path);
417+ struct predicate *our_pred = insert_primary_withpred (entry, pred_path, name);
418 our_pred->need_stat = our_pred->need_type = false;
419 our_pred->args.str = name;
420 our_pred->est_success_rate = estimate_pattern_match_rate (name, 0);
421@@ -1894,7 +1900,7 @@ parse_perm (const struct parser_table* entry, char **argv, int *arg_ptr)
422 rate = 0.9986; /* probably matches anything but a broken symlink */
423 }
424
425- our_pred = insert_primary (entry);
426+ our_pred = insert_primary (entry, perm_expr);
427 our_pred->est_success_rate = rate;
428 if (havekind)
429 {
430@@ -1928,7 +1934,7 @@ parse_print (const struct parser_table* entry, char **argv, int *arg_ptr)
431 (void) argv;
432 (void) arg_ptr;
433
434- our_pred = insert_primary (entry);
435+ our_pred = insert_primary_noarg (entry);
436 /* -print has the side effect of printing. This prevents us
437 from doing undesired multiple printing when the user has
438 already specified -print. */
439@@ -1981,7 +1987,7 @@ parse_prune (const struct parser_table* entry, char **argv, int *arg_ptr)
440 (void) argv;
441 (void) arg_ptr;
442
443- our_pred = insert_primary (entry);
444+ our_pred = insert_primary_noarg (entry);
445 if (options.do_dir_first == false)
446 our_pred->need_stat = our_pred->need_type = false;
447 /* -prune has a side effect that it does not descend into
448@@ -1994,7 +2000,7 @@ parse_prune (const struct parser_table* entry, char **argv, int *arg_ptr)
449 static boolean
450 parse_quit (const struct parser_table* entry, char **argv, int *arg_ptr)
451 {
452- struct predicate *our_pred = insert_primary (entry);
453+ struct predicate *our_pred = insert_primary_noarg (entry);
454 (void) argv;
455 (void) arg_ptr;
456 our_pred->need_stat = our_pred->need_type = false;
457@@ -2036,7 +2042,7 @@ insert_regex (char **argv,
458 {
459 struct re_pattern_buffer *re;
460 const char *error_message;
461- struct predicate *our_pred = insert_primary_withpred (entry, pred_regex);
462+ struct predicate *our_pred = insert_primary_withpred (entry, pred_regex, rx);
463 our_pred->need_stat = our_pred->need_type = false;
464 re = xmalloc (sizeof (struct re_pattern_buffer));
465 our_pred->args.regex = re;
466@@ -2061,6 +2067,7 @@ static boolean
467 parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
468 {
469 struct predicate *our_pred;
470+ char *arg;
471 uintmax_t num;
472 char suffix;
473 enum comparison_type c_type;
474@@ -2073,42 +2080,43 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
475 */
476 if ((argv == NULL) || (argv[*arg_ptr] == NULL))
477 return false;
478+ arg = argv[*arg_ptr];
479
480- len = strlen (argv[*arg_ptr]);
481+ len = strlen (arg);
482 if (len == 0)
483 error (1, 0, _("invalid null argument to -size"));
484
485- suffix = argv[*arg_ptr][len - 1];
486+ suffix = arg[len - 1];
487 switch (suffix)
488 {
489 case 'b':
490 blksize = 512;
491- argv[*arg_ptr][len - 1] = '\0';
492+ arg[len - 1] = '\0';
493 break;
494
495 case 'c':
496 blksize = 1;
497- argv[*arg_ptr][len - 1] = '\0';
498+ arg[len - 1] = '\0';
499 break;
500
501 case 'k':
502 blksize = 1024;
503- argv[*arg_ptr][len - 1] = '\0';
504+ arg[len - 1] = '\0';
505 break;
506
507 case 'M': /* Megabytes */
508 blksize = 1024*1024;
509- argv[*arg_ptr][len - 1] = '\0';
510+ arg[len - 1] = '\0';
511 break;
512
513 case 'G': /* Gigabytes */
514 blksize = 1024*1024*1024;
515- argv[*arg_ptr][len - 1] = '\0';
516+ arg[len - 1] = '\0';
517 break;
518
519 case 'w':
520 blksize = 2;
521- argv[*arg_ptr][len - 1] = '\0';
522+ arg[len - 1] = '\0';
523 break;
524
525 case '0':
526@@ -2127,14 +2135,14 @@ parse_size (const struct parser_table* entry, char **argv, int *arg_ptr)
527 error (1, 0, _("invalid -size type `%c'"), argv[*arg_ptr][len - 1]);
528 }
529 /* TODO: accept fractional megabytes etc. ? */
530- if (!get_num (argv[*arg_ptr], &num, &c_type))
531+ if (!get_num (arg, &num, &c_type))
532 {
533 error(1, 0,
534 _("Invalid argument `%s%c' to -size"),
535- argv[*arg_ptr], (int)suffix);
536+ arg, (int)suffix);
537 return false;
538 }
539- our_pred = insert_primary (entry);
540+our_pred = insert_primary (entry, arg);
541 our_pred->args.size.kind = c_type;
542 our_pred->args.size.blocksize = blksize;
543 our_pred->args.size.size = num;
544@@ -2162,9 +2170,10 @@ parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
545 struct predicate *our_pred;
546 struct stat st, fst;
547 int fd, openflags;
548+ const char *filename;
549
550 set_stat_placeholders(&st);
551- if (!collect_arg_stat_info(argv, arg_ptr, &st))
552+ if (!collect_arg_stat_info(argv, arg_ptr, &st, &filename))
553 return false;
554
555 set_stat_placeholders(&fst);
556@@ -2289,7 +2298,7 @@ parse_samefile (const struct parser_table* entry, char **argv, int *arg_ptr)
557 }
558 }
559
560- our_pred = insert_primary (entry);
561+ our_pred = insert_primary (entry, filename);
562 our_pred->args.samefileid.ino = st.st_ino;
563 our_pred->args.samefileid.dev = st.st_dev;
564 our_pred->args.samefileid.fd = fd;
565@@ -2350,7 +2359,7 @@ parse_true (const struct parser_table* entry, char **argv, int *arg_ptr)
566 (void) argv;
567 (void) arg_ptr;
568
569- our_pred = insert_primary (entry);
570+ our_pred = insert_primary_noarg (entry);
571 our_pred->need_stat = our_pred->need_type = false;
572 our_pred->est_success_rate = 1.0f;
573 return true;
574@@ -2369,7 +2378,7 @@ parse_accesscheck (const struct parser_table* entry, char **argv, int *arg_ptr)
575 struct predicate *our_pred;
576 (void) argv;
577 (void) arg_ptr;
578- our_pred = insert_primary (entry);
579+ our_pred = insert_primary_noarg (entry);
580 our_pred->need_stat = our_pred->need_type = false;
581 our_pred->side_effects = our_pred->no_default_print = false;
582 if (pred_is(our_pred, pred_executable))
583@@ -2414,7 +2423,7 @@ parse_used (const struct parser_table* entry, char **argv, int *arg_ptr)
584 struct timespec zero = {0,0};
585 if (get_relative_timestamp(offset_str, &tval, zero, DAYSECS, errmsg))
586 {
587- our_pred = insert_primary (entry);
588+ our_pred = insert_primary (entry, offset_str);
589 our_pred->args.reftime = tval;
590 our_pred->est_success_rate = estimate_file_age_success_rate(tval.ts.tv_sec / DAYSECS);
591 return true;
592@@ -2472,7 +2481,7 @@ parse_user (const struct parser_table* entry, char **argv, int *arg_ptr)
593 return false;
594 }
595 }
596- our_pred = insert_primary (entry);
597+ our_pred = insert_primary (entry, username);
598 our_pred->args.uid = uid;
599 our_pred->est_success_rate = (our_pred->args.uid < 100) ? 0.99 : 0.2;
600 return true;
601@@ -2650,7 +2659,7 @@ insert_type (char **argv, int *arg_ptr,
602 error(1, 0, _("Unknown argument to -type: %c"), (*typeletter));
603 return false;
604 }
605- our_pred = insert_primary_withpred (entry, which_pred);
606+ our_pred = insert_primary_withpred (entry, which_pred, typeletter);
607 our_pred->est_success_rate = rate;
608
609 /* Figure out if we will need to stat the file, because if we don't
610@@ -2706,7 +2715,7 @@ insert_fprintf (struct format_val *vec,
611 struct segment **segmentp; /* Address of current segment. */
612 struct predicate *our_pred;
613
614- our_pred = insert_primary_withpred (entry, func);
615+ our_pred = insert_primary_withpred (entry, func, format_const);
616 our_pred->side_effects = our_pred->no_default_print = true;
617 our_pred->args.printf_vec = *vec;
618 our_pred->need_type = false;
619@@ -3045,7 +3054,7 @@ new_insert_exec_ok (const char *action,
620 if ((argv == NULL) || (argv[*arg_ptr] == NULL))
621 return false;
622
623- our_pred = insert_primary_withpred (entry, func);
624+ our_pred = insert_primary_withpred (entry, func, "(some -exec* arguments)");
625 our_pred->side_effects = our_pred->no_default_print = true;
626 our_pred->need_type = our_pred->need_stat = false;
627
628@@ -3374,7 +3383,7 @@ parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
629 if (!get_relative_timestamp(timearg, &tval, origin, DAYSECS, errmsg))
630 return false;
631
632- our_pred = insert_primary (entry);
633+ our_pred = insert_primary (entry, orig_timearg);
634 our_pred->args.reftime = tval;
635 our_pred->est_success_rate = estimate_timestamp_success_rate(tval.ts.tv_sec);
636
637@@ -3487,7 +3496,7 @@ insert_num (char **argv, int *arg_ptr, const struct parser_table *entry)
638
639 if (get_num (numstr, &num, &c_type))
640 {
641- struct predicate *our_pred = insert_primary (entry);
642+ struct predicate *our_pred = insert_primary (entry, numstr);
643 our_pred->args.numinfo.kind = c_type;
644 our_pred->args.numinfo.l_val = num;
645
646diff --git a/find/tree.c b/find/tree.c
647index 7420c60..60a0601 100644
648--- a/find/tree.c
649+++ b/find/tree.c
650@@ -269,10 +269,14 @@ predicate_is_cost_free(const struct predicate *p)
651 /* Prints a predicate */
652 void print_predicate(FILE *fp, const struct predicate *p)
653 {
654- fprintf (fp, "%s%s%s",
655- p->p_name,
656- p->arg_text ? " " : "",
657- p->arg_text ? p->arg_text : "");
658+ if (p->arg_text)
659+ {
660+ fprintf (fp, "%s %s", p->p_name, p->arg_text);
661+ }
662+ else
663+ {
664+ fprintf (fp, "%s", p->p_name);
665+ }
666 }
667
668
669@@ -832,7 +836,8 @@ set_new_parent (struct predicate *curr, enum predicate_precedence high_prec, str
670 new_parent->need_stat = false;
671 new_parent->need_type = false;
672 new_parent->p_cost = NeedsNothing;
673-
674+ new_parent->arg_text = NULL;
675+
676 switch (high_prec)
677 {
678 case COMMA_PREC:
679@@ -1393,6 +1398,18 @@ init_pred_perf(struct predicate *pred)
680 p->visits = p->successes = 0;
681 }
682
683+
684+struct predicate *
685+get_new_pred_noarg (const struct parser_table *entry)
686+{
687+ struct predicate *p = get_new_pred(entry);
688+ if (p)
689+ {
690+ p->arg_text = NULL;
691+ }
692+ return p;
693+}
694+
695
696 /* Return a pointer to a new predicate structure, which has been
697 linked in as the last one in the predicates list.
698@@ -1433,6 +1450,8 @@ get_new_pred (const struct parser_table *entry)
699 last_pred->no_default_print = false;
700 last_pred->need_stat = true;
701 last_pred->need_type = true;
702+ last_pred->p_cost = NeedsUnknown;
703+ last_pred->arg_text = "ThisShouldBeSetToSomethingElse";
704 last_pred->args.str = NULL;
705 last_pred->pred_next = NULL;
706 last_pred->pred_left = NULL;
707@@ -1449,7 +1468,8 @@ get_new_pred (const struct parser_table *entry)
708 predicate is an operator. If it isn't, the AND operator is inserted. */
709
710 struct predicate *
711-get_new_pred_chk_op (const struct parser_table *entry)
712+get_new_pred_chk_op (const struct parser_table *entry,
713+ const char *arg)
714 {
715 struct predicate *new_pred;
716 static const struct parser_table *entry_and = NULL;
717@@ -1471,13 +1491,14 @@ get_new_pred_chk_op (const struct parser_table *entry)
718 case PRIMARY_TYPE:
719 case CLOSE_PAREN:
720 /* We need to interpose the and operator. */
721- new_pred = get_new_pred (entry_and);
722+ new_pred = get_new_pred_noarg (entry_and);
723 new_pred->pred_func = pred_and;
724 new_pred->p_name = "-a";
725 new_pred->p_type = BI_OP;
726 new_pred->p_prec = AND_PREC;
727 new_pred->need_stat = false;
728 new_pred->need_type = false;
729+ new_pred->arg_text = NULL;
730 new_pred->args.str = NULL;
731 new_pred->side_effects = false;
732 new_pred->no_default_print = false;
733@@ -1488,6 +1509,7 @@ get_new_pred_chk_op (const struct parser_table *entry)
734 }
735
736 new_pred = get_new_pred (entry);
737+ new_pred->arg_text = arg;
738 new_pred->parser_entry = entry;
739 return new_pred;
740 }
741diff --git a/find/util.c b/find/util.c
742index a06eada..cc9a3eb 100644
743--- a/find/util.c
744+++ b/find/util.c
745@@ -89,11 +89,13 @@ static struct debug_option_assoc debugassoc[] =
746 operator. */
747
748 struct predicate *
749-insert_primary_withpred (const struct parser_table *entry, PRED_FUNC pred_func)
750+insert_primary_withpred (const struct parser_table *entry,
751+ PRED_FUNC pred_func,
752+ const char *arg)
753 {
754 struct predicate *new_pred;
755
756- new_pred = get_new_pred_chk_op (entry);
757+ new_pred = get_new_pred_chk_op (entry, arg);
758 new_pred->pred_func = pred_func;
759 new_pred->p_name = entry->parser_name;
760 new_pred->args.str = NULL;
761@@ -118,10 +120,16 @@ insert_primary_withpred (const struct parser_table *entry, PRED_FUNC pred_func)
762 either not there at all (we are the very first node) or is an
763 operator. */
764 struct predicate *
765-insert_primary (const struct parser_table *entry)
766+insert_primary (const struct parser_table *entry, const char *arg)
767 {
768 assert (entry->pred_func != NULL);
769- return insert_primary_withpred(entry, entry->pred_func);
770+ return insert_primary_withpred(entry, entry->pred_func, arg);
771+}
772+
773+struct predicate *
774+insert_primary_noarg (const struct parser_table *entry)
775+{
776+ return insert_primary(entry, NULL);
777 }
778
779
diff --git a/meta/recipes-extended/findutils/findutils-4.4.2/02-28824.patch b/meta/recipes-extended/findutils/findutils-4.4.2/02-28824.patch
new file mode 100644
index 0000000000..3469712d90
--- /dev/null
+++ b/meta/recipes-extended/findutils/findutils-4.4.2/02-28824.patch
@@ -0,0 +1,292 @@
1commit 76ed377d6d3e4a83a00cabd401f751b37ecd1e7b
2Author: James Youngman <jay@gnu.org>
3Date: Sat Feb 20 13:11:45 2010 +0000
4
5 Fix Savannah bug# 28824: "-ctime x" yields "missing argument to `-ctime'".
6
7 * find/parser.c (parse_fls): If the argument is invalid, reverse
8 the change that collect_arg() made to *arg_ptr (that is, don't
9 consume the argument).
10 (parse_fprint0): Likewise.
11 (parse_gid): Likewise.
12 (parse_group): Likewise.
13 (parse_inum): Likewise.
14 (parse_links): Likewise.
15 (do_parse_xmin): Likewise.
16 (parse_name): Likewise.
17 (parse_printf): Likewise.
18 (parse_uid): Likewise.
19 (parse_used): Likewise.
20 (parse_time): Likewise.
21
22 Signed-off-by: James Youngman <jay@gnu.org>
23
24diff --git a/ChangeLog b/ChangeLog
25index d0ce1fe..13539a4 100644
26--- a/ChangeLog
27+++ b/ChangeLog
28@@ -1,0 +1,19 @@
29+2010-02-20 James Youngman <jay@gnu.org>
30+
31+ Fix Savannah bug# 28824: "-ctime x" yields "missing argument to
32+ `-ctime'".
33+ * find/parser.c (parse_fls): If the argument is invalid, reverse
34+ the change that collect_arg() made to *arg_ptr (that is, don't
35+ consume the argument).
36+ (parse_fprint0): Likewise.
37+ (parse_gid): Likewise.
38+ (parse_group): Likewise.
39+ (parse_inum): Likewise.
40+ (parse_links): Likewise.
41+ (do_parse_xmin): Likewise.
42+ (parse_name): Likewise.
43+ (parse_printf): Likewise.
44+ (parse_uid): Likewise.
45+ (parse_used): Likewise.
46+ (parse_time): Likewise.
47+
48diff --git a/NEWS b/NEWS
49index 5394311..4e910df 100644
50--- a/NEWS
51+++ b/NEWS
52@@ -4,5 +4,8 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout)
53
54 ** Bug Fixes
55
56+#28824: Corrected error message for "-ctime x".
57+ Likewise for -gid, -inum, -links, -mmin, -cmin, -amin,
58+ -uid, -used, -atime, -mtime, -ctime.
59 #26537: find -prune now makes sure it has valid stat() information.
60
61diff --git a/find/parser.c b/find/parser.c
62index 2e6b989..08758ee 100644
63--- a/find/parser.c
64+++ b/find/parser.c
65@@ -886,8 +886,14 @@ static boolean
66 parse_fls (const struct parser_table* entry, char **argv, int *arg_ptr)
67 {
68 const char *filename;
69- return collect_arg(argv, arg_ptr, &filename)
70- && insert_fls(entry, filename);
71+ if (collect_arg(argv, arg_ptr, &filename))
72+ {
73+ if (insert_fls(entry, filename))
74+ return true;
75+ else
76+ --*arg_ptr; /* don't consume the invalid arg. */
77+ }
78+ return false;
79 }
80
81 static boolean
82@@ -937,9 +943,13 @@ parse_fprint0 (const struct parser_table* entry, char **argv, int *arg_ptr)
83 {
84 const char *filename;
85 if (collect_arg(argv, arg_ptr, &filename))
86- return insert_fprint(entry, filename);
87- else
88- return false;
89+ {
90+ if (insert_fprint(entry, filename))
91+ return true;
92+ else
93+ --*arg_ptr; /* don't consume the bad arg. */
94+ }
95+ return false;
96 }
97
98 static float estimate_fstype_success_rate(const char *fsname)
99@@ -993,6 +1003,7 @@ parse_gid (const struct parser_table* entry, char **argv, int *arg_ptr)
100 }
101 else
102 {
103+ --*arg_ptr; /* don't consume the invalid argument. */
104 return false;
105 }
106 }
107@@ -1049,6 +1060,7 @@ static boolean
108 parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
109 {
110 const char *groupname;
111+ const int saved_argc = *arg_ptr;
112
113 if (collect_arg(argv, arg_ptr, &groupname))
114 {
115@@ -1077,6 +1089,7 @@ parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
116 "because it has the unexpected suffix %s"),
117 quotearg_n_style(0, options.err_quoting_style, groupname),
118 quotearg_n_style(1, options.err_quoting_style, groupname+gid_len));
119+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
120 return false;
121 }
122 }
123@@ -1092,6 +1105,7 @@ parse_group (const struct parser_table* entry, char **argv, int *arg_ptr)
124 {
125 error(1, 0, _("argument to -group is empty, but should be a group name"));
126 }
127+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
128 return false;
129 }
130 }
131@@ -1256,6 +1270,7 @@ parse_inum (const struct parser_table* entry, char **argv, int *arg_ptr)
132 }
133 else
134 {
135+ --*arg_ptr; /* don't consume the invalid argument. */
136 return false;
137 }
138 }
139@@ -1310,6 +1325,7 @@ parse_links (const struct parser_table* entry, char **argv, int *arg_ptr)
140 }
141 else
142 {
143+ --*arg_ptr; /* don't consume the invalid argument. */
144 return false;
145 }
146 }
147@@ -1358,6 +1374,7 @@ insert_depthspec(const struct parser_table* entry, char **argv, int *arg_ptr,
148 error(1, 0, _("Expected a positive decimal integer argument to %s, but got %s"),
149 predicate,
150 quotearg_n_style(0, options.err_quoting_style, depthstr));
151+ /* NOTREACHED */
152 return false;
153 }
154 /* missing argument */
155@@ -1385,6 +1402,7 @@ do_parse_xmin (const struct parser_table* entry,
156 enum xval xv)
157 {
158 const char *minutes;
159+ const int saved_argc = *arg_ptr;
160
161 if (collect_arg(argv, arg_ptr, &minutes))
162 {
163@@ -1401,6 +1419,11 @@ do_parse_xmin (const struct parser_table* entry,
164 our_pred->est_success_rate = estimate_timestamp_success_rate(tval.ts.tv_sec);
165 return true;
166 }
167+ else
168+ {
169+ /* Don't consume the invalid argument. */
170+ *arg_ptr = saved_argc;
171+ }
172 }
173 return false;
174 }
175@@ -1427,6 +1450,8 @@ static boolean
176 parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
177 {
178 const char *name;
179+ const int saved_argc = *arg_ptr;
180+
181 if (collect_arg(argv, arg_ptr, &name))
182 {
183 fnmatch_sanitycheck();
184@@ -1438,6 +1463,10 @@ parse_name (const struct parser_table* entry, char **argv, int *arg_ptr)
185 our_pred->est_success_rate = estimate_pattern_match_rate(name, 0);
186 return true;
187 }
188+ else
189+ {
190+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
191+ }
192 }
193 return false;
194 }
195@@ -1954,11 +1983,21 @@ static boolean
196 parse_printf (const struct parser_table* entry, char **argv, int *arg_ptr)
197 {
198 const char *format;
199+ const int saved_argc = *arg_ptr;
200+
201 if (collect_arg(argv, arg_ptr, &format))
202 {
203 struct format_val fmt;
204 open_stdout(&fmt);
205- return insert_fprintf (&fmt, entry, pred_fprintf, format);
206+ if (insert_fprintf (&fmt, entry, pred_fprintf, format))
207+ {
208+ return true;
209+ }
210+ else
211+ {
212+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
213+ return false;
214+ }
215 }
216 return false;
217 }
218@@ -1967,15 +2006,21 @@ static boolean
219 parse_fprintf (const struct parser_table* entry, char **argv, int *arg_ptr)
220 {
221 const char *format, *filename;
222+ int saved_argc = *arg_ptr;
223+
224 if (collect_arg(argv, arg_ptr, &filename))
225 {
226 if (collect_arg(argv, arg_ptr, &format))
227 {
228 struct format_val fmt;
229 open_output_file (filename, &fmt);
230- return insert_fprintf (&fmt, entry, pred_fprintf, format);
231+ saved_argc = *arg_ptr;
232+
233+ if (insert_fprintf (&fmt, entry, pred_fprintf, format))
234+ return true;
235 }
236 }
237+ *arg_ptr = saved_argc; /* don't consume the invalid argument. */
238 return false;
239 }
240
241@@ -2405,6 +2450,7 @@ parse_uid (const struct parser_table* entry, char **argv, int *arg_ptr)
242 }
243 else
244 {
245+ --*arg_ptr; /* don't consume the invalid argument. */
246 return false;
247 }
248 }
249@@ -2431,6 +2477,7 @@ parse_used (const struct parser_table* entry, char **argv, int *arg_ptr)
250 else
251 {
252 error(1, 0, _("Invalid argument %s to -used"), offset_str);
253+ /*NOTREACHED*/
254 return false;
255 }
256 }
257@@ -2610,6 +2657,7 @@ insert_type (char **argv, int *arg_ptr,
258 if (strlen(typeletter) != 1u)
259 {
260 error(1, 0, _("Arguments to -type should contain only one letter"));
261+ /*NOTREACHED*/
262 return false;
263 }
264
265@@ -2657,6 +2705,7 @@ insert_type (char **argv, int *arg_ptr,
266 #endif
267 default: /* None of the above ... nuke 'em. */
268 error(1, 0, _("Unknown argument to -type: %c"), (*typeletter));
269+ /*NOTREACHED*/
270 return false;
271 }
272 our_pred = insert_primary_withpred (entry, which_pred, typeletter);
273@@ -3349,6 +3398,7 @@ parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
274 const char *errmsg = "arithmetic overflow while converting %s "
275 "days to a number of seconds";
276 struct timespec origin;
277+ const int saved_argc = *arg_ptr;
278
279 if (!collect_arg(argv, arg_ptr, &timearg))
280 return false;
281@@ -3381,7 +3431,10 @@ parse_time (const struct parser_table* entry, char *argv[], int *arg_ptr)
282 timearg = orig_timearg;
283
284 if (!get_relative_timestamp(timearg, &tval, origin, DAYSECS, errmsg))
285- return false;
286+ {
287+ *arg_ptr = saved_argc; /* don't consume the invalid argument */
288+ return false;
289+ }
290
291 our_pred = insert_primary (entry, orig_timearg);
292 our_pred->args.reftime = tval;
diff --git a/meta/recipes-extended/findutils/findutils-4.4.2/03-28872.patch b/meta/recipes-extended/findutils/findutils-4.4.2/03-28872.patch
new file mode 100644
index 0000000000..8bede38920
--- /dev/null
+++ b/meta/recipes-extended/findutils/findutils-4.4.2/03-28872.patch
@@ -0,0 +1,56 @@
1commit 5f5eb921765794e8fc58c4bdffa2daa2ae34800f
2Author: James Youngman <jay@gnu.org>
3Date: Sat Feb 20 19:53:13 2010 +0000
4
5 Fix Savannah bug#28872, Mistake in "Problems with -exec and filenames"
6
7 * doc/find.texi (Problems with -exec and filenames): Add missing
8 $0 argument in example for sh -c 'something "$@" sh ...
9 * NEWS: Mention this change.
10
11 Signed-off-by: James Youngman <jay@gnu.org>
12
13diff --git a/ChangeLog b/ChangeLog
14index 13539a4..e94ba96 100644
15--- a/ChangeLog
16+++ b/ChangeLog
17@@ -1,5 +1,10 @@
18 2010-02-20 James Youngman <jay@gnu.org>
19
20+ Fix Savannah bug#28872, Mistake in "Problems with -exec and filenames"
21+ * doc/find.texi (Problems with -exec and filenames): Add missing
22+ $0 argument in example for sh -c 'something "$@" sh ...
23+ * NEWS: Mention this change.
24+
25 Fix Savannah bug# 28824: "-ctime x" yields "missing argument to
26 `-ctime'".
27 * find/parser.c (parse_fls): If the argument is invalid, reverse
28diff --git a/NEWS b/NEWS
29index 4e910df..4c97be9 100644
30--- a/NEWS
31+++ b/NEWS
32@@ -4,6 +4,9 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout)
33
34 ** Bug Fixes
35
36+#28872: Mistake in "#safer" example in "Problems with -exec and
37+ filenames" section of the Texinfo manual.
38+
39 #28824: Corrected error message for "-ctime x".
40 Likewise for -gid, -inum, -links, -mmin, -cmin, -amin,
41 -uid, -used, -atime, -mtime, -ctime.
42diff --git a/doc/find.texi b/doc/find.texi
43index 2e5958d..391ffa0 100644
44--- a/doc/find.texi
45+++ b/doc/find.texi
46@@ -4830,8 +4830,8 @@ problem:
47
48 @example
49 # safer
50-find -exec sh -c 'something "$@@"' @{@} \;
51-find -execdir sh -c 'something "$@@"' @{@}\;
52+find -exec sh -c 'something "$@@"' sh @{@} \;
53+find -execdir sh -c 'something "$@@"' sh @{@}\;
54 @end example
55
56 This approach is not guaranteed to avoid every problem, but it is much