Merge to trunk from 4.2.x fixes

This commit is contained in:
James Youngman 2005-11-24 01:41:47 +00:00
parent dd0afc6850
commit ceb1f0aef4
3 changed files with 55 additions and 10 deletions

8
NEWS
View File

@ -18,6 +18,10 @@ can be read, written or executed respectively.
** Bug Fixes
If xargs is invoked with many short arguments on PPC systems running
the Linux kernel, we no longer get an "argument list too long" error
from the operating system.
Fixed a bug in the test suite which caused it to spuriously fail on
systems where ARG_MAX is different to the value used by the Linux
kernel on 32-bit x86-architecture systems.
@ -31,6 +35,10 @@ remounted elsewhere using "mount --bind". (Savannah bug #14921).
The %M format specifier of "find -printf" is now documented, although
it has existed since release 4.2.5.
The 'find' manual page now correctly documents the fact that -regex
defaults to using Emacs-style regular expressions (though this can be
changed).
* Major changes in release 4.2.26
** Public Service Announcements

View File

@ -74,6 +74,8 @@
/* for sysconf() */
#include <unistd.h>
#include <assert.h>
/* COMPAT: SYSV version defaults size (and has a max value of) to 470.
We try to make it as large as possible. */
#if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
@ -118,7 +120,12 @@ bc_do_insert (const struct buildcmd_control *ctl,
char *p;
int bytes_left = ctl->arg_max - 1; /* Bytes left on the command line. */
int need_prefix;
/* XXX: on systems lacking an upper limit for exec args, ctl->arg_max
* may have been set to LONG_MAX (see bc_get_arg_max()). Hence
* this xmalloc call may be a bad idea, especially since we are
* adding 1 to it...
*/
if (!insertbuf)
insertbuf = (char *) xmalloc (ctl->arg_max + 1);
p = insertbuf;
@ -183,22 +190,28 @@ void do_exec(const struct buildcmd_control *ctl,
}
/* Return nonzero if there would not be enoughy room for an additional
* argument. If we return zero, there still may not be enough room
* for the next one, depending on its length.
/* Return nonzero if there would not be enough room for an additional
* argument. We check the total number of arguments only, not the space
* occupied by those arguments.
*
* If we return zero, there still may not be enough room for the next
* argument, depending on its length.
*/
static int
bc_argc_limit_reached(int initial_args,
const struct buildcmd_control *ctl,
struct buildcmd_state *state)
{
/* Check to see if we about to exceed a limit set by xargs' -n option */
if (!initial_args && ctl->args_per_exec &&
( (state->cmd_argc - ctl->initial_argc) == ctl->args_per_exec))
return 1;
else if (state->cmd_argc == ARG_MAX / sizeof (void *) - 1)
return 1;
else
return 0;
/* We deliberately use an equality test here rather than >= in order
* to force a software failure if the code is modified in such a way
* that it fails to call this function for every new argument.
*/
return state->cmd_argc == ctl->max_arg_count;
}
@ -359,8 +372,14 @@ static int cb_exec_noop(const struct buildcmd_control *ctl,
void
bc_init_controlinfo(struct buildcmd_control *ctl)
{
long arg_max = bc_get_arg_max();
assert(arg_max > 0);
ctl->exit_if_size_exceeded = 0;
ctl->arg_max = bc_get_arg_max() - 2048; /* a la xargs */
ctl->arg_max = arg_max - 2048; /* a la xargs */
/* need to subtract 2 on the following line - for Linux/PPC */
ctl->max_arg_count = (arg_max / sizeof(void*)) - 2;
assert(ctl->max_arg_count > 0);
ctl->rplen = 0u;
ctl->replace_pat = NULL;
ctl->initial_argc = 0;
@ -378,7 +397,13 @@ bc_init_state(const struct buildcmd_control *ctl,
state->cmd_argv_chars = 0;
state->cmd_argv = NULL;
state->cmd_argv_alloc = 0;
/* XXX: the following memory allocation is inadvisable on systems
* with no ARG_MAX, because ctl->arg_max may actually be LONG_MAX.
* Also, adding one to that is a bad idea.
*/
state->argbuf = (char *) xmalloc (ctl->arg_max + 1);
state->cmd_argv_chars = state->cmd_initial_argv_chars = 0;
state->todo = 0;
state->usercontext = context;

View File

@ -57,6 +57,18 @@ struct buildcmd_control
/* The maximum number of characters that can be used per command line. */
long arg_max;
/* max_arg_count: the maximum number of arguments that can be used.
*
* Many systems include the size of the pointers in ARG_MAX.
* Linux on PPC fails if we just subtract 1 here.
*
* However, not all systems define ARG_MAX. Our bc_get_arg_max()
* function returns a useful value even if ARG_MAX is not defined.
* However, sometimes, max_arg_count is LONG_MAX!
*/
long max_arg_count;
/* The length of `replace_pat'. */
size_t rplen;
@ -78,7 +90,7 @@ struct buildcmd_control
long lines_per_exec; /* 0 */
/* The maximum number of arguments to use per command line. */
long args_per_exec; /* 1024 */
long args_per_exec;
};