cvsimport
[findutils.git] / lib / buildcmd.c
blob751027885ac06c3b2566befc9359e31aefe30cde
1 /* buildcmd.c -- build command lines from a list of arguments.
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2005 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 2, or (at your option)
7 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, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17 USA.
21 XXX_SOC:
23 One of the aspects of the SOC project is to adapt this module.
24 This module currently makes an initial guess at two things:
26 buildcmd_control->arg_max (The most characters we can fit in)
27 buildcmd_control->max_arg_count (most args)
29 The nature of the SOC task is to adjust these values when exec fails.
30 Optionally (if we have the time) we can make the software adjust them
31 when exec succeeds. If we do the latter, we need to ensure we don't
32 get into some state where we are sitting just below the limit and
33 keep trying to extend, because that would lead to every other exec
34 failing.
36 If our initial guess is successful, there is no pressing need really to
37 increase our guess. Indeed, if we are beign called by xargs (as opposed
38 to find) th user may have specified a limit with "-s" and we should not
39 exceed it.
43 #include <config.h>
45 # ifndef PARAMS
46 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
47 # define PARAMS(Args) Args
48 # else
49 # define PARAMS(Args) ()
50 # endif
51 # endif
53 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
54 #include <string.h>
55 #endif
58 #if DO_MULTIBYTE
59 # if HAVE_MBRLEN
60 # include <wchar.h>
61 # else
62 /* Simulate mbrlen with mblen as best we can. */
63 # define mbstate_t int
64 # define mbrlen(s, n, ps) mblen (s, n)
65 # endif
66 #endif
68 #ifdef HAVE_LOCALE_H
69 #include <locale.h>
70 #endif
71 #if ENABLE_NLS
72 # include <libintl.h>
73 # define _(Text) gettext (Text)
74 #else
75 # define _(Text) Text
76 #define textdomain(Domain)
77 #define bindtextdomain(Package, Directory)
78 #endif
79 #ifdef gettext_noop
80 # define N_(String) gettext_noop (String)
81 #else
82 /* See locate.c for explanation as to why not use (String) */
83 # define N_(String) String
84 #endif
86 #ifndef _POSIX_SOURCE
87 #include <sys/param.h>
88 #endif
90 #ifdef HAVE_LIMITS_H
91 #include <limits.h>
92 #endif
94 /* The presence of unistd.h is assumed by gnulib these days, so we
95 * might as well assume it too.
97 /* for sysconf() */
98 #include <unistd.h>
100 #include <assert.h>
102 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
103 We try to make it as large as possible. */
104 #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
105 #define ARG_MAX sysconf (_SC_ARG_MAX)
106 #endif
107 #ifndef ARG_MAX
108 #define ARG_MAX NCARGS
109 #endif
113 #include <xalloc.h>
114 #include <error.h>
115 #include <openat.h>
117 #include "buildcmd.h"
120 extern char **environ;
123 static char *mbstrstr PARAMS ((const char *haystack, const char *needle));
125 /* Replace all instances of `replace_pat' in ARG with `linebuf',
126 and add the resulting string to the list of arguments for the command
127 to execute.
128 ARGLEN is the length of ARG, not including the null.
129 LBLEN is the length of LINEBUF, not including the null.
130 PFXLEN is the length of PREFIX. Substitution is not performed on
131 the prefix. The prefix is used if the argument contains replace_pat.
133 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
134 and a max of 5 occurrences of replace_pat in the initial-arguments.
135 Those restrictions do not exist here. */
137 void
138 bc_do_insert (const struct buildcmd_control *ctl,
139 struct buildcmd_state *state,
140 char *arg, size_t arglen,
141 const char *prefix, size_t pfxlen,
142 const char *linebuf, size_t lblen,
143 int initial_args)
145 /* Temporary copy of each arg with the replace pattern replaced by the
146 real arg. */
147 static char *insertbuf;
148 char *p;
149 size_t bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */
151 /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
152 * may have been set to LONG_MAX (see bc_get_arg_max()). Hence
153 * this xmalloc call may be a bad idea, especially since we are
154 * adding 1 to it...
156 if (!insertbuf)
157 insertbuf = (char *) xmalloc (ctl->arg_max + 1);
158 p = insertbuf;
162 size_t len; /* Length in ARG before `replace_pat'. */
163 char *s = mbstrstr (arg, ctl->replace_pat);
164 if (s)
166 len = s - arg;
168 else
170 len = arglen;
173 if (bytes_left <= len)
174 break;
175 else
176 bytes_left -= len;
178 strncpy (p, arg, len);
179 p += len;
180 arg += len;
181 arglen -= len;
183 if (s)
185 if (bytes_left <= (lblen + pfxlen))
186 break;
187 else
188 bytes_left -= (lblen + pfxlen);
190 if (prefix)
192 strcpy (p, prefix);
193 p += pfxlen;
195 strcpy (p, linebuf);
196 p += lblen;
198 arg += ctl->rplen;
199 arglen -= ctl->rplen;
202 while (*arg);
203 if (*arg)
204 error (1, 0, _("command too long"));
205 *p++ = '\0';
207 bc_push_arg (ctl, state,
208 insertbuf, p - insertbuf,
209 NULL, 0,
210 initial_args);
213 static
214 void do_exec(const struct buildcmd_control *ctl,
215 struct buildcmd_state *state)
217 /* XXX_SOC:
219 Here we are calling the user's function. Currently there is no
220 way for it to report that the argument list was too long. We
221 should introduce an externally callable function that allows them
222 to report this.
224 If the callee does report that the exec failed, we need to retry
225 the exec with a shorter argument list. Once we have reduced the
226 argument list to the point where the exec can succeed, we need to
227 preserve the list of arguments we couldn't exec this time.
229 This also means that the control argument here probably needs not
230 to be const (since the limits are in the control arg).
232 The caller's only requirement on do_exec is that it should
233 free up enough room for at least one argument.
235 (ctl->exec_callback)(ctl, state);
239 /* Return nonzero if there would not be enough room for an additional
240 * argument. We check the total number of arguments only, not the space
241 * occupied by those arguments.
243 * If we return zero, there still may not be enough room for the next
244 * argument, depending on its length.
246 static int
247 bc_argc_limit_reached(int initial_args,
248 const struct buildcmd_control *ctl,
249 struct buildcmd_state *state)
251 /* Check to see if we about to exceed a limit set by xargs' -n option */
252 if (!initial_args && ctl->args_per_exec &&
253 ( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec))
254 return 1;
256 /* We deliberately use an equality test here rather than >= in order
257 * to force a software failure if the code is modified in such a way
258 * that it fails to call this function for every new argument.
260 return state->cmd_argc == ctl->max_arg_count;
264 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
265 to the command.
266 LEN is the length of ARG, including the terminating null.
267 If this brings the list up to its maximum size, execute the command.
269 /* XXX: sometimes this function is called (internally)
270 * just to push a NULL onto the and of the arg list.
271 * We should probably do that with a separate function
272 * for greater clarity.
274 void
275 bc_push_arg (const struct buildcmd_control *ctl,
276 struct buildcmd_state *state,
277 const char *arg, size_t len,
278 const char *prefix, size_t pfxlen,
279 int initial_args)
281 if (!initial_args)
283 state->todo = 1;
286 if (arg)
288 /* XXX_SOC: if do_exec() is only guaranteeed to free up one
289 * argument, this if statement may need to become a while loop.
290 * If it becomes a while loop, it needs not to be an infinite
291 * loop...
293 if (state->cmd_argv_chars + len > ctl->arg_max)
295 if (initial_args || state->cmd_argc == ctl->initial_argc)
296 error (1, 0, _("can not fit single argument within argument list size limit"));
297 /* xargs option -i (replace_pat) implies -x (exit_if_size_exceeded) */
298 if (ctl->replace_pat
299 || (ctl->exit_if_size_exceeded &&
300 (ctl->lines_per_exec || ctl->args_per_exec)))
301 error (1, 0, _("argument list too long"));
302 do_exec (ctl, state);
304 /* XXX_SOC: this if may also need to become a while loop. In
305 fact perhaps it is best to factor this out into a separate
306 function which ceeps calling the exec handler until there is
307 space for our next argument. Each exec will free one argc
308 "slot" so the main thing to worry about repeated exec calls
309 for would be total argument length.
311 if (bc_argc_limit_reached(initial_args, ctl, state))
312 do_exec (ctl, state);
315 if (state->cmd_argc >= state->cmd_argv_alloc)
317 /* XXX: we could use extendbuf() here. */
318 if (!state->cmd_argv)
320 state->cmd_argv_alloc = 64;
321 state->cmd_argv = (char **) xmalloc (sizeof (char *) * state->cmd_argv_alloc);
323 else
325 state->cmd_argv_alloc *= 2;
326 state->cmd_argv = (char **) xrealloc (state->cmd_argv,
327 sizeof (char *) * state->cmd_argv_alloc);
331 if (!arg)
332 state->cmd_argv[state->cmd_argc++] = NULL;
333 else
335 state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
336 if (prefix)
338 strcpy (state->argbuf + state->cmd_argv_chars, prefix);
339 state->cmd_argv_chars += pfxlen;
342 strcpy (state->argbuf + state->cmd_argv_chars, arg);
343 state->cmd_argv_chars += len;
345 /* If we have now collected enough arguments,
346 * do the exec immediately. This must be
347 * conditional on arg!=NULL, since do_exec()
348 * actually calls bc_push_arg(ctl, state, NULL, 0, false).
350 if (bc_argc_limit_reached(initial_args, ctl, state))
351 do_exec (ctl, state);
354 /* If this is an initial argument, set the high-water mark. */
355 if (initial_args)
357 state->cmd_initial_argv_chars = state->cmd_argv_chars;
362 /* Finds the first occurrence of the substring NEEDLE in the string
363 HAYSTACK. Both strings can be multibyte strings. */
364 /* XXX: gnulib probably offers this. We'll probably remove
365 * this from trunk 4.3.x development.
367 static char *
368 mbstrstr (const char *haystack, const char *needle)
370 #if DO_MULTIBYTE
371 if (MB_CUR_MAX > 1)
373 size_t hlen = strlen (haystack);
374 size_t nlen = strlen (needle);
375 mbstate_t mbstate;
376 size_t step;
378 memset (&mbstate, 0, sizeof (mbstate_t));
379 while (hlen >= nlen)
381 if (memcmp (haystack, needle, nlen) == 0)
382 return (char *) haystack;
383 step = mbrlen (haystack, hlen, &mbstate);
384 if (step <= 0)
385 break;
386 haystack += step;
387 hlen -= step;
389 return NULL;
391 #endif
392 return strstr (haystack, needle);
395 static size_t
396 get_line_max(void)
398 long val;
399 #ifdef _SC_LINE_MAX
400 val = sysconf(_SC_LINE_MAX);
401 #else
402 val = -1;
403 #endif
405 if (val > 0)
406 return val;
408 /* either _SC_LINE_MAX was not available or
409 * there is no particular limit.
411 #ifdef LINE_MAX
412 val = LINE_MAX;
413 #endif
415 if (val > 0)
416 return val;
418 return 2048L; /* a reasonable guess. */
422 size_t
423 bc_get_arg_max(void)
425 long val;
427 /* We may resort to using LONG_MAX, so check it fits. */
428 /* XXX: better to do a compile-time check */
429 assert( (~(size_t)0) >= LONG_MAX);
431 #ifdef _SC_ARG_MAX
432 val = sysconf(_SC_ARG_MAX);
433 #else
434 val = -1;
435 #endif
437 if (val > 0)
438 return val;
440 /* either _SC_ARG_MAX was not available or
441 * there is no particular limit.
443 #ifdef ARG_MAX
444 val = ARG_MAX;
445 #endif
447 if (val > 0)
448 return val;
450 /* The value returned by this function bounds the
451 * value applied as the ceiling for the -s option.
452 * Hence it the system won't tell us what its limit
453 * is, we allow the user to specify more or less
454 * whatever value they like.
456 return LONG_MAX;
460 static int cb_exec_noop(const struct buildcmd_control *ctl,
461 struct buildcmd_state *state)
463 /* does nothing. */
464 (void) ctl;
465 (void) state;
467 return 0;
471 /* Return how much of ARG_MAX is used by the environment. */
472 size_t
473 bc_size_of_environment (void)
475 size_t len = 0u;
476 char **envp = environ;
478 while (*envp)
479 len += strlen (*envp++) + 1;
481 return len;
485 enum BC_INIT_STATUS
486 bc_init_controlinfo(struct buildcmd_control *ctl)
488 size_t size_of_environment = bc_size_of_environment();
489 size_t arg_max;
491 ctl->posix_arg_size_min = get_line_max();
492 arg_max = bc_get_arg_max();
494 /* POSIX.2 requires subtracting 2048. */
495 assert(arg_max > 2048u); /* XXX: this is an external condition, should not check it with assert. */
496 ctl->posix_arg_size_max = (arg_max - 2048);
498 ctl->exit_if_size_exceeded = 0;
500 /* Take the size of the environment into account. */
501 if (size_of_environment > ctl->posix_arg_size_max)
503 return BC_INIT_ENV_TOO_BIG;
505 else
507 #warning the next line is probably a bug.
508 /* Probably should be "-=" not "-". */
509 ctl->posix_arg_size_max - size_of_environment;
512 /* need to subtract 2 on the following line - for Linux/PPC */
513 ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u;
514 assert(ctl->max_arg_count > 0);
515 ctl->rplen = 0u;
516 ctl->replace_pat = NULL;
517 ctl->initial_argc = 0;
518 ctl->exec_callback = cb_exec_noop;
519 ctl->lines_per_exec = 0;
520 ctl->args_per_exec = 0;
522 /* Set the initial value of arg_max to the largest value we can
523 * tolerate.
525 ctl->arg_max = ctl->posix_arg_size_max;
527 return BC_INIT_OK;
530 void
531 bc_use_sensible_arg_max(struct buildcmd_control *ctl)
533 size_t env_size = bc_size_of_environment();
534 const size_t arg_size = (128u * 1024u) + env_size;
536 /* Check against the upper and lower limits. */
537 if (arg_size > ctl->posix_arg_size_max)
538 ctl->arg_max = ctl->posix_arg_size_max - env_size;
539 else if (arg_size < ctl->posix_arg_size_min)
540 ctl->arg_max = ctl->posix_arg_size_min;
541 else
542 ctl->arg_max = arg_size;
548 void
549 bc_init_state(const struct buildcmd_control *ctl,
550 struct buildcmd_state *state,
551 void *context)
553 state->cmd_argc = 0;
554 state->cmd_argv_chars = 0;
555 state->cmd_argv = NULL;
556 state->cmd_argv_alloc = 0;
558 /* XXX: the following memory allocation is inadvisable on systems
559 * with no ARG_MAX, because ctl->arg_max may actually be close to
560 * LONG_MAX. Adding one to it is safe though because earlier we
561 * subtracted 2048.
563 assert(ctl->arg_max <= (LONG_MAX - 2048L));
564 state->argbuf = (char *) xmalloc (ctl->arg_max + 1u);
566 state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
567 state->todo = 0;
568 state->dirfd = -1;
569 state->usercontext = context;
572 void
573 bc_clear_args(const struct buildcmd_control *ctl,
574 struct buildcmd_state *state)
576 state->cmd_argc = ctl->initial_argc;
577 state->cmd_argv_chars = state->cmd_initial_argv_chars;
578 state->todo = 0;
579 state->dirfd = -1;