* lib/buildcmd.c (bc_do_exec): Declare variables at the top of the relevant block, in order to avoid mixing declarations and statements. * xargs/xargs.c (main): Likewise.
* NEWS: Mention the fix for bug #22708 in the correct section. --- ChangeLog | 46 ++++++++++++++++++++++++++++++++++++++++++++++ NEWS | 17 ++++++++++++----- lib/buildcmd.c | 21 ++++++++++++--------- xargs/xargs.c | 3 ++- 4 files changed, 72 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 06e3d71..5b91447 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,49 @@ +2009-04-12 James Youngman <[email protected]> + + * NEWS: Mention the fix for bug #22708 in the correct section. + + Avoid mixing declarations and statements. + * lib/buildcmd.c (bc_do_exec): Declare variables at the top of the + relevant block, in order to avoid mixing declarations and + statements. + * xargs/xargs.c (main): Likewise. + +2009-04-12 Leslie Polzer <[email protected]> + + Merge Leslie Polzer's ARG_MAX enhancements to xargs which were + produced as part of the Google Summer of Code 2007. + These changes fix Savannah bug #22708. + * find/pred.c (launch): The struct buildcmd_control* argument is + no longer const. + * find/defs.h: Likewise + * lib/buildcmd.c (bc_do_insert): The struct buildcmd_control* + argument is no longer const. + (bc_push_arg): Likewise. + (cb_exec_noop): Likewise. + (get_stringv_len): New function; measures the length of + a NULL-terminated argv sequence. + (bc_do_exec): Rename from do_exec, and make global. Modify the + function to react to exec failing with E2BIG by trying again + with fewer arguments. + * xargs/xargs.1: Mention that xargs automatically adopts to the + situation where exec fails with E2BIG. + * xargs/xargs.c: (parent): New variable, the PID of the parent + process. + (main): initialise the variable 'parent'. Don't fail immediately + due to lack of space when the environment is large. Call + xargs_do_exec via bc_do_exec. + (xargs_do_exec): The struct buildcmd_control* argument is no + longer const. When exec fails in the child, communicate the + errno value back to the parent through a pipe which is + close-on-exec; this allows us to accurately determine the cause of + the failure and also to distinguish exec failures from all + possible exit codes in the child. + (wait_for_proc): If the utility cannot be found or cannot be run, + we now find out about this by reading an errno value from the + pipe, so this means that exit codes 126 and 127 in the child no + longer have a special interpretation. + * NEWS: mention these changes. + 2009-03-07 James Youngman <[email protected]> Update the code to better reflect the semantics of digest_mode(). diff --git a/NEWS b/NEWS index fe9b426..5fe3ebe 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,18 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout) * Major changes in release 4.5.5-git, YYYY-MM-DD +xargs now handles the case where the system's actual exec limits are +smaller than the value of ARG_MAX at compile time. Very few platforms +normally have this property, but it is possible to configure some Unix +systems this way. + +** Bug Fixes + +#22708: Exit status 126 and 127 from the utility invoked from xargs +now makes xargs return 123, meaning that exit status values 126 and +127 now unambigously mean that the utility could not be run or could +not be found, respectively. + * Major changes in release 4.5.4, 2009-03-10 ** Performance changes @@ -37,11 +49,6 @@ declarations to follow statements. #24342: -inum predicate shoud use dirent.d_ino instead of stat.st_ino (this is a performance bug). -#22708: Exit status 126 and 127 from the utility invoked from xargs -now makes xargs return 123, meaning that exit status values 126 and -127 now unambigously mean that the utility could not be run or could -not be found, respectively. - ** Translations Updated translations for Bulgarian, German, Irish, Hungarian, diff --git a/lib/buildcmd.c b/lib/buildcmd.c index 5fcced1..8cf8ff1 100644 --- a/lib/buildcmd.c +++ b/lib/buildcmd.c @@ -184,21 +184,25 @@ void bc_do_exec(struct buildcmd_control *ctl, struct buildcmd_state *state) { + int argc_orig; + char** argv_orig; + char** initial_args; + int i, pos, done, argc_current; + bc_push_arg (ctl, state, (char *) NULL, 0, NULL, 0, false); /* Null terminate the arg list. */ /* save original argv data so we can free the memory later */ - int argc_orig = state->cmd_argc; - char** argv_orig = state->cmd_argv; + argc_orig = state->cmd_argc; + argv_orig = state->cmd_argv; if ((ctl->exec_callback)(ctl, state)) goto fin; /* got E2BIG, adjust arguments */ - char** initial_args = xmalloc(ctl->initial_argc * sizeof(char*)); - int i; + initial_args = xmalloc(ctl->initial_argc * sizeof(char*)); for (i=0; i<ctl->initial_argc; ++i) initial_args[i] = argv_orig[i]; @@ -206,15 +210,14 @@ bc_do_exec(struct buildcmd_control *ctl, state->cmd_argv += ctl->initial_argc; - int pos; - int done = 0; /* number of argv elements we have relayed successfully */ - - int argc_current = state->cmd_argc; + done = 0; /* number of argv elements we have relayed successfully */ + argc_current = state->cmd_argc; pos = -1; /* array offset from the right end */ for (;;) { + int r; int divider = argc_current+pos; char* swapped_out = state->cmd_argv[divider]; state->cmd_argv[divider] = NULL; @@ -230,7 +233,7 @@ bc_do_exec(struct buildcmd_control *ctl, state->cmd_argv[i] = initial_args[i]; ++state->cmd_argc; /* include trailing NULL */ - int r = (ctl->exec_callback)(ctl, state); + r = (ctl->exec_callback)(ctl, state); state->cmd_argv += ctl->initial_argc; state->cmd_argc -= ctl->initial_argc; --state->cmd_argc; /* exclude trailing NULL again */ diff --git a/xargs/xargs.c b/xargs/xargs.c index 0f41a37..46c3cf0 100644 --- a/xargs/xargs.c +++ b/xargs/xargs.c @@ -437,9 +437,10 @@ main (int argc, char **argv) * environment list shall not exceed {ARG_MAX}-2048 bytes. It also * specifies that it shall be at least LINE_MAX. */ + long val; assert(bc_ctl.arg_max <= (ARG_MAX-2048)); #ifdef _SC_ARG_MAX - long val = sysconf(_SC_ARG_MAX); + val = sysconf(_SC_ARG_MAX); if (val > 0) { /* Note that val can in fact be greater than ARG_MAX -- 1.5.6.5
