I would like xargs to attempt to terminate its children when one of them returns with the code 255 to stop immediately, whereas currently xargs imposes unnecessary delay and, when process produce output, makes the output of a failing process to be buried behind output from remaining running processes.
--- xargs/xargs.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/xargs/xargs.c b/xargs/xargs.c index 5cf8c13..2541f3b 100644 --- a/xargs/xargs.c +++ b/xargs/xargs.c @@ -133,6 +133,9 @@ static bool procs_executed = false; /* The number of elements in `pids'. */ static unsigned long int procs_executing = 0uL; +/* Should we terminate child processes at exit? */ +static bool kill_children_at_exit = false; + /* List of child processes currently executing. */ static pid_t *pids = NULL; @@ -1455,13 +1458,23 @@ wait_for_proc (bool all, unsigned int minreap) wflags = WNOHANG; } } + else if (kill_children_at_exit) + { + for (i = 0; i < pids_alloc; i++) + { + if (pids[i] != 0) + { + kill(pids[i], SIGTERM); + } + } + } stop_waiting = 0; do { /* Wait for any child. We used to use wait () here, but it's * unlikely that that offers any portability advantage over - * wait these days. + * waitpid these days. */ while ((pid = waitpid (-1, &status, wflags)) == (pid_t) -1) { @@ -1518,8 +1531,11 @@ wait_for_proc (bool all, unsigned int minreap) reaped++; if (WEXITSTATUS (status) == CHILD_EXIT_PLEASE_STOP_IMMEDIATELY) - error (XARGS_EXIT_CLIENT_EXIT_255, 0, - _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]); + { + kill_children_at_exit = true; + error (XARGS_EXIT_CLIENT_EXIT_255, 0, + _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]); + } if (WIFSTOPPED (status)) error (XARGS_EXIT_CLIENT_FATAL_SIG, 0, _("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status)); -- 2.7.2