Merged some changes from the 4.2 branch:
[findutils.git] / lib / buildcmd.c
blob0bf716d82b0fde6c7815b11fe70e77c7169bf750
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.
20 #include <config.h>
22 # ifndef PARAMS
23 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
24 # define PARAMS(Args) Args
25 # else
26 # define PARAMS(Args) ()
27 # endif
28 # endif
30 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
31 #include <string.h>
32 #endif
35 #if DO_MULTIBYTE
36 # if HAVE_MBRLEN
37 # include <wchar.h>
38 # else
39 /* Simulate mbrlen with mblen as best we can. */
40 # define mbstate_t int
41 # define mbrlen(s, n, ps) mblen (s, n)
42 # endif
43 #endif
45 #ifdef HAVE_LOCALE_H
46 #include <locale.h>
47 #endif
48 #if ENABLE_NLS
49 # include <libintl.h>
50 # define _(Text) gettext (Text)
51 #else
52 # define _(Text) Text
53 #define textdomain(Domain)
54 #define bindtextdomain(Package, Directory)
55 #endif
56 #ifdef gettext_noop
57 # define N_(String) gettext_noop (String)
58 #else
59 /* See locate.c for explanation as to why not use (String) */
60 # define N_(String) String
61 #endif
63 #ifndef _POSIX_SOURCE
64 #include <sys/param.h>
65 #endif
67 #ifdef HAVE_LIMITS_H
68 #include <limits.h>
69 #endif
71 /* The presence of unistd.h is assumed by gnulib these days, so we
72 * might as well assume it too.
74 /* for sysconf() */
75 #include <unistd.h>
77 #include <assert.h>
79 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
80 We try to make it as large as possible. */
81 #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
82 #define ARG_MAX sysconf (_SC_ARG_MAX)
83 #endif
84 #ifndef ARG_MAX
85 #define ARG_MAX NCARGS
86 #endif
90 #include <xalloc.h>
91 #include <error.h>
93 #include "buildcmd.h"
96 extern char **environ;
99 static char *mbstrstr PARAMS ((const char *haystack, const char *needle));
101 /* Replace all instances of `replace_pat' in ARG with `linebuf',
102 and add the resulting string to the list of arguments for the command
103 to execute.
104 ARGLEN is the length of ARG, not including the null.
105 LBLEN is the length of LINEBUF, not including the null.
106 PFXLEN is the length of PREFIX. Substitution is not performed on
107 the prefix. The prefix is used if the argument contains replace_pat.
109 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
110 and a max of 5 occurrences of replace_pat in the initial-arguments.
111 Those restrictions do not exist here. */
113 void
114 bc_do_insert (const struct buildcmd_control *ctl,
115 struct buildcmd_state *state,
116 char *arg, size_t arglen,
117 const char *prefix, size_t pfxlen,
118 const char *linebuf, size_t lblen,
119 int initial_args)
121 /* Temporary copy of each arg with the replace pattern replaced by the
122 real arg. */
123 static char *insertbuf;
124 char *p;
125 size_t bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */
126 int need_prefix;
128 /* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
129 * may have been set to LONG_MAX (see bc_get_arg_max()). Hence
130 * this xmalloc call may be a bad idea, especially since we are
131 * adding 1 to it...
133 if (!insertbuf)
134 insertbuf = (char *) xmalloc (ctl->arg_max + 1);
135 p = insertbuf;
137 need_prefix = 0;
140 size_t len; /* Length in ARG before `replace_pat'. */
141 char *s = mbstrstr (arg, ctl->replace_pat);
142 if (s)
144 need_prefix = 1;
145 len = s - arg;
147 else
149 len = arglen;
152 if (bytes_left <= len)
153 break;
154 else
155 bytes_left -= len;
157 strncpy (p, arg, len);
158 p += len;
159 arg += len;
160 arglen -= len;
162 if (s)
164 if (bytes_left <= lblen)
165 break;
166 else
167 bytes_left -= lblen;
169 strcpy (p, linebuf);
170 arg += ctl->rplen;
171 arglen -= ctl->rplen;
172 p += lblen;
175 while (*arg);
176 if (*arg)
177 error (1, 0, _("command too long"));
178 *p++ = '\0';
180 if (!need_prefix)
182 prefix = NULL;
183 pfxlen = 0;
186 bc_push_arg (ctl, state,
187 insertbuf, p - insertbuf,
188 prefix, pfxlen,
189 initial_args);
192 static
193 void do_exec(const struct buildcmd_control *ctl,
194 struct buildcmd_state *state)
196 (ctl->exec_callback)(ctl, state);
200 /* Return nonzero if there would not be enough room for an additional
201 * argument. We check the total number of arguments only, not the space
202 * occupied by those arguments.
204 * If we return zero, there still may not be enough room for the next
205 * argument, depending on its length.
207 static int
208 bc_argc_limit_reached(int initial_args,
209 const struct buildcmd_control *ctl,
210 struct buildcmd_state *state)
212 /* Check to see if we about to exceed a limit set by xargs' -n option */
213 if (!initial_args && ctl->args_per_exec &&
214 ( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec))
215 return 1;
217 /* We deliberately use an equality test here rather than >= in order
218 * to force a software failure if the code is modified in such a way
219 * that it fails to call this function for every new argument.
221 return state->cmd_argc == ctl->max_arg_count;
225 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
226 to the command.
227 LEN is the length of ARG, including the terminating null.
228 If this brings the list up to its maximum size, execute the command. */
230 void
231 bc_push_arg (const struct buildcmd_control *ctl,
232 struct buildcmd_state *state,
233 const char *arg, size_t len,
234 const char *prefix, size_t pfxlen,
235 int initial_args)
237 if (!initial_args)
238 state->todo = 1;
240 if (arg)
242 if (state->cmd_argv_chars + len > ctl->arg_max)
244 if (initial_args || state->cmd_argc == ctl->initial_argc)
245 error (1, 0, _("can not fit single argument within argument list size limit"));
246 /* option -i (replace_pat) implies -x (exit_if_size_exceeded) */
247 if (ctl->replace_pat
248 || (ctl->exit_if_size_exceeded &&
249 (ctl->lines_per_exec || ctl->args_per_exec)))
250 error (1, 0, _("argument list too long"));
251 do_exec (ctl, state);
254 if (bc_argc_limit_reached(initial_args, ctl, state))
255 do_exec (ctl, state);
258 if (state->cmd_argc >= state->cmd_argv_alloc)
260 if (!state->cmd_argv)
262 state->cmd_argv_alloc = 64;
263 state->cmd_argv = (char **) xmalloc (sizeof (char *) * state->cmd_argv_alloc);
265 else
267 state->cmd_argv_alloc *= 2;
268 state->cmd_argv = (char **) xrealloc (state->cmd_argv,
269 sizeof (char *) * state->cmd_argv_alloc);
273 if (!arg)
274 state->cmd_argv[state->cmd_argc++] = NULL;
275 else
277 state->cmd_argv[state->cmd_argc++] = state->argbuf + state->cmd_argv_chars;
278 if (prefix)
280 strcpy (state->argbuf + state->cmd_argv_chars, prefix);
281 state->cmd_argv_chars += pfxlen;
284 strcpy (state->argbuf + state->cmd_argv_chars, arg);
285 state->cmd_argv_chars += len;
287 /* If we have now collected enough arguments,
288 * do the exec immediately. This must be
289 * conditional on arg!=NULL, since do_exec()
290 * actually calls bc_push_arg(ctl, state, NULL, 0, false).
292 if (bc_argc_limit_reached(initial_args, ctl, state))
293 do_exec (ctl, state);
296 /* If this is an initial argument, set the high-water mark. */
297 if (initial_args)
299 state->cmd_initial_argv_chars = state->cmd_argv_chars;
304 /* Finds the first occurrence of the substring NEEDLE in the string
305 HAYSTACK. Both strings can be multibyte strings. */
307 static char *
308 mbstrstr (const char *haystack, const char *needle)
310 #if DO_MULTIBYTE
311 if (MB_CUR_MAX > 1)
313 size_t hlen = strlen (haystack);
314 size_t nlen = strlen (needle);
315 mbstate_t mbstate;
316 size_t step;
318 memset (&mbstate, 0, sizeof (mbstate_t));
319 while (hlen >= nlen)
321 if (memcmp (haystack, needle, nlen) == 0)
322 return (char *) haystack;
323 step = mbrlen (haystack, hlen, &mbstate);
324 if (step <= 0)
325 break;
326 haystack += step;
327 hlen -= step;
329 return NULL;
331 #endif
332 return strstr (haystack, needle);
335 static size_t
336 get_line_max(void)
338 long val;
339 #ifdef _SC_LINE_MAX
340 val = sysconf(_SC_LINE_MAX);
341 #else
342 val = -1;
343 #endif
345 if (val > 0)
346 return val;
348 /* either _SC_LINE_MAX was not available or
349 * there is no particular limit.
351 #ifdef LINE_MAX
352 val = LINE_MAX;
353 #endif
355 if (val > 0)
356 return val;
358 return 2048L; /* a reasonable guess. */
362 size_t
363 bc_get_arg_max(void)
365 long val;
367 /* We may resort to using LONG_MAX, so check it fits. */
368 /* XXX: better to do a compile-time check */
369 assert( (~(size_t)0) >= LONG_MAX);
371 #ifdef _SC_ARG_MAX
372 val = sysconf(_SC_ARG_MAX);
373 #else
374 val = -1;
375 #endif
377 if (val > 0)
378 return val;
380 /* either _SC_ARG_MAX was not available or
381 * there is no particular limit.
383 #ifdef ARG_MAX
384 val = ARG_MAX;
385 #endif
387 if (val > 0)
388 return val;
390 /* The value returned by this function bounds the
391 * value applied as the ceiling for the -s option.
392 * Hence it the system won't tell us what its limit
393 * is, we allow the user to specify more or less
394 * whatever value they like.
396 return LONG_MAX;
400 static int cb_exec_noop(const struct buildcmd_control *ctl,
401 struct buildcmd_state *state)
403 /* does nothing. */
404 (void) ctl;
405 (void) state;
407 return 0;
411 /* Return how much of ARG_MAX is used by the environment. */
412 size_t
413 bc_size_of_environment (void)
415 size_t len = 0u;
416 char **envp = environ;
418 while (*envp)
419 len += strlen (*envp++) + 1;
421 return len;
425 enum BC_INIT_STATUS
426 bc_init_controlinfo(struct buildcmd_control *ctl)
428 size_t size_of_environment = bc_size_of_environment();
429 size_t arg_max;
431 ctl->posix_arg_size_min = get_line_max();
432 arg_max = bc_get_arg_max();
434 /* POSIX.2 requires subtracting 2048. */
435 assert(arg_max > 2048u); /* XXX: this is an external condition, should not check it with assert. */
436 ctl->posix_arg_size_max = (arg_max - 2048);
438 ctl->exit_if_size_exceeded = 0;
440 /* Take the size of the environment into account. */
441 if (size_of_environment > ctl->posix_arg_size_max)
443 return BC_INIT_ENV_TOO_BIG;
445 else
447 ctl->posix_arg_size_max - size_of_environment;
450 /* need to subtract 2 on the following line - for Linux/PPC */
451 ctl->max_arg_count = (ctl->posix_arg_size_max / sizeof(char*)) - 2u;
452 assert(ctl->max_arg_count > 0);
453 ctl->rplen = 0u;
454 ctl->replace_pat = NULL;
455 ctl->initial_argc = 0;
456 ctl->exec_callback = cb_exec_noop;
457 ctl->lines_per_exec = 0;
458 ctl->args_per_exec = 0;
460 /* Set the initial value of arg_max to the largest value we can
461 * tolerate.
463 ctl->arg_max = ctl->posix_arg_size_max;
465 return BC_INIT_OK;
468 void
469 bc_use_sensible_arg_max(struct buildcmd_control *ctl)
471 size_t env_size = bc_size_of_environment();
472 const size_t arg_size = (128u * 1024u) + env_size;
474 /* Check against the upper and lower limits. */
475 if (arg_size > ctl->posix_arg_size_max)
476 ctl->arg_max = ctl->posix_arg_size_max - env_size;
477 else if (arg_size < ctl->posix_arg_size_min)
478 ctl->arg_max = ctl->posix_arg_size_min;
479 else
480 ctl->arg_max = arg_size;
486 void
487 bc_init_state(const struct buildcmd_control *ctl,
488 struct buildcmd_state *state,
489 void *context)
491 state->cmd_argc = 0;
492 state->cmd_argv_chars = 0;
493 state->cmd_argv = NULL;
494 state->cmd_argv_alloc = 0;
496 /* XXX: the following memory allocation is inadvisable on systems
497 * with no ARG_MAX, because ctl->arg_max may actually be close to
498 * LONG_MAX. Adding one to it is safe though because earlier we
499 * subtracted 2048.
501 assert(ctl->arg_max <= (LONG_MAX - 2048L));
502 state->argbuf = (char *) xmalloc (ctl->arg_max + 1u);
504 state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
505 state->todo = 0;
506 state->usercontext = context;
509 void
510 bc_clear_args(const struct buildcmd_control *ctl,
511 struct buildcmd_state *state)
513 state->cmd_argc = ctl->initial_argc;
514 state->cmd_argv_chars = state->cmd_initial_argv_chars;
515 state->todo = 0;