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 | |
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>
-rw-r--r-- | findutils/find.c | 4 | ||||
-rw-r--r-- | findutils/xargs.c | 26 | ||||
-rw-r--r-- | include/libbb.h | 8 | ||||
-rw-r--r-- | libbb/Kbuild.src | 1 | ||||
-rw-r--r-- | libbb/sysconf.c | 16 |
5 files changed, 38 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 | } |
diff --git a/include/libbb.h b/include/libbb.h index a1a0dc18c..fa69a7fe6 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -731,6 +731,14 @@ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST | |||
731 | /* Never returns NULL */ | 731 | /* Never returns NULL */ |
732 | extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | 732 | extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; |
733 | 733 | ||
734 | #if defined ARG_MAX | ||
735 | # define bb_arg_max() ((unsigned)ARG_MAX) | ||
736 | #elif defined _SC_ARG_MAX | ||
737 | unsigned bb_arg_max(void) FAST_FUNC; | ||
738 | #else | ||
739 | # define bb_arg_max() ((unsigned)(32 * 1024)) | ||
740 | #endif | ||
741 | |||
734 | #define SEAMLESS_COMPRESSION (0 \ | 742 | #define SEAMLESS_COMPRESSION (0 \ |
735 | || ENABLE_FEATURE_SEAMLESS_XZ \ | 743 | || ENABLE_FEATURE_SEAMLESS_XZ \ |
736 | || ENABLE_FEATURE_SEAMLESS_LZMA \ | 744 | || ENABLE_FEATURE_SEAMLESS_LZMA \ |
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 6578d1171..62680bd52 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -92,6 +92,7 @@ lib-y += skip_whitespace.o | |||
92 | lib-y += speed_table.o | 92 | lib-y += speed_table.o |
93 | lib-y += str_tolower.o | 93 | lib-y += str_tolower.o |
94 | lib-y += strrstr.o | 94 | lib-y += strrstr.o |
95 | lib-y += sysconf.o | ||
95 | lib-y += time.o | 96 | lib-y += time.o |
96 | lib-y += trim.o | 97 | lib-y += trim.o |
97 | lib-y += u_signal_names.o | 98 | lib-y += u_signal_names.o |
diff --git a/libbb/sysconf.c b/libbb/sysconf.c new file mode 100644 index 000000000..c5fa5e001 --- /dev/null +++ b/libbb/sysconf.c | |||
@@ -0,0 +1,16 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Various system configuration helpers. | ||
4 | * | ||
5 | * Copyright (C) 2014 Bartosz Golaszewski <bartekgola@gmail.com> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | #include "libbb.h" | ||
10 | |||
11 | #if defined _SC_ARG_MAX | ||
12 | unsigned FAST_FUNC bb_arg_max(void) | ||
13 | { | ||
14 | return sysconf(_SC_ARG_MAX); | ||
15 | } | ||
16 | #endif | ||