find: use sysconf(_SC_ARG_MAX) to determine the command-line size limit
No binary (build failed)
—
(log yok)
| @@ -419,6 +419,7 @@ struct globals { | |
| smallint need_print; | |
| smallint xdev_on; | |
| recurse_flags_t recurse_flags; | |
| + | IF_FEATURE_FIND_EXEC_PLUS(unsigned max_argv_len;) |
| } FIX_ALIASING; | |
| #define G (*(struct globals*)&bb_common_bufsiz1) | |
| #define INIT_G() do { \ | |
| @@ -428,6 +429,7 @@ struct globals { | |
| /* we have to zero it out because of NOEXEC */ \ | |
| memset(&G, 0, sizeof(G)); \ | |
| IF_FEATURE_FIND_MAXDEPTH(G.minmaxdepth[1] = INT_MAX;) \ | |
| + | IF_FEATURE_FIND_EXEC_PLUS(G.max_argv_len = bb_arg_max() - 2048;) \ |
| G.need_print = 1; \ | |
| G.recurse_flags = ACTION_RECURSE; \ | |
| } while (0) | |
| @@ -677,7 +679,7 @@ ACTF(exec) | |
| ap->file_len += strlen(fileName) + sizeof(char*) + 1; | |
| /* If we have lots of files already, exec the command */ | |
| rc = 1; | |
| - | if (ap->file_len >= 32*1024) |
| + | if (ap->file_len >= G.max_argv_len) |
| rc = do_exec(ap, NULL); | |
| return rc; | |
| } | |
| @@ -523,12 +523,7 @@ int xargs_main(int argc, char **argv) | |
| argc++; | |
| } | |
| - | /* -s NUM default. fileutils-4.4.2 uses 128k, but I heasitate |
| - | * to use such a big value - first need to change code to use |
| - | * growable buffer instead of fixed one. |
| - | */ |
| - | n_max_chars = 32 * 1024; |
| - | /* Make smaller if system does not allow our default value. |
| + | /* |
| * The Open Group Base Specifications Issue 6: | |
| * "The xargs utility shall limit the command line length such that | |
| * when the command line is invoked, the combined argument | |
| @@ -536,16 +531,15 @@ int xargs_main(int argc, char **argv) | |
| * in the System Interfaces volume of IEEE Std 1003.1-2001) | |
| * shall not exceed {ARG_MAX}-2048 bytes". | |
| */ | |
| - | { |
| - | long arg_max = 0; |
| - | #if defined _SC_ARG_MAX |
| - | arg_max = sysconf(_SC_ARG_MAX) - 2048; |
| - | #elif defined ARG_MAX |
| - | arg_max = ARG_MAX - 2048; |
| - | #endif |
| - | if (arg_max > 0 && n_max_chars > arg_max) |
| - | n_max_chars = arg_max; |
| - | } |
| + | n_max_chars = bb_arg_max(); |
| + | if (n_max_chars > 32 * 1024) |
| + | n_max_chars = 32 * 1024; |
| + | /* |
| + | * POSIX suggests substracting 2048 bytes from sysconf(_SC_ARG_MAX) |
| + | * so that the process may safely modify its environment. |
| + | */ |
| + | n_max_chars -= 2048; |
| + | |
| if (opt & OPT_UPTO_SIZE) { | |
| n_max_chars = xatou_range(max_chars, 1, INT_MAX); | |
| } | |
| @@ -731,6 +731,14 @@ extern void *xmalloc_open_read_close(const char *filename, size_t *maxsz_p) FAST | |
| /* Never returns NULL */ | |
| extern void *xmalloc_xopen_read_close(const char *filename, size_t *maxsz_p) FAST_FUNC RETURNS_MALLOC; | |
| + | #if defined ARG_MAX |
| + | # define bb_arg_max() ((unsigned)ARG_MAX) |
| + | #elif defined _SC_ARG_MAX |
| + | unsigned bb_arg_max(void) FAST_FUNC; |
| + | #else |
| + | # define bb_arg_max() ((unsigned)(32 * 1024)) |
| + | #endif |
| + | |
| #define SEAMLESS_COMPRESSION (0 \ | |
| || ENABLE_FEATURE_SEAMLESS_XZ \ | |
| || ENABLE_FEATURE_SEAMLESS_LZMA \ | |
| @@ -92,6 +92,7 @@ lib-y += skip_whitespace.o | |
| lib-y += speed_table.o | |
| lib-y += str_tolower.o | |
| lib-y += strrstr.o | |
| + | lib-y += sysconf.o |
| lib-y += time.o | |
| lib-y += trim.o | |
| lib-y += u_signal_names.o | |
| @@ -0,0 +1,16 @@ | |
| + | /* vi: set sw=4 ts=4: */ |
| + | /* |
| + | * Various system configuration helpers. |
| + | * |
| + | * Copyright (C) 2014 Bartosz Golaszewski <[email protected]> |
| + | * |
| + | * Licensed under GPLv2 or later, see file LICENSE in this source tree. |
| + | */ |
| + | #include "libbb.h" |
| + | |
| + | #if defined _SC_ARG_MAX |
| + | unsigned FAST_FUNC bb_arg_max(void) |
| + | { |
| + | return sysconf(_SC_ARG_MAX); |
| + | } |
| + | #endif |