diff options
author | Rob Landley <rob@landley.net> | 2024-02-21 09:45:03 -0600 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2024-02-21 09:45:03 -0600 |
commit | b89c8914513ea055fdb686a765aaf4c65eaf706d (patch) | |
tree | fc3559707f21424c9965da5a9f4cd943c921b4f3 /toys | |
parent | f79b72761f4950021cf97e8c683830d1ff969ead (diff) | |
download | toybox-b89c8914513ea055fdb686a765aaf4c65eaf706d.tar.gz |
When xargs child exits with 255, stop processing input.
Diffstat (limited to 'toys')
-rw-r--r-- | toys/posix/xargs.c | 60 |
1 files changed, 30 insertions, 30 deletions
diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c index c5dca26a..c2a1f02d 100644 --- a/toys/posix/xargs.c +++ b/toys/posix/xargs.c @@ -98,10 +98,25 @@ static void signal_P(int sig) else TT.P++; } +static void waitchild(int options) +{ + int ii, status; + + if (1>waitpid(-1, &status, options)) return; + TT.np--; + ii = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+128; + if (ii == 255) { + error_msg("%s: exited with status 255; aborting", *toys.optargs); + toys.exitval = 124; + } else if ((ii|1)==127) toys.exitval = ii; + else if (ii>127) toys.exitval = 125; + else if (ii) toys.exitval = 123; +} + void xargs_main(void) { struct double_list *dlist = 0, *dtemp; - int entries, bytes, done = 0, status; + int entries, bytes, done = 0; char *data = 0, **out = 0; pid_t pid = 0; @@ -133,10 +148,17 @@ void xargs_main(void) while (data || !done) { TT.entries = 0; TT.bytes = bytes; + if (TT.np) waitchild(WNOHANG*!(TT.np==TT.P||(!data && done))); + if (toys.exitval==124) break; + + // Arbitrary number of execs, can't just leak memory each time... + llist_traverse(dlist, llist_free_double); + dlist = 0; + free(out); + out = 0; // Loop reading input for (;;) { - // Read line if (!data) { size_t l = 0; @@ -159,15 +181,15 @@ void xargs_main(void) if (!TT.entries) { if (data) error_exit("argument too long"); - if (pid || FLAG(r)) goto reap_children; + if (pid || FLAG(r)) break; } // Fill out command line to exec - out = xzalloc((entries+TT.entries+1)*sizeof(char *)); - memcpy(out, toys.optargs, entries*sizeof(char *)); + out = xzalloc((toys.optc+TT.entries+1)*sizeof(char *)); + memcpy(out, toys.optargs, toys.optc*sizeof(char *)); TT.entries = 0; TT.bytes = bytes; - if (dlist) dlist->prev->next = 0; + dlist_terminate(dlist); for (dtemp = dlist; dtemp; dtemp = dtemp->next) handle_entries(dtemp->data, out+entries); @@ -178,7 +200,7 @@ void xargs_main(void) if (FLAG(p)) { fprintf(stderr, "?"); if (!TT.tty) TT.tty = xfopen("/dev/tty", "re"); - if (!fyesno(TT.tty, 0)) goto reap_children; + if (!fyesno(TT.tty, 0)) continue; } else fprintf(stderr, "\n"); } @@ -188,29 +210,7 @@ void xargs_main(void) xexec(out); } TT.np++; - -reap_children: - while (TT.np) { - int xv = (TT.np == TT.P) || (!data && done); - - if (1>(xv = waitpid(-1, &status, WNOHANG*!xv))) break; - TT.np--; - xv = WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+128; - if (xv == 255) { - error_msg("%s: exited with status 255; aborting", *out); - toys.exitval = 124; - break; - } else if ((xv|1)==127) toys.exitval = xv; - else if (xv>127) xv = 125; - else if (xv) toys.exitval = 123; - } - - // Abritrary number of execs, can't just leak memory each time... - llist_traverse(dlist, llist_free_double); - dlist = 0; - free(out); - out = 0; } - while (TT.np && -1 != wait(&status)) TT.np--; + while (TT.np) waitchild(0); if (TT.tty) fclose(TT.tty); } |