diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-22 13:54:40 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2014-06-22 13:54:40 +0200 |
commit | f92f1d0181853b989f9377debb56902e3e21c9a8 (patch) | |
tree | 14c0bb888dea4b92e0f8dcaec2aa9c2a40eb3966 /findutils | |
parent | 6be3a5242ce4855734a4cdd5770b6ea7adaf2b3d (diff) | |
download | busybox-w32-f92f1d0181853b989f9377debb56902e3e21c9a8.tar.gz busybox-w32-f92f1d0181853b989f9377debb56902e3e21c9a8.tar.bz2 busybox-w32-f92f1d0181853b989f9377debb56902e3e21c9a8.zip |
find: use sysconf(_SC_ARG_MAX) to determine the command-line size limit
The find utility uses a hardcoded value of 32 * 1024 as the limit of
the command-line length when calling 'find -exec ... {} +'. This results
in over 4 times more execve() calls than in coreutils' find.
This patch uses the limit defined in system headers.
Based on the patch by Bartosz Golaszewski <bartekgola@gmail.com>.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'findutils')
-rw-r--r-- | findutils/find.c | 4 | ||||
-rw-r--r-- | findutils/xargs.c | 26 |
2 files changed, 13 insertions, 17 deletions
diff --git a/findutils/find.c b/findutils/find.c index 493f72e61..56a7ed3ab 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -419,6 +419,7 @@ struct globals { | |||
419 | smallint need_print; | 419 | smallint need_print; |
420 | smallint xdev_on; | 420 | smallint xdev_on; |
421 | recurse_flags_t recurse_flags; | 421 | recurse_flags_t recurse_flags; |
422 | IF_FEATURE_FIND_EXEC_PLUS(unsigned max_argv_len;) | ||
422 | } FIX_ALIASING; | 423 | } FIX_ALIASING; |
423 | #define G (*(struct globals*)&bb_common_bufsiz1) | 424 | #define G (*(struct globals*)&bb_common_bufsiz1) |
424 | #define INIT_G() do { \ | 425 | #define INIT_G() do { \ |
@@ -428,6 +429,7 @@ struct globals { | |||
428 | /* we have to zero it out because of NOEXEC */ \ | 429 | /* we have to zero it out because of NOEXEC */ \ |
429 | memset(&G, 0, sizeof(G)); \ | 430 | memset(&G, 0, sizeof(G)); \ |
430 | IF_FEATURE_FIND_MAXDEPTH(G.minmaxdepth[1] = INT_MAX;) \ | 431 | IF_FEATURE_FIND_MAXDEPTH(G.minmaxdepth[1] = INT_MAX;) \ |
432 | IF_FEATURE_FIND_EXEC_PLUS(G.max_argv_len = bb_arg_max() - 2048;) \ | ||
431 | G.need_print = 1; \ | 433 | G.need_print = 1; \ |
432 | G.recurse_flags = ACTION_RECURSE; \ | 434 | G.recurse_flags = ACTION_RECURSE; \ |
433 | } while (0) | 435 | } while (0) |
@@ -677,7 +679,7 @@ ACTF(exec) | |||
677 | ap->file_len += strlen(fileName) + sizeof(char*) + 1; | 679 | ap->file_len += strlen(fileName) + sizeof(char*) + 1; |
678 | /* If we have lots of files already, exec the command */ | 680 | /* If we have lots of files already, exec the command */ |
679 | rc = 1; | 681 | rc = 1; |
680 | if (ap->file_len >= 32*1024) | 682 | if (ap->file_len >= G.max_argv_len) |
681 | rc = do_exec(ap, NULL); | 683 | rc = do_exec(ap, NULL); |
682 | return rc; | 684 | return rc; |
683 | } | 685 | } |
diff --git a/findutils/xargs.c b/findutils/xargs.c index 0ba5b566d..76c4747fe 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -523,12 +523,7 @@ int xargs_main(int argc, char **argv) | |||
523 | argc++; | 523 | argc++; |
524 | } | 524 | } |
525 | 525 | ||
526 | /* -s NUM default. fileutils-4.4.2 uses 128k, but I heasitate | 526 | /* |
527 | * to use such a big value - first need to change code to use | ||
528 | * growable buffer instead of fixed one. | ||
529 | */ | ||
530 | n_max_chars = 32 * 1024; | ||
531 | /* Make smaller if system does not allow our default value. | ||
532 | * The Open Group Base Specifications Issue 6: | 527 | * The Open Group Base Specifications Issue 6: |
533 | * "The xargs utility shall limit the command line length such that | 528 | * "The xargs utility shall limit the command line length such that |
534 | * when the command line is invoked, the combined argument | 529 | * when the command line is invoked, the combined argument |
@@ -536,16 +531,15 @@ int xargs_main(int argc, char **argv) | |||
536 | * in the System Interfaces volume of IEEE Std 1003.1-2001) | 531 | * in the System Interfaces volume of IEEE Std 1003.1-2001) |
537 | * shall not exceed {ARG_MAX}-2048 bytes". | 532 | * shall not exceed {ARG_MAX}-2048 bytes". |
538 | */ | 533 | */ |
539 | { | 534 | n_max_chars = bb_arg_max(); |
540 | long arg_max = 0; | 535 | if (n_max_chars > 32 * 1024) |
541 | #if defined _SC_ARG_MAX | 536 | n_max_chars = 32 * 1024; |
542 | arg_max = sysconf(_SC_ARG_MAX) - 2048; | 537 | /* |
543 | #elif defined ARG_MAX | 538 | * POSIX suggests substracting 2048 bytes from sysconf(_SC_ARG_MAX) |
544 | arg_max = ARG_MAX - 2048; | 539 | * so that the process may safely modify its environment. |
545 | #endif | 540 | */ |
546 | if (arg_max > 0 && n_max_chars > arg_max) | 541 | n_max_chars -= 2048; |
547 | n_max_chars = arg_max; | 542 | |
548 | } | ||
549 | if (opt & OPT_UPTO_SIZE) { | 543 | if (opt & OPT_UPTO_SIZE) { |
550 | n_max_chars = xatou_range(max_chars, 1, INT_MAX); | 544 | n_max_chars = xatou_range(max_chars, 1, INT_MAX); |
551 | } | 545 | } |