Documented the fact that -printf also supports the '\0' escape code.
[findutils.git] / xargs / xargs.c
blob06a0f73e6917487f7faac996109a2830c1a9e77c
1 /* xargs -- build and execute command lines from standard input
2 Copyright (C) 1990, 91, 92, 93, 94, 2000,2003 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., 9 Temple Place - Suite 330, Boston, MA 02111-1307,
17 USA.
20 /* Written by Mike Rendell <michael@cs.mun.ca>
21 and David MacKenzie <djm@gnu.ai.mit.edu>. */
23 #include <gnulib/config.h>
24 #undef VERSION
25 #undef PACKAGE_VERSION
26 #undef PACKAGE_TARNAME
27 #undef PACKAGE_STRING
28 #undef PACKAGE_NAME
29 #undef PACKAGE
30 #include <config.h>
32 # ifndef PARAMS
33 # if defined PROTOTYPES || (defined __STDC__ && __STDC__)
34 # define PARAMS(Args) Args
35 # else
36 # define PARAMS(Args) ()
37 # endif
38 # endif
40 #ifndef _GNU_SOURCE
41 #define _GNU_SOURCE
42 #endif
43 #include <ctype.h>
45 #if !defined (isascii) || defined (STDC_HEADERS)
46 #ifdef isascii
47 #undef isascii
48 #endif
49 #define isascii(c) 1
50 #endif
52 #ifdef isblank
53 #define ISBLANK(c) (isascii (c) && isblank (c))
54 #else
55 #define ISBLANK(c) ((c) == ' ' || (c) == '\t')
56 #endif
58 #define ISSPACE(c) (ISBLANK (c) || (c) == '\n' || (c) == '\r' \
59 || (c) == '\f' || (c) == '\v')
61 #include <sys/types.h>
62 #include <stdio.h>
63 #include <errno.h>
64 #include <getopt.h>
66 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
67 #include <string.h>
68 #if !defined(STDC_HEADERS)
69 #include <memory.h>
70 #endif
71 #else
72 #include <strings.h>
73 #define memcpy(dest, source, count) (bcopy((source), (dest), (count)))
74 #endif
76 #ifndef _POSIX_SOURCE
77 #include <sys/param.h>
78 #endif
80 #ifdef HAVE_LIMITS_H
81 #include <limits.h>
82 #endif
84 #ifndef LONG_MAX
85 #define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
86 #endif
88 #ifdef HAVE_UNISTD_H
89 #include <unistd.h>
90 #endif
92 #include <signal.h>
94 #if !defined(SIGCHLD) && defined(SIGCLD)
95 #define SIGCHLD SIGCLD
96 #endif
98 /* COMPAT: SYSV version defaults size (and has a max value of) to 470.
99 We try to make it as large as possible. */
100 #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
101 #define ARG_MAX sysconf (_SC_ARG_MAX)
102 #endif
103 #ifndef ARG_MAX
104 #define ARG_MAX NCARGS
105 #endif
107 #include "wait.h"
109 /* States for read_line. */
110 #define NORM 0
111 #define SPACE 1
112 #define QUOTE 2
113 #define BACKSLASH 3
115 #ifdef STDC_HEADERS
116 #include <stdlib.h>
117 #else
118 extern int errno;
119 #endif
121 #ifdef HAVE_LOCALE_H
122 #include <locale.h>
123 #endif
124 #if ENABLE_NLS
125 # include <libintl.h>
126 # define _(Text) gettext (Text)
127 #else
128 # define _(Text) Text
129 #define textdomain(Domain)
130 #define bindtextdomain(Package, Directory)
131 #endif
132 #ifdef gettext_noop
133 # define N_(String) gettext_noop (String)
134 #else
135 # define N_(String) (String)
136 #endif
138 /* Return nonzero if S is the EOF string. */
139 #define EOF_STR(s) (eof_str && *eof_str == *s && !strcmp (eof_str, s))
141 extern char **environ;
143 /* Do multibyte processing if multibyte characters are supported,
144 unless multibyte sequences are search safe. Multibyte sequences
145 are search safe if searching for a substring using the byte
146 comparison function 'strstr' gives no false positives. All 8-bit
147 encodings and the UTF-8 multibyte encoding are search safe, but
148 the EUC encodings are not.
149 BeOS uses the UTF-8 encoding exclusively, so it is search safe. */
150 #if defined __BEOS__
151 # define MULTIBYTE_IS_SEARCH_SAFE 1
152 #endif
153 #define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_SEARCH_SAFE)
155 #if DO_MULTIBYTE
156 # if HAVE_MBRLEN
157 # include <wchar.h>
158 # else
159 /* Simulate mbrlen with mblen as best we can. */
160 # define mbstate_t int
161 # define mbrlen(s, n, ps) mblen (s, n)
162 # endif
163 #endif
165 /* Not char because of type promotion; NeXT gcc can't handle it. */
166 typedef int boolean;
167 #define true 1
168 #define false 0
170 #if __STDC__
171 #define VOID void
172 #else
173 #define VOID char
174 #endif
176 #include <xalloc.h>
177 void error PARAMS ((int status, int errnum, char *message,...));
179 extern char *version_string;
181 /* The name this program was run with. */
182 char *program_name;
184 /* Buffer for reading arguments from stdin. */
185 static char *linebuf;
187 /* Line number in stdin since the last command was executed. */
188 static int lineno = 0;
190 /* If nonzero, then instead of putting the args from stdin at
191 the end of the command argument list, they are each stuck into the
192 initial args, replacing each occurrence of the `replace_pat' in the
193 initial args. */
194 static char *replace_pat = NULL;
196 /* The length of `replace_pat'. */
197 static size_t rplen = 0;
199 /* If nonzero, when this string is read on stdin it is treated as
200 end of file.
201 I don't like this - it should default to NULL. */
202 static char *eof_str = "_";
204 /* If nonzero, the maximum number of nonblank lines from stdin to use
205 per command line. */
206 static long lines_per_exec = 0;
208 /* The maximum number of arguments to use per command line. */
209 static long args_per_exec = 1024;
211 /* If true, exit if lines_per_exec or args_per_exec is exceeded. */
212 static boolean exit_if_size_exceeded = false;
214 /* The maximum number of characters that can be used per command line. */
215 static long arg_max;
217 /* Storage for elements of `cmd_argv'. */
218 static char *argbuf;
220 /* The list of args being built. */
221 static char **cmd_argv = NULL;
223 /* Number of elements allocated for `cmd_argv'. */
224 static int cmd_argv_alloc = 0;
226 /* Number of valid elements in `cmd_argv'. */
227 static int cmd_argc = 0;
229 /* Number of chars being used in `cmd_argv'. */
230 static int cmd_argv_chars = 0;
232 /* Number of initial arguments given on the command line. */
233 static int initial_argc = 0;
235 /* Number of chars in the initial args. */
236 static int initial_argv_chars = 0;
238 /* true when building up initial arguments in `cmd_argv'. */
239 static boolean initial_args = true;
241 /* If nonzero, the maximum number of child processes that can be running
242 at once. */
243 static int proc_max = 1;
245 /* Total number of child processes that have been executed. */
246 static int procs_executed = 0;
248 /* The number of elements in `pids'. */
249 static int procs_executing = 0;
251 /* List of child processes currently executing. */
252 static pid_t *pids = NULL;
254 /* The number of allocated elements in `pids'. */
255 static int pids_alloc = 0;
257 /* Exit status; nonzero if any child process exited with a
258 status of 1-125. */
259 static int child_error = 0;
261 /* If true, print each command on stderr before executing it. */
262 static boolean print_command = false;
264 /* If true, query the user before executing each command, and only
265 execute the command if the user responds affirmatively. */
266 static boolean query_before_executing = false;
268 static struct option const longopts[] =
270 {"null", no_argument, NULL, '0'},
271 {"eof", optional_argument, NULL, 'e'},
272 {"replace", optional_argument, NULL, 'i'},
273 {"max-lines", optional_argument, NULL, 'l'},
274 {"max-args", required_argument, NULL, 'n'},
275 {"interactive", no_argument, NULL, 'p'},
276 {"no-run-if-empty", no_argument, NULL, 'r'},
277 {"max-chars", required_argument, NULL, 's'},
278 {"verbose", no_argument, NULL, 't'},
279 {"exit", no_argument, NULL, 'x'},
280 {"max-procs", required_argument, NULL, 'P'},
281 {"version", no_argument, NULL, 'v'},
282 {"help", no_argument, NULL, 'h'},
283 {NULL, no_argument, NULL, 0}
286 static int read_line PARAMS ((void));
287 static int read_string PARAMS ((void));
288 static char *mbstrstr PARAMS ((const char *haystack, const char *needle));
289 static void do_insert PARAMS ((char *arg, size_t arglen, size_t lblen));
290 static void push_arg PARAMS ((char *arg, size_t len));
291 static boolean print_args PARAMS ((boolean ask));
292 static void do_exec PARAMS ((void));
293 static void add_proc PARAMS ((pid_t pid));
294 static void wait_for_proc PARAMS ((boolean all));
295 static long parse_num PARAMS ((char *str, int option, long min, long max));
296 static long env_size PARAMS ((char **envp));
297 static void usage PARAMS ((FILE * stream, int status));
300 main (int argc, char **argv)
302 int optc;
303 int always_run_command = 1;
304 long orig_arg_max;
305 char *default_cmd = "/bin/echo";
306 int (*read_args) PARAMS ((void)) = read_line;
308 program_name = argv[0];
310 #ifdef HAVE_SETLOCALE
311 setlocale (LC_ALL, "");
312 #endif
313 bindtextdomain (PACKAGE, LOCALEDIR);
314 textdomain (PACKAGE);
316 orig_arg_max = ARG_MAX;
317 if (orig_arg_max == -1)
318 orig_arg_max = LONG_MAX;
319 orig_arg_max -= 2048; /* POSIX.2 requires subtracting 2048. */
320 arg_max = orig_arg_max;
322 /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which
323 have it at 1 meg). Things will work fine with a large ARG_MAX but it
324 will probably hurt the system more than it needs to; an array of this
325 size is allocated. */
326 if (arg_max > 20 * 1024)
327 arg_max = 20 * 1024;
329 /* Take the size of the environment into account. */
330 arg_max -= env_size (environ);
331 if (arg_max <= 0)
332 error (1, 0, _("environment is too large for exec"));
334 while ((optc = getopt_long (argc, argv, "+0e::i::l::n:prs:txP:",
335 longopts, (int *) 0)) != -1)
337 switch (optc)
339 case '0':
340 read_args = read_string;
341 break;
343 case 'e':
344 if (optarg)
345 eof_str = optarg;
346 else
347 eof_str = 0;
348 break;
350 case 'h':
351 usage (stdout, 0);
353 case 'i':
354 if (optarg)
355 replace_pat = optarg;
356 else
357 replace_pat = "{}";
358 /* -i excludes -n -l. */
359 args_per_exec = 0;
360 lines_per_exec = 0;
361 break;
363 case 'l':
364 if (optarg)
365 lines_per_exec = parse_num (optarg, 'l', 1L, -1L);
366 else
367 lines_per_exec = 1;
368 /* -l excludes -i -n. */
369 args_per_exec = 0;
370 replace_pat = NULL;
371 break;
373 case 'n':
374 args_per_exec = parse_num (optarg, 'n', 1L, -1L);
375 /* -n excludes -i -l. */
376 lines_per_exec = 0;
377 replace_pat = NULL;
378 break;
380 case 's':
381 arg_max = parse_num (optarg, 's', 1L, orig_arg_max);
382 break;
384 case 't':
385 print_command = true;
386 break;
388 case 'x':
389 exit_if_size_exceeded = true;
390 break;
392 case 'p':
393 query_before_executing = true;
394 print_command = true;
395 break;
397 case 'r':
398 always_run_command = 0;
399 break;
401 case 'P':
402 proc_max = parse_num (optarg, 'P', 0L, -1L);
403 break;
405 case 'v':
406 printf (_("GNU xargs version %s\n"), version_string);
407 exit (0);
409 default:
410 usage (stderr, 1);
414 if (replace_pat || lines_per_exec)
415 exit_if_size_exceeded = true;
417 if (optind == argc)
419 optind = 0;
420 argc = 1;
421 argv = &default_cmd;
424 linebuf = (char *) xmalloc (arg_max + 1);
425 argbuf = (char *) xmalloc (arg_max + 1);
427 /* Make sure to listen for the kids. */
428 signal (SIGCHLD, SIG_DFL);
430 if (!replace_pat)
432 for (; optind < argc; optind++)
433 push_arg (argv[optind], strlen (argv[optind]) + 1);
434 initial_args = false;
435 initial_argc = cmd_argc;
436 initial_argv_chars = cmd_argv_chars;
438 while ((*read_args) () != -1)
439 if (lines_per_exec && lineno >= lines_per_exec)
441 do_exec ();
442 lineno = 0;
445 /* SYSV xargs seems to do at least one exec, even if the
446 input is empty. */
447 if (cmd_argc != initial_argc
448 || (always_run_command && procs_executed == 0))
449 do_exec ();
451 else
453 int i;
454 size_t len;
455 size_t *arglen = (size_t *) xmalloc (sizeof (size_t) * argc);
457 for (i = optind; i < argc; i++)
458 arglen[i] = strlen(argv[i]);
459 rplen = strlen (replace_pat);
460 while ((len = (*read_args) ()) != -1)
462 /* Don't do insert on the command name. */
463 push_arg (argv[optind], arglen[optind] + 1);
464 len--;
465 for (i = optind + 1; i < argc; i++)
466 do_insert (argv[i], arglen[i], len);
467 do_exec ();
471 wait_for_proc (true);
472 exit (child_error);
475 /* Read a line of arguments from stdin and add them to the list of
476 arguments to pass to the command. Ignore blank lines and initial blanks.
477 Single and double quotes and backslashes quote metacharacters and blanks
478 as they do in the shell.
479 Return -1 if eof (either physical or logical) is reached,
480 otherwise the length of the last string read (including the null). */
482 static int
483 read_line (void)
485 static boolean eof = false;
486 /* Start out in mode SPACE to always strip leading spaces (even with -i). */
487 int state = SPACE; /* The type of character we last read. */
488 int prevc; /* The previous value of c. */
489 int quotc = 0; /* The last quote character read. */
490 int c = EOF;
491 boolean first = true; /* true if reading first arg on line. */
492 int len;
493 char *p = linebuf;
494 /* Including the NUL, the args must not grow past this point. */
495 char *endbuf = linebuf + arg_max - initial_argv_chars - 1;
497 if (eof)
498 return -1;
499 while (1)
501 prevc = c;
502 c = getc (stdin);
503 if (c == EOF)
505 /* COMPAT: SYSV seems to ignore stuff on a line that
506 ends without a \n; we don't. */
507 eof = true;
508 if (p == linebuf)
509 return -1;
510 *p++ = '\0';
511 len = p - linebuf;
512 /* FIXME we don't check for unterminated quotes here. */
513 if (first && EOF_STR (linebuf))
514 return -1;
515 if (!replace_pat)
516 push_arg (linebuf, len);
517 return len;
519 switch (state)
521 case SPACE:
522 if (ISSPACE (c))
523 continue;
524 state = NORM;
525 /* aaahhhh.... */
527 case NORM:
528 if (c == '\n')
530 if (!ISBLANK (prevc))
531 lineno++; /* For -l. */
532 if (p == linebuf)
534 /* Blank line. */
535 state = SPACE;
536 continue;
538 *p++ = '\0';
539 len = p - linebuf;
540 if (EOF_STR (linebuf))
542 eof = true;
543 return first ? -1 : len;
545 if (!replace_pat)
546 push_arg (linebuf, len);
547 return len;
549 if (!replace_pat && ISSPACE (c))
551 *p++ = '\0';
552 len = p - linebuf;
553 if (EOF_STR (linebuf))
555 eof = true;
556 return first ? -1 : len;
558 push_arg (linebuf, len);
559 p = linebuf;
560 state = SPACE;
561 first = false;
562 continue;
564 switch (c)
566 case '\\':
567 state = BACKSLASH;
568 continue;
570 case '\'':
571 case '"':
572 state = QUOTE;
573 quotc = c;
574 continue;
576 break;
578 case QUOTE:
579 if (c == '\n')
580 error (1, 0, _("unmatched %s quote"),
581 quotc == '"' ? _("double") : _("single"));
582 if (c == quotc)
584 state = NORM;
585 continue;
587 break;
589 case BACKSLASH:
590 state = NORM;
591 break;
593 if (p >= endbuf)
594 error (1, 0, _("argument line too long"));
595 *p++ = c;
599 /* Read a null-terminated string from stdin and add it to the list of
600 arguments to pass to the command.
601 Return -1 if eof (either physical or logical) is reached,
602 otherwise the length of the string read (including the null). */
604 static int
605 read_string (void)
607 static boolean eof = false;
608 int len;
609 char *p = linebuf;
610 /* Including the NUL, the args must not grow past this point. */
611 char *endbuf = linebuf + arg_max - initial_argv_chars - 1;
613 if (eof)
614 return -1;
615 while (1)
617 int c = getc (stdin);
618 if (c == EOF)
620 eof = true;
621 if (p == linebuf)
622 return -1;
623 *p++ = '\0';
624 len = p - linebuf;
625 if (!replace_pat)
626 push_arg (linebuf, len);
627 return len;
629 if (c == '\0')
631 lineno++; /* For -l. */
632 *p++ = '\0';
633 len = p - linebuf;
634 if (!replace_pat)
635 push_arg (linebuf, len);
636 return len;
638 if (p >= endbuf)
639 error (1, 0, _("argument line too long"));
640 *p++ = c;
644 /* Finds the first occurrence of the substring NEEDLE in the string
645 HAYSTACK. Both strings can be multibyte strings. */
647 static char *
648 mbstrstr (const char *haystack, const char *needle)
650 #if DO_MULTIBYTE
651 if (MB_CUR_MAX > 1)
653 size_t hlen = strlen (haystack);
654 size_t nlen = strlen (needle);
655 mbstate_t mbstate;
656 size_t step;
658 memset (&mbstate, 0, sizeof (mbstate_t));
659 while (hlen >= nlen)
661 if (memcmp (haystack, needle, nlen) == 0)
662 return (char *) haystack;
663 step = mbrlen (haystack, hlen, &mbstate);
664 if (step <= 0)
665 break;
666 haystack += step;
667 hlen -= step;
669 return NULL;
671 #endif
672 return strstr (haystack, needle);
675 /* Replace all instances of `replace_pat' in ARG with `linebuf',
676 and add the resulting string to the list of arguments for the command
677 to execute.
678 ARGLEN is the length of ARG, not including the null.
679 LBLEN is the length of `linebuf', not including the null.
681 COMPAT: insertions on the SYSV version are limited to 255 chars per line,
682 and a max of 5 occurrences of replace_pat in the initial-arguments.
683 Those restrictions do not exist here. */
685 static void
686 do_insert (char *arg, size_t arglen, size_t lblen)
688 /* Temporary copy of each arg with the replace pattern replaced by the
689 real arg. */
690 static char *insertbuf;
691 char *p;
692 int bytes_left = arg_max - 1; /* Bytes left on the command line. */
694 if (!insertbuf)
695 insertbuf = (char *) xmalloc (arg_max + 1);
696 p = insertbuf;
700 size_t len; /* Length in ARG before `replace_pat'. */
701 char *s = mbstrstr (arg, replace_pat);
702 if (s)
703 len = s - arg;
704 else
705 len = arglen;
706 bytes_left -= len;
707 if (bytes_left <= 0)
708 break;
710 strncpy (p, arg, len);
711 p += len;
712 arg += len;
713 arglen -= len;
715 if (s)
717 bytes_left -= lblen;
718 if (bytes_left <= 0)
719 break;
720 strcpy (p, linebuf);
721 arg += rplen;
722 arglen -= rplen;
723 p += lblen;
726 while (*arg);
727 if (*arg)
728 error (1, 0, _("command too long"));
729 *p++ = '\0';
730 push_arg (insertbuf, p - insertbuf);
733 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
734 to the command.
735 LEN is the length of ARG, including the terminating null.
736 If this brings the list up to its maximum size, execute the command. */
738 static void
739 push_arg (char *arg, size_t len)
741 if (arg)
743 if (cmd_argv_chars + len > arg_max)
745 if (initial_args || cmd_argc == initial_argc)
746 error (1, 0, _("can not fit single argument within argument list size limit"));
747 if (replace_pat
748 || (exit_if_size_exceeded &&
749 (lines_per_exec || args_per_exec)))
750 error (1, 0, _("argument list too long"));
751 do_exec ();
753 if (!initial_args && args_per_exec &&
754 cmd_argc - initial_argc == args_per_exec)
755 do_exec ();
758 if (cmd_argc >= cmd_argv_alloc)
760 if (!cmd_argv)
762 cmd_argv_alloc = 64;
763 cmd_argv = (char **) xmalloc (sizeof (char *) * cmd_argv_alloc);
765 else
767 cmd_argv_alloc *= 2;
768 cmd_argv = (char **) xrealloc (cmd_argv,
769 sizeof (char *) * cmd_argv_alloc);
773 if (!arg)
774 cmd_argv[cmd_argc++] = NULL;
775 else
777 cmd_argv[cmd_argc++] = argbuf + cmd_argv_chars;
778 strcpy (argbuf + cmd_argv_chars, arg);
779 cmd_argv_chars += len;
783 /* Print the arguments of the command to execute.
784 If ASK is nonzero, prompt the user for a response, and
785 if the user responds affirmatively, return true;
786 otherwise, return false. */
788 static boolean
789 print_args (boolean ask)
791 int i;
793 for (i = 0; i < cmd_argc - 1; i++)
794 fprintf (stderr, "%s ", cmd_argv[i]);
795 if (ask)
797 static FILE *tty_stream;
798 int c, savec;
800 if (!tty_stream)
802 tty_stream = fopen ("/dev/tty", "r");
803 if (!tty_stream)
804 error (1, errno, "/dev/tty");
806 fputs ("?...", stderr);
807 fflush (stderr);
808 c = savec = getc (tty_stream);
809 while (c != EOF && c != '\n')
810 c = getc (tty_stream);
811 if (savec == 'y' || savec == 'Y')
812 return true;
814 else
815 putc ('\n', stderr);
817 return false;
820 /* Execute the command that has been built in `cmd_argv'. This may involve
821 waiting for processes that were previously executed. */
823 static void
824 do_exec (void)
826 pid_t child;
828 push_arg ((char *) NULL, 0); /* Null terminate the arg list. */
829 if (!query_before_executing || print_args (true))
831 if (proc_max && procs_executing >= proc_max)
832 wait_for_proc (false);
833 if (!query_before_executing && print_command)
834 print_args (false);
835 /* If we run out of processes, wait for a child to return and
836 try again. */
837 while ((child = fork ()) < 0 && errno == EAGAIN && procs_executing)
838 wait_for_proc (false);
839 switch (child)
841 case -1:
842 error (1, errno, _("cannot fork"));
844 case 0: /* Child. */
845 execvp (cmd_argv[0], cmd_argv);
846 error (0, errno, "%s", cmd_argv[0]);
847 _exit (errno == ENOENT ? 127 : 126);
849 add_proc (child);
852 cmd_argc = initial_argc;
853 cmd_argv_chars = initial_argv_chars;
856 /* Add the process with id PID to the list of processes that have
857 been executed. */
859 static void
860 add_proc (pid_t pid)
862 int i;
864 /* Find an empty slot. */
865 for (i = 0; i < pids_alloc && pids[i]; i++)
867 if (i == pids_alloc)
869 if (pids_alloc == 0)
871 pids_alloc = proc_max ? proc_max : 64;
872 pids = (pid_t *) xmalloc (sizeof (pid_t) * pids_alloc);
874 else
876 pids_alloc *= 2;
877 pids = (pid_t *) xrealloc (pids,
878 sizeof (pid_t) * pids_alloc);
880 memset (&pids[i], '\0', sizeof (pid_t) * (pids_alloc - i));
882 pids[i] = pid;
883 procs_executing++;
884 procs_executed++;
887 /* If ALL is true, wait for all child processes to finish;
888 otherwise, wait for one child process to finish.
889 Remove the processes that finish from the list of executing processes. */
891 static void
892 wait_for_proc (boolean all)
894 while (procs_executing)
896 int i, status;
900 pid_t pid;
902 while ((pid = wait (&status)) == (pid_t) -1)
903 if (errno != EINTR)
904 error (1, errno, _("error waiting for child process"));
906 /* Find the entry in `pids' for the child process
907 that exited. */
908 for (i = 0; i < pids_alloc && pid != pids[i]; i++)
911 while (i == pids_alloc); /* A child died that we didn't start? */
913 /* Remove the child from the list. */
914 pids[i] = 0;
915 procs_executing--;
917 if (WEXITSTATUS (status) == 126 || WEXITSTATUS (status) == 127)
918 exit (WEXITSTATUS (status)); /* Can't find or run the command. */
919 if (WEXITSTATUS (status) == 255)
920 error (124, 0, _("%s: exited with status 255; aborting"), cmd_argv[0]);
921 if (WIFSTOPPED (status))
922 error (125, 0, _("%s: stopped by signal %d"), cmd_argv[0], WSTOPSIG (status));
923 if (WIFSIGNALED (status))
924 error (125, 0, _("%s: terminated by signal %d"), cmd_argv[0], WTERMSIG (status));
925 if (WEXITSTATUS (status) != 0)
926 child_error = 123;
928 if (!all)
929 break;
933 /* Return the value of the number represented in STR.
934 OPTION is the command line option to which STR is the argument.
935 If the value does not fall within the boundaries MIN and MAX,
936 Print an error message mentioning OPTION and exit. */
938 static long
939 parse_num (char *str, int option, long int min, long int max)
941 char *eptr;
942 long val;
944 val = strtol (str, &eptr, 10);
945 if (eptr == str || *eptr)
947 fprintf (stderr, _("%s: invalid number for -%c option\n"),
948 program_name, option);
949 usage (stderr, 1);
951 else if (val < min)
953 fprintf (stderr, _("%s: value for -%c option must be >= %ld\n"),
954 program_name, option, min);
955 usage (stderr, 1);
957 else if (max >= 0 && val > max)
959 fprintf (stderr, _("%s: value for -%c option must be < %ld\n"),
960 program_name, option, max);
961 usage (stderr, 1);
963 return val;
966 /* Return how much of ARG_MAX is used by the environment. */
968 static long
969 env_size (char **envp)
971 long len = 0;
973 while (*envp)
974 len += strlen (*envp++) + 1;
976 return len;
979 static void
980 usage (FILE *stream, int status)
982 fprintf (stream, _("\
983 Usage: %s [-0prtx] [-e[eof-str]] [-i[replace-str]] [-l[max-lines]]\n\
984 [-n max-args] [-s max-chars] [-P max-procs] [--null] [--eof[=eof-str]]\n\
985 [--replace[=replace-str]] [--max-lines[=max-lines]] [--interactive]\n\
986 [--max-chars=max-chars] [--verbose] [--exit] [--max-procs=max-procs]\n\
987 [--max-args=max-args] [--no-run-if-empty] [--version] [--help]\n\
988 [command [initial-arguments]]\n"),
989 program_name);
990 fputs (_("\nReport bugs to <bug-findutils@gnu.org>.\n"), stream);
991 exit (status);