aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-04-09 14:58:40 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-04-09 14:58:40 +0200
commitd7b5289209131ae94b540b35f0f147d2302ec0c9 (patch)
tree99f42a344c1216060dc7fe8347c5e1773d1e0d52
parent125d0154e6c591addbaf1fae7c9ffdf5b7e7ed7b (diff)
downloadbusybox-w32-d7b5289209131ae94b540b35f0f147d2302ec0c9.tar.gz
busybox-w32-d7b5289209131ae94b540b35f0f147d2302ec0c9.tar.bz2
busybox-w32-d7b5289209131ae94b540b35f0f147d2302ec0c9.zip
xargs: do not decrease orig_arg_max to negative values
Based on patch by Nguyễn Thái Ngọc Duy <pclouds@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--findutils/xargs.c45
1 files changed, 25 insertions, 20 deletions
diff --git a/findutils/xargs.c b/findutils/xargs.c
index f5dbc7825..3785f1ec0 100644
--- a/findutils/xargs.c
+++ b/findutils/xargs.c
@@ -25,10 +25,10 @@
25/* COMPAT: SYSV version defaults size (and has a max value of) to 470. 25/* COMPAT: SYSV version defaults size (and has a max value of) to 470.
26 We try to make it as large as possible. */ 26 We try to make it as large as possible. */
27#if !defined(ARG_MAX) && defined(_SC_ARG_MAX) 27#if !defined(ARG_MAX) && defined(_SC_ARG_MAX)
28#define ARG_MAX sysconf (_SC_ARG_MAX) 28# define ARG_MAX sysconf(_SC_ARG_MAX)
29#endif 29#endif
30#ifndef ARG_MAX 30#if !defined(ARG_MAX)
31#define ARG_MAX 470 31# define ARG_MAX 470
32#endif 32#endif
33 33
34 34
@@ -378,8 +378,6 @@ int xargs_main(int argc, char **argv)
378 int child_error = 0; 378 int child_error = 0;
379 char *max_args, *max_chars; 379 char *max_args, *max_chars;
380 int n_max_arg; 380 int n_max_arg;
381 size_t n_chars = 0;
382 long orig_arg_max;
383 const char *eof_str = NULL; 381 const char *eof_str = NULL;
384 unsigned opt; 382 unsigned opt;
385 size_t n_max_chars; 383 size_t n_max_chars;
@@ -408,28 +406,35 @@ int xargs_main(int argc, char **argv)
408 argc++; 406 argc++;
409 } 407 }
410 408
411 orig_arg_max = ARG_MAX; 409 n_max_chars = ARG_MAX; /* might be calling sysconf(_SC_ARG_MAX) */
412 if (orig_arg_max == -1) 410 if (n_max_chars < 4*1024); /* paranoia */
413 orig_arg_max = LONG_MAX; 411 n_max_chars = LONG_MAX;
414 orig_arg_max -= 2048; /* POSIX.2 requires subtracting 2048 */ 412 /* The Open Group Base Specifications Issue 6:
413 * "The xargs utility shall limit the command line length such that
414 * when the command line is invoked, the combined argument
415 * and environment lists (see the exec family of functions
416 * in the System Interfaces volume of IEEE Std 1003.1-2001)
417 * shall not exceed {ARG_MAX}-2048 bytes".
418 */
419 n_max_chars -= 2048;
420 /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which
421 * have it at 1 meg). Things will work fine with a large ARG_MAX but it
422 * will probably hurt the system more than it needs to; an array of this
423 * size is allocated.
424 */
425 if (n_max_chars > 20 * 1024)
426 n_max_chars = 20 * 1024;
415 427
416 if (opt & OPT_UPTO_SIZE) { 428 if (opt & OPT_UPTO_SIZE) {
417 n_max_chars = xatoul_range(max_chars, 1, orig_arg_max); 429 size_t n_chars = 0;
430 n_max_chars = xatoul_range(max_chars, 1, n_max_chars);
418 for (i = 0; i < argc; i++) { 431 for (i = 0; i < argc; i++) {
419 n_chars += strlen(*argv) + 1; 432 n_chars += strlen(*argv) + 1;
420 } 433 }
421 if (n_max_chars < n_chars) { 434 if (n_max_chars <= n_chars) {
422 bb_error_msg_and_die("can't fit single argument within argument list size limit"); 435 bb_error_msg_and_die("can't fit single argument within argument list size limit");
423 } 436 }
424 n_max_chars -= n_chars; 437 n_max_chars -= n_chars;
425 } else {
426 /* Sanity check for systems with huge ARG_MAX defines (e.g., Suns which
427 have it at 1 meg). Things will work fine with a large ARG_MAX but it
428 will probably hurt the system more than it needs to; an array of this
429 size is allocated. */
430 if (orig_arg_max > 20 * 1024)
431 orig_arg_max = 20 * 1024;
432 n_max_chars = orig_arg_max;
433 } 438 }
434 max_chars = xmalloc(n_max_chars); 439 max_chars = xmalloc(n_max_chars);
435 440
@@ -442,9 +447,9 @@ int xargs_main(int argc, char **argv)
442 while ((list = read_args(list, eof_str, n_max_chars, max_chars)) != NULL || 447 while ((list = read_args(list, eof_str, n_max_chars, max_chars)) != NULL ||
443 !(opt & OPT_NO_EMPTY)) 448 !(opt & OPT_NO_EMPTY))
444 { 449 {
450 size_t n_chars = 0;
445 opt |= OPT_NO_EMPTY; 451 opt |= OPT_NO_EMPTY;
446 n = 0; 452 n = 0;
447 n_chars = 0;
448#if ENABLE_FEATURE_XARGS_SUPPORT_TERMOPT 453#if ENABLE_FEATURE_XARGS_SUPPORT_TERMOPT
449 for (cur = list; cur;) { 454 for (cur = list; cur;) {
450 n_chars += cur->length; 455 n_chars += cur->length;