adf1f134c0df7b75c1666eee48f4e752b302fbff
[oweals/busybox.git] / xargs.c
1 /* xargs for busybox  -- using GNU xargs till we can get something
2  * better.  minix xargs is a bit smaller... */
3
4 /* xargs -- build and execute command lines from standard input
5    Copyright (C) 1990, 91, 92, 93, 94 Free Software Foundation, Inc.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2, or (at your option)
10    any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
20
21 /* Written by Mike Rendell <michael@cs.mun.ca>
22    and David MacKenzie <djm@gnu.ai.mit.edu>.  */
23
24 #include "internal.h"
25
26 #define HAVE_STRING_H 1
27 #define HAVE_SYS_WAIT_H 1
28 #define HAVE_UNISTD_H 1
29 #define HAVE_LIMITS_H 1
30 #define STDC_HEADERS 1
31
32 #include <sys/types.h>          /* For pid_t. */
33 #if HAVE_SYS_WAIT_H
34 #include <sys/wait.h>
35 #endif
36
37 #ifndef WIFSTOPPED
38 #define WIFSTOPPED(w) (((w) & 0xff) == 0x7f)
39 #endif
40 #ifndef WIFSIGNALED
41 #define WIFSIGNALED(w) (((w) & 0xff) != 0x7f && ((w) & 0xff) != 0)
42 #endif
43 #ifndef WIFEXITED
44 #define WIFEXITED(w) (((w) & 0xff) == 0)
45 #endif
46
47 #ifndef WSTOPSIG
48 #define WSTOPSIG(w) (((w) >> 8) & 0xff)
49 #endif
50 #ifndef WTERMSIG
51 #define WTERMSIG(w) ((w) & 0x7f)
52 #endif
53 #ifndef WEXITSTATUS
54 #define WEXITSTATUS(w) (((w) >> 8) & 0xff)
55 #endif
56
57 #if __STDC__
58 #define P_(s) s
59 #else
60 #define P_(s) ()
61 #endif
62
63 #include <ctype.h>
64
65 #if !defined (isascii) || defined (STDC_HEADERS)
66 #ifdef isascii
67 #undef isascii
68 #endif
69 #define isascii(c) 1
70 #endif
71
72 #ifdef isblank
73 #define ISBLANK(c) (isascii (c) && isblank (c))
74 #else
75 #define ISBLANK(c) ((c) == ' ' || (c) == '\t')
76 #endif
77
78 #define ISSPACE(c) (ISBLANK (c) || (c) == '\n' || (c) == '\r' \
79                     || (c) == '\f' || (c) == '\v')
80
81 #include <stdio.h>
82 #include <errno.h>
83 #include <getopt.h>
84
85 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
86 #include <string.h>
87 #if !defined(STDC_HEADERS)
88 #include <memory.h>
89 #endif
90 #else
91 #include <strings.h>
92 #define memcpy(dest, source, count) (bcopy((source), (dest), (count)))
93 #endif
94
95 #ifndef _POSIX_SOURCE
96 #include <sys/param.h>
97 #endif
98
99 #ifdef HAVE_LIMITS_H
100 #include <limits.h>
101 #endif
102
103 #ifndef LONG_MAX
104 #define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
105 #endif
106
107 #ifdef HAVE_UNISTD_H
108 #include <unistd.h>
109 #endif
110
111 #include <signal.h>
112
113 #if !defined(SIGCHLD) && defined(SIGCLD)
114 #define SIGCHLD SIGCLD
115 #endif
116
117 /* COMPAT:  SYSV version defaults size (and has a max value of) to 470.
118    We try to make it as large as possible. */
119 #if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
120 #define ARG_MAX sysconf (_SC_ARG_MAX)
121 #endif
122 #ifndef ARG_MAX
123 #define ARG_MAX NCARGS
124 #endif
125
126 /* States for read_line. */
127 #define NORM 0
128 #define SPACE 1
129 #define QUOTE 2
130 #define BACKSLASH 3
131
132 #ifdef STDC_HEADERS
133 #include <stdlib.h>
134 #else
135 extern int errno;
136 #endif
137
138 /* Return nonzero if S is the EOF string.  */
139 #define EOF_STR(s) (eof_str && *eof_str == *s && !strcmp (eof_str, s))
140
141 extern char **environ;
142
143 /* Not char because of type promotion; NeXT gcc can't handle it.  */
144 typedef int boolean;
145 #define         true    1
146 #define         false   0
147
148 #if __STDC__
149 #define VOID void
150 #else
151 #define VOID char
152 #endif
153
154 VOID *xmalloc P_ ((size_t n));
155 VOID *xrealloc P_ ((VOID * p, size_t n));
156
157 /* The name this program was run with.  */
158 char *program_name;
159
160 /* Buffer for reading arguments from stdin.  */
161 static char *linebuf;
162
163 /* Line number in stdin since the last command was executed.  */
164 static int lineno = 0;
165
166 /* If nonzero, then instead of putting the args from stdin at
167    the end of the command argument list, they are each stuck into the
168    initial args, replacing each occurrence of the `replace_pat' in the
169    initial args.  */
170 static char *replace_pat = NULL;
171
172 /* The length of `replace_pat'.  */
173 static size_t rplen = 0;
174
175 /* If nonzero, when this string is read on stdin it is treated as
176    end of file.
177    I don't like this - it should default to NULL.  */
178 static char *eof_str = "_";
179
180 /* If nonzero, the maximum number of nonblank lines from stdin to use
181    per command line.  */
182 static long lines_per_exec = 0;
183
184 /* The maximum number of arguments to use per command line.  */
185 static long args_per_exec = 1024;
186
187 /* If true, exit if lines_per_exec or args_per_exec is exceeded.  */
188 static boolean exit_if_size_exceeded = false;
189
190 /* The maximum number of characters that can be used per command line.  */
191 static long arg_max;
192
193 /* Storage for elements of `cmd_argv'.  */
194 static char *argbuf;
195
196 /* The list of args being built.  */
197 static char **cmd_argv = NULL;
198
199 /* Number of elements allocated for `cmd_argv'.  */
200 static int cmd_argv_alloc = 0;
201
202 /* Number of valid elements in `cmd_argv'.  */
203 static int cmd_argc = 0;
204
205 /* Number of chars being used in `cmd_argv'.  */
206 static int cmd_argv_chars = 0;
207
208 /* Number of initial arguments given on the command line.  */
209 static int initial_argc = 0;
210
211 /* Number of chars in the initial args.  */
212 static int initial_argv_chars = 0;
213
214 /* true when building up initial arguments in `cmd_argv'.  */
215 static boolean initial_args = true;
216
217 /* If nonzero, the maximum number of child processes that can be running
218    at once.  */
219 static int proc_max = 1;
220
221 /* Total number of child processes that have been executed.  */
222 static int procs_executed = 0;
223
224 /* The number of elements in `pids'.  */
225 static int procs_executing = 0;
226
227 /* List of child processes currently executing.  */
228 static pid_t *pids = NULL;
229
230 /* The number of allocated elements in `pids'. */
231 static int pids_alloc = 0;
232
233 /* Exit status; nonzero if any child process exited with a
234    status of 1-125.  */
235 static int child_error = 0;
236
237 /* If true, print each command on stderr before executing it.  */
238 static boolean print_command = false;
239
240 /* If true, query the user before executing each command, and only
241    execute the command if the user responds affirmatively.  */
242 static boolean query_before_executing = false;
243
244 static struct option const longopts[] =
245 {
246   {"null", no_argument, NULL, '0'},
247   {"eof", optional_argument, NULL, 'e'},
248   {"replace", optional_argument, NULL, 'i'},
249   {"max-lines", optional_argument, NULL, 'l'},
250   {"max-args", required_argument, NULL, 'n'},
251   {"interactive", no_argument, NULL, 'p'},
252   {"no-run-if-empty", no_argument, NULL, 'r'},
253   {"max-chars", required_argument, NULL, 's'},
254   {"verbose", no_argument, NULL, 't'},
255   {"exit", no_argument, NULL, 'x'},
256   {"max-procs", required_argument, NULL, 'P'},
257   {"help", no_argument, NULL, 'h'},
258   {NULL, no_argument, NULL, 0}
259 };
260
261 static int read_line P_ ((void));
262 static int read_string P_ ((void));
263 static void do_insert P_ ((char *arg, size_t arglen, size_t lblen));
264 static void push_arg P_ ((char *arg, size_t len));
265 static boolean print_args P_ ((boolean ask));
266 static void do_exec P_ ((void));
267 static void add_proc P_ ((pid_t pid));
268 static void wait_for_proc P_ ((boolean all));
269 static long parse_num P_ ((char *str, int option, long min, long max));
270 static long env_size P_ ((char **envp));
271
272 int xargs_main (argc, argv)
273      int argc;
274      char **argv;
275 {
276   int optc;
277   int always_run_command = 1;
278   long orig_arg_max;
279   char *default_cmd = "/bin/echo";
280   int (*read_args) P_ ((void)) = read_line;
281
282   program_name = argv[0];
283
284   orig_arg_max = ARG_MAX;
285   if (orig_arg_max == -1)
286     orig_arg_max = LONG_MAX;
287   orig_arg_max -= 2048; /* POSIX.2 requires subtracting 2048.  */
288   arg_max = orig_arg_max;
289
290   /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which
291      have it at 1 meg).  Things will work fine with a large ARG_MAX but it
292      will probably hurt the system more than it needs to; an array of this
293      size is allocated.  */
294   if (arg_max > 20 * 1024)
295     arg_max = 20 * 1024;
296
297   /* Take the size of the environment into account.  */
298   arg_max -= env_size (environ);
299   if (arg_max <= 0)
300     fatalError("environment is too large for exec");
301
302   while ((optc = getopt_long (argc, argv, "+0e::i::l::n:prs:txP:",
303                               longopts, (int *) 0)) != -1)
304     {
305       switch (optc)
306         {
307         case '0':
308           read_args = read_string;
309           break;
310
311         case 'e':
312           if (optarg)
313             eof_str = optarg;
314           else
315             eof_str = 0;
316           break;
317
318         case 'h':
319           usage (xargs_usage);
320
321         case 'i':
322           if (optarg)
323             replace_pat = optarg;
324           else
325             replace_pat = "{}";
326           /* -i excludes -n -l.  */
327           args_per_exec = 0;
328           lines_per_exec = 0;
329           break;
330
331         case 'l':
332           if (optarg)
333             lines_per_exec = parse_num (optarg, 'l', 1L, -1L);
334           else
335             lines_per_exec = 1;
336           /* -l excludes -i -n.  */
337           args_per_exec = 0;
338           replace_pat = NULL;
339           break;
340
341         case 'n':
342           args_per_exec = parse_num (optarg, 'n', 1L, -1L);
343           /* -n excludes -i -l.  */
344           lines_per_exec = 0;
345           replace_pat = NULL;
346           break;
347
348         case 's':
349           arg_max = parse_num (optarg, 's', 1L, orig_arg_max);
350           break;
351
352         case 't':
353           print_command = true;
354           break;
355
356         case 'x':
357           exit_if_size_exceeded = true;
358           break;
359
360         case 'p':
361           query_before_executing = true;
362           print_command = true;
363           break;
364
365         case 'r':
366           always_run_command = 0;
367           break;
368
369         case 'P':
370           proc_max = parse_num (optarg, 'P', 0L, -1L);
371           break;
372
373         default:
374           usage (xargs_usage);
375         }
376     }
377
378   if (replace_pat || lines_per_exec)
379     exit_if_size_exceeded = true;
380
381   if (optind == argc)
382     {
383       optind = 0;
384       argc = 1;
385       argv = &default_cmd;
386     }
387
388   linebuf = (char *) xmalloc (arg_max + 1);
389   argbuf = (char *) xmalloc (arg_max + 1);
390
391   /* Make sure to listen for the kids.  */
392   signal (SIGCHLD, SIG_DFL);
393
394   if (!replace_pat)
395     {
396       for (; optind < argc; optind++)
397         push_arg (argv[optind], strlen (argv[optind]) + 1);
398       initial_args = false;
399       initial_argc = cmd_argc;
400       initial_argv_chars = cmd_argv_chars;
401
402       while ((*read_args) () != -1)
403         if (lines_per_exec && lineno >= lines_per_exec)
404           {
405             do_exec ();
406             lineno = 0;
407           }
408
409       /* SYSV xargs seems to do at least one exec, even if the
410          input is empty.  */
411       if (cmd_argc != initial_argc
412           || (always_run_command && procs_executed == 0))
413         do_exec ();
414     }
415   else
416     {
417       int i;
418       size_t len;
419       size_t *arglen = (size_t *) xmalloc (sizeof (size_t) * argc);
420
421       for (i = optind; i < argc; i++)
422         arglen[i] = strlen(argv[i]);
423       rplen = strlen (replace_pat);
424       while ((len = (*read_args) ()) != -1)
425         {
426           /* Don't do insert on the command name.  */
427           push_arg (argv[optind], arglen[optind] + 1);
428           len--;
429           for (i = optind + 1; i < argc; i++)
430             do_insert (argv[i], arglen[i], len);
431           do_exec ();
432         }
433     }
434
435   wait_for_proc (true);
436   exit (child_error);
437 }
438
439 /* Read a line of arguments from stdin and add them to the list of
440    arguments to pass to the command.  Ignore blank lines and initial blanks.
441    Single and double quotes and backslashes quote metacharacters and blanks
442    as they do in the shell.
443    Return -1 if eof (either physical or logical) is reached,
444    otherwise the length of the last string read (including the null).  */
445
446 static int
447 read_line ()
448 {
449   static boolean eof = false;
450   /* Start out in mode SPACE to always strip leading spaces (even with -i).  */
451   int state = SPACE;            /* The type of character we last read.  */
452   int prevc;                    /* The previous value of c.  */
453   int quotc = 0;                /* The last quote character read.  */
454   int c = EOF;
455   boolean first = true;         /* true if reading first arg on line.  */
456   int len;
457   char *p = linebuf;
458   /* Including the NUL, the args must not grow past this point.  */
459   char *endbuf = linebuf + arg_max - initial_argv_chars - 1;
460
461   if (eof)
462     return -1;
463   while (1)
464     {
465       prevc = c;
466       c = getc (stdin);
467       if (c == EOF)
468         {
469           /* COMPAT: SYSV seems to ignore stuff on a line that
470              ends without a \n; we don't.  */
471           eof = true;
472           if (p == linebuf)
473             return -1;
474           *p++ = '\0';
475           len = p - linebuf;
476           /* FIXME we don't check for unterminated quotes here.  */
477           if (first && EOF_STR (linebuf))
478             return -1;
479           if (!replace_pat)
480             push_arg (linebuf, len);
481           return len;
482         }
483       switch (state)
484         {
485         case SPACE:
486           if (ISSPACE (c))
487             continue;
488           state = NORM;
489           /* aaahhhh....  */
490
491         case NORM:
492           if (c == '\n')
493             {
494               if (!ISBLANK (prevc))
495                 lineno++;       /* For -l.  */
496               if (p == linebuf)
497                 {
498                   /* Blank line.  */
499                   state = SPACE;
500                   continue;
501                 }
502               *p++ = '\0';
503               len = p - linebuf;
504               if (EOF_STR (linebuf))
505                 {
506                   eof = true;
507                   return first ? -1 : len;
508                 }
509               if (!replace_pat)
510                 push_arg (linebuf, len);
511               return len;
512             }
513           if (!replace_pat && ISSPACE (c))
514             {
515               *p++ = '\0';
516               len = p - linebuf;
517               if (EOF_STR (linebuf))
518                 {
519                   eof = true;
520                   return first ? -1 : len;
521                 }
522               push_arg (linebuf, len);
523               p = linebuf;
524               state = SPACE;
525               first = false;
526               continue;
527             }
528           switch (c)
529             {
530             case '\\':
531               state = BACKSLASH;
532               continue;
533
534             case '\'':
535             case '"':
536               state = QUOTE;
537               quotc = c;
538               continue;
539             }
540           break;
541
542         case QUOTE:
543           if (c == '\n')
544             fatalError ("unmatched %s quote", quotc == '"' ? "double" : "single");
545           if (c == quotc)
546             {
547               state = NORM;
548               continue;
549             }
550           break;
551
552         case BACKSLASH:
553           state = NORM;
554           break;
555         }
556       if (p >= endbuf)
557         fatalError ("argument line too long");
558       *p++ = c;
559     }
560 }
561
562 /* Read a null-terminated string from stdin and add it to the list of
563    arguments to pass to the command.
564    Return -1 if eof (either physical or logical) is reached,
565    otherwise the length of the string read (including the null).  */
566
567 static int
568 read_string ()
569 {
570   static boolean eof = false;
571   int len;
572   char *p = linebuf;
573   /* Including the NUL, the args must not grow past this point.  */
574   char *endbuf = linebuf + arg_max - initial_argv_chars - 1;
575
576   if (eof)
577     return -1;
578   while (1)
579     {
580       int c = getc (stdin);
581       if (c == EOF)
582         {
583           eof = true;
584           if (p == linebuf)
585             return -1;
586           *p++ = '\0';
587           len = p - linebuf;
588           if (!replace_pat)
589             push_arg (linebuf, len);
590           return len;
591         }
592       if (c == '\0')
593         {
594           lineno++;             /* For -l.  */
595           *p++ = '\0';
596           len = p - linebuf;
597           if (!replace_pat)
598             push_arg (linebuf, len);
599           return len;
600         }
601       if (p >= endbuf)
602         fatalError ("argument line too long");
603       *p++ = c;
604     }
605 }
606
607 /* Replace all instances of `replace_pat' in ARG with `linebuf',
608    and add the resulting string to the list of arguments for the command
609    to execute.
610    ARGLEN is the length of ARG, not including the null.
611    LBLEN is the length of `linebuf', not including the null.
612
613    COMPAT: insertions on the SYSV version are limited to 255 chars per line,
614    and a max of 5 occurences of replace_pat in the initial-arguments.
615    Those restrictions do not exist here.  */
616
617 static void
618 do_insert (arg, arglen, lblen)
619      char *arg;
620      size_t arglen;
621      size_t lblen;
622 {
623   /* Temporary copy of each arg with the replace pattern replaced by the
624      real arg.  */
625   static char *insertbuf;
626   char *p;
627   int bytes_left = arg_max - 1; /* Bytes left on the command line.  */
628
629   if (!insertbuf)
630     insertbuf = (char *) xmalloc (arg_max + 1);
631   p = insertbuf;
632
633   do
634     {
635       size_t len;               /* Length in ARG before `replace_pat'.  */
636       char *s = strstr (arg, replace_pat);
637       if (s)
638         len = s - arg;
639       else
640         len = arglen;
641       bytes_left -= len;
642       if (bytes_left <= 0)
643         break;
644
645       strncpy (p, arg, len);
646       p += len;
647       arg += len;
648       arglen -= len;
649
650       if (s)
651         {
652           bytes_left -= lblen;
653           if (bytes_left <= 0)
654             break;
655           strcpy (p, linebuf);
656           arg += rplen;
657           arglen -= rplen;
658           p += lblen;
659         }
660     }
661   while (*arg);
662   if (*arg)
663     fatalError ("command too long");
664   *p++ = '\0';
665   push_arg (insertbuf, p - insertbuf);
666 }
667
668 /* Add ARG to the end of the list of arguments `cmd_argv' to pass
669    to the command.
670    LEN is the length of ARG, including the terminating null.
671    If this brings the list up to its maximum size, execute the command.  */
672
673 static void
674 push_arg (arg, len)
675      char *arg;
676      size_t len;
677 {
678   if (arg)
679     {
680       if (cmd_argv_chars + len > arg_max)
681         {
682           if (initial_args || cmd_argc == initial_argc)
683             fatalError ("can not fit single argument within argument list size limit");
684           if (replace_pat
685               || (exit_if_size_exceeded &&
686                   (lines_per_exec || args_per_exec)))
687             fatalError ("argument list too long");
688           do_exec ();
689         }
690       if (!initial_args && args_per_exec &&
691           cmd_argc - initial_argc == args_per_exec)
692         do_exec ();
693     }
694
695   if (cmd_argc >= cmd_argv_alloc)
696     {
697       if (!cmd_argv)
698         {
699           cmd_argv_alloc = 64;
700           cmd_argv = (char **) xmalloc (sizeof (char *) * cmd_argv_alloc);
701         }
702       else
703         {
704           cmd_argv_alloc *= 2;
705           cmd_argv = (char **) xrealloc (cmd_argv,
706                                          sizeof (char *) * cmd_argv_alloc);
707         }
708     }
709
710   if (!arg)
711     cmd_argv[cmd_argc++] = NULL;
712   else
713     {
714       cmd_argv[cmd_argc++] = argbuf + cmd_argv_chars;
715       strcpy (argbuf + cmd_argv_chars, arg);
716       cmd_argv_chars += len;
717     }
718 }
719
720 /* Print the arguments of the command to execute.
721    If ASK is nonzero, prompt the user for a response, and
722    if the user responds affirmatively, return true;
723    otherwise, return false.  */
724
725 static boolean
726 print_args (ask)
727      boolean ask;
728 {
729   int i;
730
731   for (i = 0; i < cmd_argc - 1; i++)
732     fprintf (stderr, "%s ", cmd_argv[i]);
733   if (ask)
734     {
735       static FILE *tty_stream;
736       int c, savec;
737
738       if (!tty_stream)
739         {
740           tty_stream = fopen ("/dev/tty", "r");
741           if (!tty_stream)
742             fatalError (" Could not open /dev/tty");
743         }
744       fputs ("?...", stderr);
745       fflush (stderr);
746       c = savec = getc (tty_stream);
747       while (c != EOF && c != '\n')
748         c = getc (tty_stream);
749       if (savec == 'y' || savec == 'Y')
750         return true;
751     }
752   else
753     putc ('\n', stderr);
754
755   return false;
756 }
757
758 /* Execute the command that has been built in `cmd_argv'.  This may involve
759    waiting for processes that were previously executed.  */
760
761 static void
762 do_exec ()
763 {
764   pid_t child;
765
766   push_arg ((char *) NULL, 0);  /* Null terminate the arg list.  */
767   if (!query_before_executing || print_args (true))
768     {
769       if (proc_max && procs_executing >= proc_max)
770         wait_for_proc (false);
771       if (!query_before_executing && print_command)
772         print_args (false);
773       /* If we run out of processes, wait for a child to return and
774          try again.  */
775       while ((child = fork ()) < 0 && errno == EAGAIN && procs_executing)
776         wait_for_proc (false);
777       switch (child)
778         {
779         case -1:
780           fatalError ("cannot fork");
781
782         case 0:         /* Child.  */
783           execvp (cmd_argv[0], cmd_argv);
784           errorMsg ("failed to exec '%s'", cmd_argv[0]);
785           _exit (errno == ENOENT ? 127 : 126);
786         }
787       add_proc (child);
788     }
789
790   cmd_argc = initial_argc;
791   cmd_argv_chars = initial_argv_chars;
792 }
793
794 /* Add the process with id PID to the list of processes that have
795    been executed.  */
796
797 static void
798 add_proc (pid)
799      pid_t pid;
800 {
801   int i;
802
803   /* Find an empty slot.  */
804   for (i = 0; i < pids_alloc && pids[i]; i++)
805     ;
806   if (i == pids_alloc)
807     {
808       if (pids_alloc == 0)
809         {
810           pids_alloc = proc_max ? proc_max : 64;
811           pids = (pid_t *) xmalloc (sizeof (pid_t) * pids_alloc);
812         }
813       else
814         {
815           pids_alloc *= 2;
816           pids = (pid_t *) xrealloc (pids,
817                                      sizeof (pid_t) * pids_alloc);
818         }
819       memset (&pids[i], '\0', sizeof (pid_t) * (pids_alloc - i));
820     }
821   pids[i] = pid;
822   procs_executing++;
823   procs_executed++;
824 }
825
826 /* If ALL is true, wait for all child processes to finish;
827    otherwise, wait for one child process to finish.
828    Remove the processes that finish from the list of executing processes.  */
829
830 static void
831 wait_for_proc (all)
832      boolean all;
833 {
834   while (procs_executing)
835     {
836       int i, status;
837
838       do
839         {
840           pid_t pid;
841
842           pid = wait (&status);
843           if (pid < 0)
844             fatalError ("error waiting for child process");
845
846           /* Find the entry in `pids' for the child process
847              that exited.  */
848           for (i = 0; i < pids_alloc && pid != pids[i]; i++)
849             ;
850         }
851       while (i == pids_alloc);  /* A child died that we didn't start? */
852
853       /* Remove the child from the list.  */
854       pids[i] = 0;
855       procs_executing--;
856
857       if (WEXITSTATUS (status) == 126 || WEXITSTATUS (status) == 127)
858         exit (WEXITSTATUS (status));    /* Can't find or run the command.  */
859       if (WEXITSTATUS (status) == 255)
860         fatalError ( "%s: exited with status 255; aborting", cmd_argv[0]);
861       if (WIFSTOPPED (status))
862         fatalError ( "%s: stopped by signal %d", cmd_argv[0], WSTOPSIG (status));
863       if (WIFSIGNALED (status))
864         fatalError ("%s: terminated by signal %d", cmd_argv[0], WTERMSIG (status));
865       if (WEXITSTATUS (status) != 0)
866         child_error = 123;
867
868       if (!all)
869         break;
870     }
871 }
872
873 /* Return the value of the number represented in STR.
874    OPTION is the command line option to which STR is the argument.
875    If the value does not fall within the boundaries MIN and MAX,
876    Print an error message mentioning OPTION and exit.  */
877
878 static long
879 parse_num (str, option, min, max)
880      char *str;
881      int option;
882      long min;
883      long max;
884 {
885   char *eptr;
886   long val;
887
888   val = strtol (str, &eptr, 10);
889   if (eptr == str || *eptr)
890     {
891       fprintf (stderr, "%s: invalid number for -%c option\n",
892                program_name, option);
893       usage (xargs_usage);
894     }
895   else if (val < min)
896     {
897       fprintf (stderr, "%s: value for -%c option must be >= %ld\n",
898                program_name, option, min);
899       usage (xargs_usage);
900     }
901   else if (max >= 0 && val > max)
902     {
903       fprintf (stderr, "%s: value for -%c option must be < %ld\n",
904                program_name, option, max);
905       usage (xargs_usage);
906     }
907   return val;
908 }
909
910 /* Return how much of ARG_MAX is used by the environment.  */
911
912 static long
913 env_size (envp)
914      char **envp;
915 {
916   long len = 0;
917
918   while (*envp)
919     len += strlen (*envp++) + 1;
920
921   return len;
922 }
923