Applied patch from Jim Meyering; rename dirfd to dir_fd to avoid shadowing problem
[findutils.git] / lib / buildcmd.c
blob6c6a9c440e5f617cbce00029652fe69660248bba
1 /* buildcmd.c -- build command lines from a list of arguments.
2 Copyright (C) 1990, 91, 92, 93, 94, 2000, 2003, 2005, 2006,
3 2007, 2008 Free Software Foundation, Inc.
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 XXX_SOC:
22 One of the aspects of the SOC project is to adapt this module.
23 This module currently makes an initial guess at two things:
25 buildcmd_control->arg_max (The most characters we can fit in)
26 buildcmd_control->max_arg_count (most args)
28 The nature of the SOC task is to adjust these values when exec fails.
29 Optionally (if we have the time) we can make the software adjust them
30 when exec succeeds. If we do the latter, we need to ensure we don't
31 get into some state where we are sitting just below the limit and
32 keep trying to extend, because that would lead to every other exec
33 failing.
35 If our initial guess is successful, there is no pressing need really to
36 increase our guess. Indeed, if we are beign called by xargs (as opposed
37 to find) th user may have specified a limit with "-s" and we should not
38 exceed it.
42 #include <config.h>
44 # ifndef PARAMS
45 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
46 # define PARAMS(Args) Args
47 # else
48 # define PARAMS(Args) ()
49 # endif
50 # endif
52 #include <string.h>
55 #if DO_MULTIBYTE
56 # if HAVE_MBRLEN
57 # include <wchar.h>
58 # else
59 /* Simulate mbrlen with mblen as best we can. */
60 # define mbstate_t int
61 # define mbrlen(s, n, ps) mblen (s, n)
62 # endif
63 #endif
65 #ifdef HAVE_LOCALE_H
66 #include <locale.h>
67 #endif
68 #if ENABLE_NLS
69 # include <libintl.h>
70 # define _(Text) gettext (Text)
71 #else
72 # define _(Text) Text
73 #define textdomain(Domain)
74 #define bindtextdomain(Package, Directory)
75 #endif
76 #ifdef gettext_noop
77 # define N_(String) gettext_noop (String)
78 #else
79 /* See locate.c for explanation as to why not use (String) */
80 # define N_(String) String
81 #endif
83 #ifndef _POSIX_SOURCE
84 #include <sys/param.h>
85 #endif
87 #ifdef HAVE_LIMITS_H
88 #include <limits.h>
89 #endif
91 /* The presence of unistd.h is assumed by gnulib these days, so we
92 * might as well assume it too.
94 /* for sysconf() */
95 #include <unistd.h>
97 #include <assert.h>
99 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
100 We try to make it as large as possible. See bc_get_arg_max() below. */
101 #if !defined(ARG_MAX) && defined(NCARGS)
102 #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"
103 #define ARG_MAX NCARGS
104 #endif
108 #include <xalloc.h>
109 #include <error.h>
110 #include <openat.h>
112 #include "buildcmd.h"
115 extern char **environ;
118 /* Replace all instances of `replace_pat' in ARG with `linebuf',
119 and add the resulting string to the list of arguments for the command
120 to execute.
121 ARGLEN is the length of ARG, not including the null.
122 LBLEN is the length of LINEBUF, not including the null.
123 PFXLEN is the length of PREFIX. Substitution is not performed on
124 the prefix. The prefix is used if the argument contains replace_pat.
126 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
127 and a max of 5 occurrences of replace_pat in the initial-arguments.
128 Those restrictions do not exist here. */
130 void
131 bc_do_insert (const struct buildcmd_control *ctl,
132 struct buildcmd_state *state,
133 char *arg, size_t arglen,
134 const char *prefix, size_t pfxlen,
135 const char *linebuf, size_t lblen,
136 int initial_args)
138 /* Temporary copy of each arg with the replace pattern replaced by the
139 real arg. */
140 static char *insertbuf;
141 char *p;
142 size_t bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */
144 /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
145 * may have been set to LONG_MAX (see bc_get_arg_max()). Hence
146 * this xmalloc call may be a bad idea, especially since we are
147 * adding 1 to it...
149 if (!insertbuf)
150 insertbuf = xmalloc (ctl->arg_max + 1);
151 p = insertbuf;
155 size_t len; /* Length in ARG before `replace_pat'. */
156 char *s = mbsstr (arg, ctl->replace_pat);
157 if (s)
159 len = s - arg;
161 else
163 len = arglen;
166 if (bytes_left <= len)
167 break;
168 else
169 bytes_left -= len;
171 strncpy (p, arg, len);
172 p += len;
173 arg += len;
174 arglen -= len;
176 if (s)
178 if (bytes_left <= (lblen + pfxlen))
179 break;
180 else
181 bytes_left -= (lblen + pfxlen);
183 if (prefix)
185 strcpy (p, prefix);
186 p += pfxlen;
188 strcpy (p, linebuf);
189 p += lblen;
191 arg += ctl->rplen;
192 arglen -= ctl->rplen;
195 while (*arg);
196 if (*arg)
197 error (1, 0, _("command too long"));
198 *p++ = '\0';
200 bc_push_arg (ctl, state,
201 insertbuf, p - insertbuf,
202 NULL, 0,
203 initial_args);
206 static
207 void do_exec(const struct buildcmd_control *ctl,
208 struct buildcmd_state *state)
210 /* XXX_SOC:
212 Here we are calling the user's function. Currently there is no
213 way for it to report that the argument list was too long. We
214 should introduce an externally callable function that allows them
215 to report this.
217 If the callee does report that the exec failed, we need to retry
218 the exec with a shorter argument list. Once we have reduced the
219 argument list to the point where the exec can succeed, we need to
220 preserve the list of arguments we couldn't exec this time.
222 This also means that the control argument here probably needs not
223 to be const (since the limits are in the control arg).
225 The caller's only requirement on do_exec is that it should
226 free up enough room for at least one argument.
228 (ctl->exec_callback)(ctl, state);
232 /* Return nonzero if there would not be enough room for an additional
233 * argument. We check the total number of arguments only, not the space
234 * occupied by those arguments.
236 * If we return zero, there still may not be enough room for the next
237 * argument, depending on its length.
239 static int
240 bc_argc_limit_reached(int initial_args,
241 const struct buildcmd_control *ctl,
242 struct buildcmd_state *state)
244 /* Check to see if we about to exceed a limit set by xargs' -n option */
245 if (!initial_args && ctl->args_per_exec &&
246 ( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec))
247 return 1;
249 /* We deliberately use an equality test here rather than >= in order
250 * to force a software failure if the code is modified in such a way
251 * that it fails to call this function for every new argument.
253 return state->cmd_argc == ctl->max_arg_count;
257 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
258 to the command.
259 LEN is the length of ARG, including the terminating null.
260 If this brings the list up to its maximum size, execute the command.
262 /* XXX: sometimes this function is called (internally)
263 * just to push a NULL onto the and of the arg list.
264 * We should probably do that with a separate function
265 * for greater clarity.
267 void
268 bc_push_arg (const struct buildcmd_control *ctl,
269 struct buildcmd_state *state,
270 const char *arg, size_t len,
271 const char *prefix, size_t pfxlen,
272 int initial_args)
274 if (!initial_args)
276 state->todo = 1;
279 if (arg)
281 /* XXX_SOC: if do_exec() is only guaranteeed to free up one
282 * argument, this if statement may need to become a while loop.
283 * If it becomes a while loop, it needs not to be an infinite
284 * loop...
286 if (state->cmd_argv_chars + len > ctl->arg_max)
288 if (initial_args || state->cmd_argc == ctl->initial_argc)
289 error (1, 0, _("can not fit single argument within argument list size limit"));
290 /* xargs option -i (replace_pat) implies -x (exit_if_size_exceeded) */
291 if (ctl->replace_pat
292 || (ctl->exit_if_size_exceeded &&
293 (ctl->lines_per_exec || ctl->args_per_exec)))
294 error (1, 0, _("argument list too long"));
295 do_exec (ctl, state);
297 /* XXX_SOC: this if may also need to become a while loop. In
298 fact perhaps it is best to factor this out into a separate
299 function which ceeps calling the exec handler until there is
300 space for our next argument. Each exec will free one argc
301 "slot" so the main thing to worry about repeated exec calls
302 for would be total argument length.
304 if (bc_argc_limit_reached(initial_args, ctl, state))
305 do_exec (ctl, state);
308 if (state->cmd_argc >= state->cmd_argv_alloc)
310 /* XXX: we could use extendbuf() here. */
311 if (!state->cmd_argv)
313 state->cmd_argv_alloc = 64;
314 state->cmd_argv = xmalloc (sizeof (char *) * state->cmd_argv_alloc);
316 else
318 state->cmd_argv_alloc *= 2;
319 state->cmd_argv = xrealloc (state->cmd_argv,
320 sizeof (char *) * state->cmd_argv_alloc);
324 if (!arg)
325 state->cmd_argv[state->cmd_argc++] = NULL;
326 else
328 state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
329 if (prefix)
331 strcpy (state->argbuf + state->cmd_argv_chars, prefix);
332 state->cmd_argv_chars += pfxlen;
335 strcpy (state->argbuf + state->cmd_argv_chars, arg);
336 state->cmd_argv_chars += len;
338 /* If we have now collected enough arguments,
339 * do the exec immediately. This must be
340 * conditional on arg!=NULL, since do_exec()
341 * actually calls bc_push_arg(ctl, state, NULL, 0, false).
343 if (bc_argc_limit_reached(initial_args, ctl, state))
344 do_exec (ctl, state);
347 /* If this is an initial argument, set the high-water mark. */
348 if (initial_args)
350 state->cmd_initial_argv_chars = state->cmd_argv_chars;
354 #if 0
355 /* We used to set posix_arg_size_min to the LINE_MAX limit, but
356 * currently we use _POSIX_ARG_MAX (which is the minimum value).
358 static size_t
359 get_line_max(void)
361 long val;
362 #ifdef _SC_LINE_MAX
363 val = sysconf(_SC_LINE_MAX);
364 #else
365 val = -1;
366 #endif
368 if (val > 0)
369 return val;
371 /* either _SC_LINE_MAX was not available or
372 * there is no particular limit.
374 #ifdef LINE_MAX
375 val = LINE_MAX;
376 #endif
378 if (val > 0)
379 return val;
381 return 2048L; /* a reasonable guess. */
383 #endif
385 size_t
386 bc_get_arg_max(void)
388 long val;
390 /* We may resort to using LONG_MAX, so check it fits. */
391 /* XXX: better to do a compile-time check */
392 assert ( (~(size_t)0) >= LONG_MAX);
394 #ifdef _SC_ARG_MAX
395 val = sysconf(_SC_ARG_MAX);
396 #else
397 val = -1;
398 #endif
400 if (val > 0)
401 return val;
403 /* either _SC_ARG_MAX was not available or
404 * there is no particular limit.
406 #ifdef ARG_MAX
407 val = ARG_MAX;
408 #endif
410 if (val > 0)
411 return val;
413 /* The value returned by this function bounds the
414 * value applied as the ceiling for the -s option.
415 * Hence it the system won't tell us what its limit
416 * is, we allow the user to specify more or less
417 * whatever value they like.
419 return LONG_MAX;
423 static int cb_exec_noop(const struct buildcmd_control *ctl,
424 struct buildcmd_state *state)
426 /* does nothing. */
427 (void) ctl;
428 (void) state;
430 return 0;
434 /* Return how much of ARG_MAX is used by the environment. */
435 size_t
436 bc_size_of_environment (void)
438 size_t len = 0u;
439 char **envp = environ;
441 while (*envp)
442 len += strlen (*envp++) + 1;
444 return len;
448 enum BC_INIT_STATUS
449 bc_init_controlinfo(struct buildcmd_control *ctl,
450 size_t headroom)
452 size_t size_of_environment = bc_size_of_environment();
454 /* POSIX requires that _POSIX_ARG_MAX is 4096. That is the lowest
455 * possible value for ARG_MAX on a POSIX compliant system. See
456 * http://www.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
458 ctl->posix_arg_size_min = _POSIX_ARG_MAX;
459 ctl->posix_arg_size_max = bc_get_arg_max();
461 ctl->exit_if_size_exceeded = 0;
463 /* Take the size of the environment into account. */
464 if (size_of_environment > ctl->posix_arg_size_max)
466 return BC_INIT_ENV_TOO_BIG;
468 else if ((headroom + size_of_environment) >= ctl->posix_arg_size_max)
470 /* POSIX.2 requires xargs to subtract 2048, but ARG_MAX is
471 * guaranteed to be at least 4096. Although xargs could use an
472 * assertion here, we use a runtime check which returns an error
473 * code, because our caller may not be xargs.
475 return BC_INIT_CANNOT_ACCOMODATE_HEADROOM;
477 else
479 ctl->posix_arg_size_max -= size_of_environment;
480 ctl->posix_arg_size_max -= headroom;
483 /* need to subtract 2 on the following line - for Linux/PPC */
484 ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u;
485 assert (ctl->max_arg_count > 0);
486 ctl->rplen = 0u;
487 ctl->replace_pat = NULL;
488 ctl->initial_argc = 0;
489 ctl->exec_callback = cb_exec_noop;
490 ctl->lines_per_exec = 0;
491 ctl->args_per_exec = 0;
493 /* Set the initial value of arg_max to the largest value we can
494 * tolerate.
496 ctl->arg_max = ctl->posix_arg_size_max;
498 return BC_INIT_OK;
501 void
502 bc_use_sensible_arg_max(struct buildcmd_control *ctl)
504 #ifdef DEFAULT_ARG_SIZE
505 enum { arg_size = DEFAULT_ARG_SIZE };
506 #else
507 enum { arg_size = (128u * 1024u) };
508 #endif
510 /* Check against the upper and lower limits. */
511 if (arg_size > ctl->posix_arg_size_max)
512 ctl->arg_max = ctl->posix_arg_size_max;
513 else if (arg_size < ctl->posix_arg_size_min)
514 ctl->arg_max = ctl->posix_arg_size_min;
515 else
516 ctl->arg_max = arg_size;
522 void
523 bc_init_state(const struct buildcmd_control *ctl,
524 struct buildcmd_state *state,
525 void *context)
527 state->cmd_argc = 0;
528 state->cmd_argv_chars = 0;
529 state->cmd_argv = NULL;
530 state->cmd_argv_alloc = 0;
532 /* XXX: the following memory allocation is inadvisable on systems
533 * with no ARG_MAX, because ctl->arg_max may actually be close to
534 * LONG_MAX. Adding one to it is safe though because earlier we
535 * subtracted 2048.
537 assert (ctl->arg_max <= (LONG_MAX - 2048L));
538 state->argbuf = xmalloc (ctl->arg_max + 1u);
540 state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
541 state->todo = 0;
542 state->dir_fd = -1;
543 state->usercontext = context;
546 void
547 bc_clear_args(const struct buildcmd_control *ctl,
548 struct buildcmd_state *state)
550 state->cmd_argc = ctl->initial_argc;
551 state->cmd_argv_chars = state->cmd_initial_argv_chars;
552 state->todo = 0;
553 state->dir_fd = -1;