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)
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
23 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
24 # define PARAMS(Args) Args
26 # define PARAMS(Args) ()
30 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
39 /* Simulate mbrlen with mblen as best we can. */
40 # define mbstate_t int
41 # define mbrlen(s, n, ps) mblen (s, n)
50 # define _(Text) gettext (Text)
53 #define textdomain(Domain)
54 #define bindtextdomain(Package, Directory)
57 # define N_(String) gettext_noop (String)
59 /* See locate.c for explanation as to why not use (String) */
60 # define N_(String) String
64 #include <sys/param.h>
76 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
77 We try to make it as large as possible. */
78 #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
79 #define ARG_MAX sysconf (_SC_ARG_MAX)
82 #define ARG_MAX NCARGS
92 static char *mbstrstr
PARAMS ((const char *haystack
, const char *needle
));
94 /* Replace all instances of `replace_pat' in ARG with `linebuf',
95 and add the resulting string to the list of arguments for the command
97 ARGLEN is the length of ARG, not including the null.
98 LBLEN is the length of LINEBUF, not including the null.
99 PFXLEN is the length of PREFIX. Substitution is not performed on
100 the prefix. The prefix is used if the argument contains replace_pat.
102 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
103 and a max of 5 occurrences of replace_pat in the initial-arguments.
104 Those restrictions do not exist here. */
107 bc_do_insert (const struct buildcmd_control
*ctl
,
108 struct buildcmd_state
*state
,
109 char *arg
, size_t arglen
,
110 const char *prefix
, size_t pfxlen
,
111 const char *linebuf
, size_t lblen
,
114 /* Temporary copy of each arg with the replace pattern replaced by the
116 static char *insertbuf
;
118 int bytes_left
= ctl
->arg_max
- 1; /* Bytes left on the command line. */
122 insertbuf
= (char *) xmalloc (ctl
->arg_max
+ 1);
128 size_t len
; /* Length in ARG before `replace_pat'. */
129 char *s
= mbstrstr (arg
, ctl
->replace_pat
);
144 strncpy (p
, arg
, len
);
156 arglen
-= ctl
->rplen
;
162 error (1, 0, _("command too long"));
171 bc_push_arg (ctl
, state
,
172 insertbuf
, p
- insertbuf
,
178 void do_exec(const struct buildcmd_control
*ctl
,
179 struct buildcmd_state
*state
)
181 (ctl
->exec_callback
)(ctl
, state
);
185 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
187 LEN is the length of ARG, including the terminating null.
188 If this brings the list up to its maximum size, execute the command. */
191 bc_push_arg (const struct buildcmd_control
*ctl
,
192 struct buildcmd_state
*state
,
193 const char *arg
, size_t len
,
194 const char *prefix
, size_t pfxlen
,
200 if (state
->cmd_argv_chars
+ len
> ctl
->arg_max
)
202 if (initial_args
|| state
->cmd_argc
== ctl
->initial_argc
)
203 error (1, 0, _("can not fit single argument within argument list size limit"));
204 /* option -i (replace_pat) implies -x (exit_if_size_exceeded) */
206 || (ctl
->exit_if_size_exceeded
&&
207 (ctl
->lines_per_exec
|| ctl
->args_per_exec
)))
208 error (1, 0, _("argument list too long"));
209 do_exec (ctl
, state
);
211 if (!initial_args
&& ctl
->args_per_exec
&&
212 state
->cmd_argc
- ctl
->initial_argc
== ctl
->args_per_exec
)
213 do_exec (ctl
, state
);
216 if (state
->cmd_argc
>= state
->cmd_argv_alloc
)
218 if (!state
->cmd_argv
)
220 state
->cmd_argv_alloc
= 64;
221 state
->cmd_argv
= (char **) xmalloc (sizeof (char *) * state
->cmd_argv_alloc
);
225 state
->cmd_argv_alloc
*= 2;
226 state
->cmd_argv
= (char **) xrealloc (state
->cmd_argv
,
227 sizeof (char *) * state
->cmd_argv_alloc
);
232 state
->cmd_argv
[state
->cmd_argc
++] = NULL
;
235 state
->cmd_argv
[state
->cmd_argc
++] = state
->argbuf
+ state
->cmd_argv_chars
;
238 strcpy (state
->argbuf
+ state
->cmd_argv_chars
, prefix
);
239 state
->cmd_argv_chars
+= pfxlen
;
242 strcpy (state
->argbuf
+ state
->cmd_argv_chars
, arg
);
243 state
->cmd_argv_chars
+= len
;
245 /* If we have now collected enough arguments,
246 * do the exec immediately. This must be
247 * conditional on arg!=NULL, since do_exec()
248 * actually calls bc_push_arg(ctl, state, NULL, 0, false).
251 && ctl
->args_per_exec
252 && (state
->cmd_argc
- ctl
->initial_argc
) == ctl
->args_per_exec
)
253 do_exec (ctl
, state
);
256 /* If this is an initial argument, set the high-water mark. */
259 state
->cmd_initial_argv_chars
= state
->cmd_argv_chars
;
264 /* Finds the first occurrence of the substring NEEDLE in the string
265 HAYSTACK. Both strings can be multibyte strings. */
268 mbstrstr (const char *haystack
, const char *needle
)
273 size_t hlen
= strlen (haystack
);
274 size_t nlen
= strlen (needle
);
278 memset (&mbstate
, 0, sizeof (mbstate_t));
281 if (memcmp (haystack
, needle
, nlen
) == 0)
282 return (char *) haystack
;
283 step
= mbrlen (haystack
, hlen
, &mbstate
);
292 return strstr (haystack
, needle
);
301 val
= sysconf(_SC_ARG_MAX
);
309 /* either _SC_ARG_MAX was not available or
310 * there is no particular limit.
319 /* The value returned by this function bounds the
320 * value applied as the ceiling for the -s option.
321 * Hence it the system won't tell us what its limit
322 * is, we allow the user to specify more or less
323 * whatever value they like.
329 static int cb_exec_noop(const struct buildcmd_control
*ctl
,
330 struct buildcmd_state
*state
)
340 bc_init_controlinfo(struct buildcmd_control
*ctl
)
342 ctl
->exit_if_size_exceeded
= 0;
343 ctl
->arg_max
= bc_get_arg_max() - 2048; /* a la xargs */
345 ctl
->replace_pat
= NULL
;
346 ctl
->initial_argc
= 0;
347 ctl
->exec_callback
= cb_exec_noop
;
348 ctl
->lines_per_exec
= 0;
349 ctl
->args_per_exec
= 0;
353 bc_init_state(const struct buildcmd_control
*ctl
,
354 struct buildcmd_state
*state
,
358 state
->cmd_argv_chars
= 0;
359 state
->cmd_argv
= NULL
;
360 state
->cmd_argv_alloc
= 0;
361 state
->argbuf
= (char *) xmalloc (ctl
->arg_max
+ 1);
362 state
->cmd_argv_chars
= state
->cmd_initial_argv_chars
= 0;
364 state
->usercontext
= context
;
368 bc_clear_args(const struct buildcmd_control
*ctl
,
369 struct buildcmd_state
*state
)
371 state
->cmd_argc
= ctl
->initial_argc
;
372 state
->cmd_argv_chars
= state
->cmd_initial_argv_chars
;