mirror of
https://https.git.savannah.gnu.org/git/findutils.git
synced 2026-01-26 15:39:06 +00:00
xargs: Wait for all children even if one exited with 255.
* xargs/xargs.c: fix Savannah bug #64451 (xargs -P exits before all children have exited if one exits with status 255). * xargs/xargs.1 (BUGS): mention this bug and the corrected behaviour. * doc/find.texi: Likewise. * NEWS: mention this bugfix.
This commit is contained in:
parent
8368fd0b2a
commit
ad636eae01
3
NEWS
3
NEWS
@ -4,6 +4,9 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout)
|
||||
|
||||
** Bug Fixes
|
||||
|
||||
xargs -P now waits for all its child processes to compete before
|
||||
exiting, even if one of them exits with status 255. [#64451]
|
||||
|
||||
'find -name /' no longer outputs a warning, because that is a valid pattern
|
||||
to match the root directory "/". Previously, a diagnostic falsely claimed
|
||||
that this pattern would not match anything. [#62227]
|
||||
|
||||
@ -2740,7 +2740,9 @@ Run up to @var{max-procs} processes at a time; the default is 1. If
|
||||
@var{max-procs} is 0, @code{xargs} will run as many processes as
|
||||
possible at a time. Use the @samp{-n}, @samp{-s}, or @samp{-L} option
|
||||
with @samp{-P}; otherwise chances are that the command will be run
|
||||
only once.
|
||||
only once. If a child process exits with status 255, @code{xargs} will
|
||||
still wait for all child processes to exit (before version 4.9.0 this
|
||||
might not happen).
|
||||
@end table
|
||||
|
||||
For example, suppose you have a directory tree of large image files
|
||||
|
||||
@ -225,6 +225,9 @@ You cannot decrease it below 1.
|
||||
never terminates its commands; when asked to decrease, it merely
|
||||
waits for more than one existing command to terminate before starting
|
||||
another.
|
||||
.B xargs
|
||||
always waits for all child processes to exit before exiting itself
|
||||
(but see BUGS).
|
||||
|
||||
.B Please note
|
||||
that it is up to the called processes to properly manage parallel
|
||||
@ -532,6 +535,13 @@ which is why this discussion appears in the BUGS section.
|
||||
The problem doesn't occur with the output of
|
||||
.BR find (1)
|
||||
because it emits just one filename per line.
|
||||
.P
|
||||
In versions of
|
||||
.B xargs
|
||||
up to and including version 4.9.0,
|
||||
.B xargs -P
|
||||
would exit while some of its children were still running, if one of
|
||||
them exited with status 255.
|
||||
.
|
||||
.SH "REPORTING BUGS"
|
||||
GNU findutils online help: <https://www.gnu.org/software/findutils/#get-help>
|
||||
|
||||
@ -1494,6 +1494,7 @@ static void
|
||||
wait_for_proc (bool all, unsigned int minreap)
|
||||
{
|
||||
unsigned int reaped = 0;
|
||||
int deferred_exit_status = 0;
|
||||
|
||||
while (procs_executing)
|
||||
{
|
||||
@ -1576,17 +1577,44 @@ wait_for_proc (bool all, unsigned int minreap)
|
||||
procs_executing--;
|
||||
reaped++;
|
||||
|
||||
#define set_deferred_exit_status(n) \
|
||||
do \
|
||||
{ \
|
||||
if (deferred_exit_status < n) \
|
||||
{ \
|
||||
deferred_exit_status = n; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
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]);
|
||||
{
|
||||
error (0, 0, _("%s: exited with status 255; aborting"), bc_state.cmd_argv[0]);
|
||||
set_deferred_exit_status(XARGS_EXIT_CLIENT_EXIT_255);
|
||||
}
|
||||
if (WIFSTOPPED (status))
|
||||
error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
|
||||
_("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status));
|
||||
{
|
||||
error (0, 0, _("%s: stopped by signal %d"), bc_state.cmd_argv[0], WSTOPSIG (status));
|
||||
set_deferred_exit_status(XARGS_EXIT_CLIENT_FATAL_SIG);
|
||||
}
|
||||
if (WIFSIGNALED (status))
|
||||
error (XARGS_EXIT_CLIENT_FATAL_SIG, 0,
|
||||
_("%s: terminated by signal %d"), bc_state.cmd_argv[0], WTERMSIG (status));
|
||||
{
|
||||
error (0, 0,
|
||||
_("%s: terminated by signal %d"), bc_state.cmd_argv[0], WTERMSIG (status));
|
||||
set_deferred_exit_status(XARGS_EXIT_CLIENT_FATAL_SIG);
|
||||
}
|
||||
if (WEXITSTATUS (status) != 0)
|
||||
child_error = XARGS_EXIT_CLIENT_EXIT_NONZERO;
|
||||
{
|
||||
child_error = XARGS_EXIT_CLIENT_EXIT_NONZERO;
|
||||
}
|
||||
if (deferred_exit_status && !all)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (deferred_exit_status)
|
||||
{
|
||||
child_error = deferred_exit_status > child_error ? deferred_exit_status : child_error;
|
||||
exit (child_error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user