Add test case for Savannah bug #20803 (-prune return value)
[findutils.git] / lib / buildcmd.c
blobbda2492ac70be62b15f6fee32a815420c8411d66
1 /* buildcmd.c -- build command lines from a list of arguments.
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2005, 2006, 2007 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
19 XXX_SOC:
21 One of the aspects of the SOC project is to adapt this module.
22 This module currently makes an initial guess at two things:
24 buildcmd_control->arg_max (The most characters we can fit in)
25 buildcmd_control->max_arg_count (most args)
27 The nature of the SOC task is to adjust these values when exec fails.
28 Optionally (if we have the time) we can make the software adjust them
29 when exec succeeds. If we do the latter, we need to ensure we don't
30 get into some state where we are sitting just below the limit and
31 keep trying to extend, because that would lead to every other exec
32 failing.
34 If our initial guess is successful, there is no pressing need really to
35 increase our guess. Indeed, if we are beign called by xargs (as opposed
36 to find) th user may have specified a limit with "-s" and we should not
37 exceed it.
41 #include <config.h>
43 # ifndef PARAMS
44 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
45 # define PARAMS(Args) Args
46 # else
47 # define PARAMS(Args) ()
48 # endif
49 # endif
51 #include <string.h>
54 #if DO_MULTIBYTE
55 # if HAVE_MBRLEN
56 # include <wchar.h>
57 # else
58 /* Simulate mbrlen with mblen as best we can. */
59 # define mbstate_t int
60 # define mbrlen(s, n, ps) mblen (s, n)
61 # endif
62 #endif
64 #ifdef HAVE_LOCALE_H
65 #include <locale.h>
66 #endif
67 #if ENABLE_NLS
68 # include <libintl.h>
69 # define _(Text) gettext (Text)
70 #else
71 # define _(Text) Text
72 #define textdomain(Domain)
73 #define bindtextdomain(Package, Directory)
74 #endif
75 #ifdef gettext_noop
76 # define N_(String) gettext_noop (String)
77 #else
78 /* See locate.c for explanation as to why not use (String) */
79 # define N_(String) String
80 #endif
82 #ifndef _POSIX_SOURCE
83 #include <sys/param.h>
84 #endif
86 #ifdef HAVE_LIMITS_H
87 #include <limits.h>
88 #endif
90 /* The presence of unistd.h is assumed by gnulib these days, so we
91 * might as well assume it too.
93 /* for sysconf() */
94 #include <unistd.h>
96 #include <assert.h>
98 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
99 We try to make it as large as possible. See bc_get_arg_max() below. */
100 #if !defined(ARG_MAX) && defined(NCARGS)
101 #error "You have an unusual system. Once you remove this error message from buildcmd.c, it should work, but please make sure that DejaGnu is installed on your system and that 'make check' passes before using the findutils programs"
102 #define ARG_MAX NCARGS
103 #endif
107 #include <xalloc.h>
108 #include <error.h>
109 #include <openat.h>
111 #include "buildcmd.h"
114 extern char **environ;
117 /* Replace all instances of `replace_pat' in ARG with `linebuf',
118 and add the resulting string to the list of arguments for the command
119 to execute.
120 ARGLEN is the length of ARG, not including the null.
121 LBLEN is the length of LINEBUF, not including the null.
122 PFXLEN is the length of PREFIX. Substitution is not performed on
123 the prefix. The prefix is used if the argument contains replace_pat.
125 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
126 and a max of 5 occurrences of replace_pat in the initial-arguments.
127 Those restrictions do not exist here. */
129 void
130 bc_do_insert (const struct buildcmd_control *ctl,
131 struct buildcmd_state *state,
132 char *arg, size_t arglen,
133 const char *prefix, size_t pfxlen,
134 const char *linebuf, size_t lblen,
135 int initial_args)
137 /* Temporary copy of each arg with the replace pattern replaced by the
138 real arg. */
139 static char *insertbuf;
140 char *p;
141 size_t bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */
143 /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
144 * may have been set to LONG_MAX (see bc_get_arg_max()). Hence
145 * this xmalloc call may be a bad idea, especially since we are
146 * adding 1 to it...
148 if (!insertbuf)
149 insertbuf = xmalloc (ctl->arg_max + 1);
150 p = insertbuf;
154 size_t len; /* Length in ARG before `replace_pat'. */
155 char *s = mbsstr (arg, ctl->replace_pat);
156 if (s)
158 len = s - arg;
160 else
162 len = arglen;
165 if (bytes_left <= len)
166 break;
167 else
168 bytes_left -= len;
170 strncpy (p, arg, len);
171 p += len;
172 arg += len;
173 arglen -= len;
175 if (s)
177 if (bytes_left <= (lblen + pfxlen))
178 break;
179 else
180 bytes_left -= (lblen + pfxlen);
182 if (prefix)
184 strcpy (p, prefix);
185 p += pfxlen;
187 strcpy (p, linebuf);
188 p += lblen;
190 arg += ctl->rplen;
191 arglen -= ctl->rplen;
194 while (*arg);
195 if (*arg)
196 error (1, 0, _("command too long"));
197 *p++ = '\0';
199 bc_push_arg (ctl, state,
200 insertbuf, p - insertbuf,
201 NULL, 0,
202 initial_args);
205 static
206 void do_exec(const struct buildcmd_control *ctl,
207 struct buildcmd_state *state)
209 /* XXX_SOC:
211 Here we are calling the user's function. Currently there is no
212 way for it to report that the argument list was too long. We
213 should introduce an externally callable function that allows them
214 to report this.
216 If the callee does report that the exec failed, we need to retry
217 the exec with a shorter argument list. Once we have reduced the
218 argument list to the point where the exec can succeed, we need to
219 preserve the list of arguments we couldn't exec this time.
221 This also means that the control argument here probably needs not
222 to be const (since the limits are in the control arg).
224 The caller's only requirement on do_exec is that it should
225 free up enough room for at least one argument.
227 (ctl->exec_callback)(ctl, state);
231 /* Return nonzero if there would not be enough room for an additional
232 * argument. We check the total number of arguments only, not the space
233 * occupied by those arguments.
235 * If we return zero, there still may not be enough room for the next
236 * argument, depending on its length.
238 static int
239 bc_argc_limit_reached(int initial_args,
240 const struct buildcmd_control *ctl,
241 struct buildcmd_state *state)
243 /* Check to see if we about to exceed a limit set by xargs' -n option */
244 if (!initial_args && ctl->args_per_exec &&
245 ( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec))
246 return 1;
248 /* We deliberately use an equality test here rather than >= in order
249 * to force a software failure if the code is modified in such a way
250 * that it fails to call this function for every new argument.
252 return state->cmd_argc == ctl->max_arg_count;
256 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
257 to the command.
258 LEN is the length of ARG, including the terminating null.
259 If this brings the list up to its maximum size, execute the command.
261 /* XXX: sometimes this function is called (internally)
262 * just to push a NULL onto the and of the arg list.
263 * We should probably do that with a separate function
264 * for greater clarity.
266 void
267 bc_push_arg (const struct buildcmd_control *ctl,
268 struct buildcmd_state *state,
269 const char *arg, size_t len,
270 const char *prefix, size_t pfxlen,
271 int initial_args)
273 if (!initial_args)
275 state->todo = 1;
278 if (arg)
280 /* XXX_SOC: if do_exec() is only guaranteeed to free up one
281 * argument, this if statement may need to become a while loop.
282 * If it becomes a while loop, it needs not to be an infinite
283 * loop...
285 if (state->cmd_argv_chars + len > ctl->arg_max)
287 if (initial_args || state->cmd_argc == ctl->initial_argc)
288 error (1, 0, _("can not fit single argument within argument list size limit"));
289 /* xargs option -i (replace_pat) implies -x (exit_if_size_exceeded) */
290 if (ctl->replace_pat
291 || (ctl->exit_if_size_exceeded &&
292 (ctl->lines_per_exec || ctl->args_per_exec)))
293 error (1, 0, _("argument list too long"));
294 do_exec (ctl, state);
296 /* XXX_SOC: this if may also need to become a while loop. In
297 fact perhaps it is best to factor this out into a separate
298 function which ceeps calling the exec handler until there is
299 space for our next argument. Each exec will free one argc
300 "slot" so the main thing to worry about repeated exec calls
301 for would be total argument length.
303 if (bc_argc_limit_reached(initial_args, ctl, state))
304 do_exec (ctl, state);
307 if (state->cmd_argc >= state->cmd_argv_alloc)
309 /* XXX: we could use extendbuf() here. */
310 if (!state->cmd_argv)
312 state->cmd_argv_alloc = 64;
313 state->cmd_argv = xmalloc (sizeof (char *) * state->cmd_argv_alloc);
315 else
317 state->cmd_argv_alloc *= 2;
318 state->cmd_argv = xrealloc (state->cmd_argv,
319 sizeof (char *) * state->cmd_argv_alloc);
323 if (!arg)
324 state->cmd_argv[state->cmd_argc++] = NULL;
325 else
327 state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
328 if (prefix)
330 strcpy (state->argbuf + state->cmd_argv_chars, prefix);
331 state->cmd_argv_chars += pfxlen;
334 strcpy (state->argbuf + state->cmd_argv_chars, arg);
335 state->cmd_argv_chars += len;
337 /* If we have now collected enough arguments,
338 * do the exec immediately. This must be
339 * conditional on arg!=NULL, since do_exec()
340 * actually calls bc_push_arg(ctl, state, NULL, 0, false).
342 if (bc_argc_limit_reached(initial_args, ctl, state))
343 do_exec (ctl, state);
346 /* If this is an initial argument, set the high-water mark. */
347 if (initial_args)
349 state->cmd_initial_argv_chars = state->cmd_argv_chars;
353 #if 0
354 /* We used to set posix_arg_size_min to the LINE_MAX limit, but
355 * currently we use _POSIX_ARG_MAX (which is the minimum value).
357 static size_t
358 get_line_max(void)
360 long val;
361 #ifdef _SC_LINE_MAX
362 val = sysconf(_SC_LINE_MAX);
363 #else
364 val = -1;
365 #endif
367 if (val > 0)
368 return val;
370 /* either _SC_LINE_MAX was not available or
371 * there is no particular limit.
373 #ifdef LINE_MAX
374 val = LINE_MAX;
375 #endif
377 if (val > 0)
378 return val;
380 return 2048L; /* a reasonable guess. */
382 #endif
384 size_t
385 bc_get_arg_max(void)
387 long val;
389 /* We may resort to using LONG_MAX, so check it fits. */
390 /* XXX: better to do a compile-time check */
391 assert ( (~(size_t)0) >= LONG_MAX);
393 #ifdef _SC_ARG_MAX
394 val = sysconf(_SC_ARG_MAX);
395 #else
396 val = -1;
397 #endif
399 if (val > 0)
400 return val;
402 /* either _SC_ARG_MAX was not available or
403 * there is no particular limit.
405 #ifdef ARG_MAX
406 val = ARG_MAX;
407 #endif
409 if (val > 0)
410 return val;
412 /* The value returned by this function bounds the
413 * value applied as the ceiling for the -s option.
414 * Hence it the system won't tell us what its limit
415 * is, we allow the user to specify more or less
416 * whatever value they like.
418 return LONG_MAX;
422 static int cb_exec_noop(const struct buildcmd_control *ctl,
423 struct buildcmd_state *state)
425 /* does nothing. */
426 (void) ctl;
427 (void) state;
429 return 0;
433 /* Return how much of ARG_MAX is used by the environment. */
434 size_t
435 bc_size_of_environment (void)
437 size_t len = 0u;
438 char **envp = environ;
440 while (*envp)
441 len += strlen (*envp++) + 1;
443 return len;
447 enum BC_INIT_STATUS
448 bc_init_controlinfo(struct buildcmd_control *ctl,
449 size_t headroom)
451 size_t size_of_environment = bc_size_of_environment();
453 /* POSIX requires that _POSIX_ARG_MAX is 4096. That is the lowest
454 * possible value for ARG_MAX on a POSIX compliant system. See
455 * http://www.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
457 ctl->posix_arg_size_min = _POSIX_ARG_MAX;
458 ctl->posix_arg_size_max = bc_get_arg_max();
460 ctl->exit_if_size_exceeded = 0;
462 /* Take the size of the environment into account. */
463 if (size_of_environment > ctl->posix_arg_size_max)
465 return BC_INIT_ENV_TOO_BIG;
467 else if ((headroom + size_of_environment) >= ctl->posix_arg_size_max)
469 /* POSIX.2 requires xargs to subtract 2048, but ARG_MAX is
470 * guaranteed to be at least 4096. Although xargs could use an
471 * assertion here, we use a runtime check which returns an error
472 * code, because our caller may not be xargs.
474 return BC_INIT_CANNOT_ACCOMODATE_HEADROOM;
476 else
478 ctl->posix_arg_size_max -= size_of_environment;
479 ctl->posix_arg_size_max -= headroom;
482 /* need to subtract 2 on the following line - for Linux/PPC */
483 ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u;
484 assert (ctl->max_arg_count > 0);
485 ctl->rplen = 0u;
486 ctl->replace_pat = NULL;
487 ctl->initial_argc = 0;
488 ctl->exec_callback = cb_exec_noop;
489 ctl->lines_per_exec = 0;
490 ctl->args_per_exec = 0;
492 /* Set the initial value of arg_max to the largest value we can
493 * tolerate.
495 ctl->arg_max = ctl->posix_arg_size_max;
497 return BC_INIT_OK;
500 void
501 bc_use_sensible_arg_max(struct buildcmd_control *ctl)
503 #ifdef DEFAULT_ARG_SIZE
504 enum { arg_size = DEFAULT_ARG_SIZE };
505 #else
506 enum { arg_size = (128u * 1024u) };
507 #endif
509 /* Check against the upper and lower limits. */
510 if (arg_size > ctl->posix_arg_size_max)
511 ctl->arg_max = ctl->posix_arg_size_max;
512 else if (arg_size < ctl->posix_arg_size_min)
513 ctl->arg_max = ctl->posix_arg_size_min;
514 else
515 ctl->arg_max = arg_size;
521 void
522 bc_init_state(const struct buildcmd_control *ctl,
523 struct buildcmd_state *state,
524 void *context)
526 state->cmd_argc = 0;
527 state->cmd_argv_chars = 0;
528 state->cmd_argv = NULL;
529 state->cmd_argv_alloc = 0;
531 /* XXX: the following memory allocation is inadvisable on systems
532 * with no ARG_MAX, because ctl->arg_max may actually be close to
533 * LONG_MAX. Adding one to it is safe though because earlier we
534 * subtracted 2048.
536 assert (ctl->arg_max <= (LONG_MAX - 2048L));
537 state->argbuf = xmalloc (ctl->arg_max + 1u);
539 state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
540 state->todo = 0;
541 state->dirfd = -1;
542 state->usercontext = context;
545 void
546 bc_clear_args(const struct buildcmd_control *ctl,
547 struct buildcmd_state *state)
549 state->cmd_argc = ctl->initial_argc;
550 state->cmd_argv_chars = state->cmd_initial_argv_chars;
551 state->todo = 0;
552 state->dirfd = -1;