diff options
Diffstat (limited to 'findutils')
-rw-r--r-- | findutils/find.c | 34 | ||||
-rw-r--r-- | findutils/grep.c | 33 | ||||
-rw-r--r-- | findutils/xargs.c | 153 |
3 files changed, 148 insertions, 72 deletions
diff --git a/findutils/find.c b/findutils/find.c index 5d5e24bfb..6d34f4d68 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -402,36 +402,6 @@ struct globals { | |||
402 | G.recurse_flags = ACTION_RECURSE; \ | 402 | G.recurse_flags = ACTION_RECURSE; \ |
403 | } while (0) | 403 | } while (0) |
404 | 404 | ||
405 | #if ENABLE_FEATURE_FIND_EXEC | ||
406 | static unsigned count_subst(const char *str) | ||
407 | { | ||
408 | unsigned count = 0; | ||
409 | while ((str = strstr(str, "{}")) != NULL) { | ||
410 | count++; | ||
411 | str++; | ||
412 | } | ||
413 | return count; | ||
414 | } | ||
415 | |||
416 | |||
417 | static char* subst(const char *src, unsigned count, const char* filename) | ||
418 | { | ||
419 | char *buf, *dst, *end; | ||
420 | size_t flen = strlen(filename); | ||
421 | /* we replace each '{}' with filename: growth by strlen-2 */ | ||
422 | buf = dst = xmalloc(strlen(src) + count*(flen-2) + 1); | ||
423 | while ((end = strstr(src, "{}"))) { | ||
424 | memcpy(dst, src, end - src); | ||
425 | dst += end - src; | ||
426 | src = end + 2; | ||
427 | memcpy(dst, filename, flen); | ||
428 | dst += flen; | ||
429 | } | ||
430 | strcpy(dst, src); | ||
431 | return buf; | ||
432 | } | ||
433 | #endif | ||
434 | |||
435 | /* Return values of ACTFs ('action functions') are a bit mask: | 405 | /* Return values of ACTFs ('action functions') are a bit mask: |
436 | * bit 1=1: prune (use SKIP constant for setting it) | 406 | * bit 1=1: prune (use SKIP constant for setting it) |
437 | * bit 0=1: matched successfully (TRUE) | 407 | * bit 0=1: matched successfully (TRUE) |
@@ -615,7 +585,7 @@ ACTF(exec) | |||
615 | char *argv[ap->exec_argc + 1]; | 585 | char *argv[ap->exec_argc + 1]; |
616 | #endif | 586 | #endif |
617 | for (i = 0; i < ap->exec_argc; i++) | 587 | for (i = 0; i < ap->exec_argc; i++) |
618 | argv[i] = subst(ap->exec_argv[i], ap->subst_count[i], fileName); | 588 | argv[i] = xmalloc_substitute_string(ap->exec_argv[i], ap->subst_count[i], "{}", fileName); |
619 | argv[i] = NULL; /* terminate the list */ | 589 | argv[i] = NULL; /* terminate the list */ |
620 | 590 | ||
621 | rc = spawn_and_wait(argv); | 591 | rc = spawn_and_wait(argv); |
@@ -1093,7 +1063,7 @@ static action*** parse_params(char **argv) | |||
1093 | ap->subst_count = xmalloc(ap->exec_argc * sizeof(int)); | 1063 | ap->subst_count = xmalloc(ap->exec_argc * sizeof(int)); |
1094 | i = ap->exec_argc; | 1064 | i = ap->exec_argc; |
1095 | while (i--) | 1065 | while (i--) |
1096 | ap->subst_count[i] = count_subst(ap->exec_argv[i]); | 1066 | ap->subst_count[i] = count_strstr(ap->exec_argv[i], "{}"); |
1097 | } | 1067 | } |
1098 | #endif | 1068 | #endif |
1099 | #if ENABLE_FEATURE_FIND_PAREN | 1069 | #if ENABLE_FEATURE_FIND_PAREN |
diff --git a/findutils/grep.c b/findutils/grep.c index f5f95cb95..615cacac4 100644 --- a/findutils/grep.c +++ b/findutils/grep.c | |||
@@ -383,6 +383,8 @@ static int grep_file(FILE *file) | |||
383 | } else { | 383 | } else { |
384 | #if ENABLE_EXTRA_COMPAT | 384 | #if ENABLE_EXTRA_COMPAT |
385 | unsigned start_pos; | 385 | unsigned start_pos; |
386 | #else | ||
387 | int match_flg; | ||
386 | #endif | 388 | #endif |
387 | char *match_at; | 389 | char *match_at; |
388 | 390 | ||
@@ -400,6 +402,7 @@ static int grep_file(FILE *file) | |||
400 | #if !ENABLE_EXTRA_COMPAT | 402 | #if !ENABLE_EXTRA_COMPAT |
401 | gl->matched_range.rm_so = 0; | 403 | gl->matched_range.rm_so = 0; |
402 | gl->matched_range.rm_eo = 0; | 404 | gl->matched_range.rm_eo = 0; |
405 | match_flg = 0; | ||
403 | #else | 406 | #else |
404 | start_pos = 0; | 407 | start_pos = 0; |
405 | #endif | 408 | #endif |
@@ -408,7 +411,7 @@ static int grep_file(FILE *file) | |||
408 | //bb_error_msg("'%s' start_pos:%d line_len:%d", match_at, start_pos, line_len); | 411 | //bb_error_msg("'%s' start_pos:%d line_len:%d", match_at, start_pos, line_len); |
409 | if ( | 412 | if ( |
410 | #if !ENABLE_EXTRA_COMPAT | 413 | #if !ENABLE_EXTRA_COMPAT |
411 | regexec(&gl->compiled_regex, match_at, 1, &gl->matched_range, 0) == 0 | 414 | regexec(&gl->compiled_regex, match_at, 1, &gl->matched_range, match_flg) == 0 |
412 | #else | 415 | #else |
413 | re_search(&gl->compiled_regex, match_at, line_len, | 416 | re_search(&gl->compiled_regex, match_at, line_len, |
414 | start_pos, /*range:*/ line_len, | 417 | start_pos, /*range:*/ line_len, |
@@ -423,13 +426,15 @@ static int grep_file(FILE *file) | |||
423 | found = 1; | 426 | found = 1; |
424 | } else { | 427 | } else { |
425 | char c = ' '; | 428 | char c = ' '; |
426 | if (gl->matched_range.rm_so) | 429 | if (match_at > line || gl->matched_range.rm_so != 0) { |
427 | c = match_at[gl->matched_range.rm_so - 1]; | 430 | c = match_at[gl->matched_range.rm_so - 1]; |
431 | } | ||
428 | if (!isalnum(c) && c != '_') { | 432 | if (!isalnum(c) && c != '_') { |
429 | c = match_at[gl->matched_range.rm_eo]; | 433 | c = match_at[gl->matched_range.rm_eo]; |
430 | if (!c || (!isalnum(c) && c != '_')) { | 434 | } |
431 | found = 1; | 435 | if (!isalnum(c) && c != '_') { |
432 | } else { | 436 | found = 1; |
437 | } else { | ||
433 | /* | 438 | /* |
434 | * Why check gl->matched_range.rm_eo? | 439 | * Why check gl->matched_range.rm_eo? |
435 | * Zero-length match makes -w skip the line: | 440 | * Zero-length match makes -w skip the line: |
@@ -438,17 +443,17 @@ static int grep_file(FILE *file) | |||
438 | * Without such check, we can loop forever. | 443 | * Without such check, we can loop forever. |
439 | */ | 444 | */ |
440 | #if !ENABLE_EXTRA_COMPAT | 445 | #if !ENABLE_EXTRA_COMPAT |
441 | if (gl->matched_range.rm_eo != 0) { | 446 | if (gl->matched_range.rm_eo != 0) { |
442 | match_at += gl->matched_range.rm_eo; | 447 | match_at += gl->matched_range.rm_eo; |
443 | goto opt_w_again; | 448 | match_flg |= REG_NOTBOL; |
444 | } | 449 | goto opt_w_again; |
450 | } | ||
445 | #else | 451 | #else |
446 | if (gl->matched_range.rm_eo > start_pos) { | 452 | if (gl->matched_range.rm_eo > start_pos) { |
447 | start_pos = gl->matched_range.rm_eo; | 453 | start_pos = gl->matched_range.rm_eo; |
448 | goto opt_w_again; | 454 | goto opt_w_again; |
449 | } | ||
450 | #endif | ||
451 | } | 455 | } |
456 | #endif | ||
452 | } | 457 | } |
453 | } | 458 | } |
454 | } | 459 | } |
diff --git a/findutils/xargs.c b/findutils/xargs.c index 0d1bb43fc..0ba5b566d 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -53,6 +53,13 @@ | |||
53 | //config: Support -0: input items are terminated by a NUL character | 53 | //config: Support -0: input items are terminated by a NUL character |
54 | //config: instead of whitespace, and the quotes and backslash | 54 | //config: instead of whitespace, and the quotes and backslash |
55 | //config: are not special. | 55 | //config: are not special. |
56 | //config: | ||
57 | //config:config FEATURE_XARGS_SUPPORT_REPL_STR | ||
58 | //config: bool "Enable -I STR: string to replace" | ||
59 | //config: default y | ||
60 | //config: depends on XARGS | ||
61 | //config: help | ||
62 | //config: Support -I STR and -i[STR] options. | ||
56 | 63 | ||
57 | //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) | 64 | //applet:IF_XARGS(APPLET_NOEXEC(xargs, xargs, BB_DIR_USR_BIN, BB_SUID_DROP, xargs)) |
58 | 65 | ||
@@ -85,19 +92,22 @@ | |||
85 | 92 | ||
86 | struct globals { | 93 | struct globals { |
87 | char **args; | 94 | char **args; |
95 | #if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR | ||
96 | char **argv; | ||
97 | const char *repl_str; | ||
98 | char eol_ch; | ||
99 | #endif | ||
88 | const char *eof_str; | 100 | const char *eof_str; |
89 | int idx; | 101 | int idx; |
90 | } FIX_ALIASING; | 102 | } FIX_ALIASING; |
91 | #define G (*(struct globals*)&bb_common_bufsiz1) | 103 | #define G (*(struct globals*)&bb_common_bufsiz1) |
92 | #define INIT_G() do { \ | 104 | #define INIT_G() do { \ |
93 | G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ | 105 | G.eof_str = NULL; /* need to clear by hand because we are NOEXEC applet */ \ |
106 | IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.repl_str = "{}";) \ | ||
107 | IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\n';) \ | ||
94 | } while (0) | 108 | } while (0) |
95 | 109 | ||
96 | 110 | ||
97 | /* | ||
98 | * This function has special algorithm. | ||
99 | * Don't use fork and include to main! | ||
100 | */ | ||
101 | static int xargs_exec(void) | 111 | static int xargs_exec(void) |
102 | { | 112 | { |
103 | int status; | 113 | int status; |
@@ -301,7 +311,7 @@ static char* FAST_FUNC process0_stdin(int n_max_chars, int n_max_arg, char *buf) | |||
301 | c = '\0'; | 311 | c = '\0'; |
302 | } | 312 | } |
303 | *p++ = c; | 313 | *p++ = c; |
304 | if (c == '\0') { /* word's delimiter or EOF detected */ | 314 | if (c == '\0') { /* NUL or EOF detected */ |
305 | /* A full word is loaded */ | 315 | /* A full word is loaded */ |
306 | store_param(s); | 316 | store_param(s); |
307 | dbg_msg("args[]:'%s'", s); | 317 | dbg_msg("args[]:'%s'", s); |
@@ -323,10 +333,71 @@ static char* FAST_FUNC process0_stdin(int n_max_chars, int n_max_arg, char *buf) | |||
323 | } | 333 | } |
324 | #endif /* FEATURE_XARGS_SUPPORT_ZERO_TERM */ | 334 | #endif /* FEATURE_XARGS_SUPPORT_ZERO_TERM */ |
325 | 335 | ||
336 | #if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR | ||
337 | /* | ||
338 | * Used if -I<repl> was specified. | ||
339 | * In this mode, words aren't appended to PROG ARGS. | ||
340 | * Instead, entire input line is read, then <repl> string | ||
341 | * in every PROG and ARG is replaced with the line: | ||
342 | * echo -e "ho ho\nhi" | xargs -I_ cmd __ _ | ||
343 | * results in "cmd 'ho hoho ho' 'ho ho'"; "cmd 'hihi' 'hi'". | ||
344 | * -n MAX_ARGS seems to be ignored. | ||
345 | * Tested with GNU findutils 4.5.10. | ||
346 | */ | ||
347 | //FIXME: n_max_chars is not handled the same way as in GNU findutils. | ||
348 | //FIXME: quoting is not implemented. | ||
349 | static char* FAST_FUNC process_stdin_with_replace(int n_max_chars, int n_max_arg UNUSED_PARAM, char *buf) | ||
350 | { | ||
351 | int i; | ||
352 | char *end, *p; | ||
353 | |||
354 | /* Free strings from last invocation, if any */ | ||
355 | for (i = 0; G.args && G.args[i]; i++) | ||
356 | if (G.args[i] != G.argv[i]) | ||
357 | free(G.args[i]); | ||
358 | |||
359 | end = buf + n_max_chars; | ||
360 | p = buf; | ||
361 | |||
362 | while (1) { | ||
363 | int c = getchar(); | ||
364 | if (c == EOF || c == G.eol_ch) { | ||
365 | if (p == buf) | ||
366 | goto ret; /* empty line */ | ||
367 | c = '\0'; | ||
368 | } | ||
369 | *p++ = c; | ||
370 | if (c == '\0') { /* EOL or EOF detected */ | ||
371 | i = 0; | ||
372 | while (G.argv[i]) { | ||
373 | char *arg = G.argv[i]; | ||
374 | int count = count_strstr(arg, G.repl_str); | ||
375 | if (count != 0) | ||
376 | arg = xmalloc_substitute_string(arg, count, G.repl_str, buf); | ||
377 | store_param(arg); | ||
378 | dbg_msg("args[]:'%s'", arg); | ||
379 | i++; | ||
380 | } | ||
381 | p = buf; | ||
382 | goto ret; | ||
383 | } | ||
384 | if (p == end) { | ||
385 | goto ret; | ||
386 | } | ||
387 | } | ||
388 | ret: | ||
389 | *p = '\0'; | ||
390 | /* store_param(NULL) - caller will do it */ | ||
391 | dbg_msg("return:'%s'", buf); | ||
392 | return buf; | ||
393 | } | ||
394 | #endif | ||
395 | |||
326 | #if ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION | 396 | #if ENABLE_FEATURE_XARGS_SUPPORT_CONFIRMATION |
327 | /* Prompt the user for a response, and | 397 | /* Prompt the user for a response, and |
328 | if the user responds affirmatively, return true; | 398 | * if user responds affirmatively, return true; |
329 | otherwise, return false. Uses "/dev/tty", not stdin. */ | 399 | * otherwise, return false. Uses "/dev/tty", not stdin. |
400 | */ | ||
330 | static int xargs_ask_confirmation(void) | 401 | static int xargs_ask_confirmation(void) |
331 | { | 402 | { |
332 | FILE *tty_stream; | 403 | FILE *tty_stream; |
@@ -360,6 +431,9 @@ static int xargs_ask_confirmation(void) | |||
360 | //usage: "\n -e[STR] STR stops input processing" | 431 | //usage: "\n -e[STR] STR stops input processing" |
361 | //usage: "\n -n N Pass no more than N args to PROG" | 432 | //usage: "\n -n N Pass no more than N args to PROG" |
362 | //usage: "\n -s N Pass command line of no more than N bytes" | 433 | //usage: "\n -s N Pass command line of no more than N bytes" |
434 | //usage: IF_FEATURE_XARGS_SUPPORT_REPL_STR( | ||
435 | //usage: "\n -I STR Replace STR within PROG ARGS with input line" | ||
436 | //usage: ) | ||
363 | //usage: IF_FEATURE_XARGS_SUPPORT_TERMOPT( | 437 | //usage: IF_FEATURE_XARGS_SUPPORT_TERMOPT( |
364 | //usage: "\n -x Exit if size is exceeded" | 438 | //usage: "\n -x Exit if size is exceeded" |
365 | //usage: ) | 439 | //usage: ) |
@@ -378,6 +452,8 @@ enum { | |||
378 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) | 452 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION(OPTBIT_INTERACTIVE,) |
379 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) | 453 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( OPTBIT_TERMINATE ,) |
380 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) | 454 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( OPTBIT_ZEROTERM ,) |
455 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR ,) | ||
456 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( OPTBIT_REPLSTR1 ,) | ||
381 | 457 | ||
382 | OPT_VERBOSE = 1 << OPTBIT_VERBOSE , | 458 | OPT_VERBOSE = 1 << OPTBIT_VERBOSE , |
383 | OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , | 459 | OPT_NO_EMPTY = 1 << OPTBIT_NO_EMPTY , |
@@ -388,11 +464,14 @@ enum { | |||
388 | OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, | 464 | OPT_INTERACTIVE = IF_FEATURE_XARGS_SUPPORT_CONFIRMATION((1 << OPTBIT_INTERACTIVE)) + 0, |
389 | OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, | 465 | OPT_TERMINATE = IF_FEATURE_XARGS_SUPPORT_TERMOPT( (1 << OPTBIT_TERMINATE )) + 0, |
390 | OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, | 466 | OPT_ZEROTERM = IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( (1 << OPTBIT_ZEROTERM )) + 0, |
467 | OPT_REPLSTR = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR )) + 0, | ||
468 | OPT_REPLSTR1 = IF_FEATURE_XARGS_SUPPORT_REPL_STR( (1 << OPTBIT_REPLSTR1 )) + 0, | ||
391 | }; | 469 | }; |
392 | #define OPTION_STR "+trn:s:e::E:" \ | 470 | #define OPTION_STR "+trn:s:e::E:" \ |
393 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ | 471 | IF_FEATURE_XARGS_SUPPORT_CONFIRMATION("p") \ |
394 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ | 472 | IF_FEATURE_XARGS_SUPPORT_TERMOPT( "x") \ |
395 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") | 473 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM( "0") \ |
474 | IF_FEATURE_XARGS_SUPPORT_REPL_STR( "I:i::") | ||
396 | 475 | ||
397 | int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 476 | int xargs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
398 | int xargs_main(int argc, char **argv) | 477 | int xargs_main(int argc, char **argv) |
@@ -405,7 +484,8 @@ int xargs_main(int argc, char **argv) | |||
405 | unsigned opt; | 484 | unsigned opt; |
406 | int n_max_chars; | 485 | int n_max_chars; |
407 | int n_max_arg; | 486 | int n_max_arg; |
408 | #if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM | 487 | #if ENABLE_FEATURE_XARGS_SUPPORT_ZERO_TERM \ |
488 | || ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR | ||
409 | char* FAST_FUNC (*read_args)(int, int, char*) = process_stdin; | 489 | char* FAST_FUNC (*read_args)(int, int, char*) = process_stdin; |
410 | #else | 490 | #else |
411 | #define read_args process_stdin | 491 | #define read_args process_stdin |
@@ -419,7 +499,10 @@ int xargs_main(int argc, char **argv) | |||
419 | "no-run-if-empty\0" No_argument "r" | 499 | "no-run-if-empty\0" No_argument "r" |
420 | ; | 500 | ; |
421 | #endif | 501 | #endif |
422 | opt = getopt32(argv, OPTION_STR, &max_args, &max_chars, &G.eof_str, &G.eof_str); | 502 | opt = getopt32(argv, OPTION_STR, |
503 | &max_args, &max_chars, &G.eof_str, &G.eof_str | ||
504 | IF_FEATURE_XARGS_SUPPORT_REPL_STR(, &G.repl_str, &G.repl_str) | ||
505 | ); | ||
423 | 506 | ||
424 | /* -E ""? You may wonder why not just omit -E? | 507 | /* -E ""? You may wonder why not just omit -E? |
425 | * This is used for portability: | 508 | * This is used for portability: |
@@ -427,8 +510,10 @@ int xargs_main(int argc, char **argv) | |||
427 | if ((opt & OPT_EOF_STRING1) && G.eof_str[0] == '\0') | 510 | if ((opt & OPT_EOF_STRING1) && G.eof_str[0] == '\0') |
428 | G.eof_str = NULL; | 511 | G.eof_str = NULL; |
429 | 512 | ||
430 | if (opt & OPT_ZEROTERM) | 513 | if (opt & OPT_ZEROTERM) { |
431 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin); | 514 | IF_FEATURE_XARGS_SUPPORT_ZERO_TERM(read_args = process0_stdin;) |
515 | IF_FEATURE_XARGS_SUPPORT_REPL_STR(G.eol_ch = '\0';) | ||
516 | } | ||
432 | 517 | ||
433 | argv += optind; | 518 | argv += optind; |
434 | argc -= optind; | 519 | argc -= optind; |
@@ -486,20 +571,36 @@ int xargs_main(int argc, char **argv) | |||
486 | /* if (n_max_arg > n_max_chars) n_max_arg = n_max_chars */ | 571 | /* if (n_max_arg > n_max_chars) n_max_arg = n_max_chars */ |
487 | } | 572 | } |
488 | 573 | ||
489 | /* Allocate pointers for execvp */ | 574 | #if ENABLE_FEATURE_XARGS_SUPPORT_REPL_STR |
490 | /* We can statically allocate (argc + n_max_arg + 1) elements | 575 | if (opt & (OPT_REPLSTR | OPT_REPLSTR1)) { |
491 | * and do not bother with resizing args[], but on 64-bit machines | 576 | /* |
492 | * this results in args[] vector which is ~8 times bigger | 577 | * -I<str>: |
493 | * than n_max_chars! That is, with n_max_chars == 20k, | 578 | * Unmodified args are kept in G.argv[i], |
494 | * args[] will take 160k (!), which will most likely be | 579 | * G.args[i] receives malloced G.argv[i] with <str> replaced |
495 | * almost entirely unused. | 580 | * with input line. Setting this up: |
496 | */ | 581 | */ |
497 | /* See store_param() for matching 256-step growth logic */ | 582 | G.args = NULL; |
498 | G.args = xmalloc(sizeof(G.args[0]) * ((argc + 0xff) & ~0xff)); | 583 | G.argv = argv; |
499 | 584 | argc = 0; | |
500 | /* Store the command to be executed, part 1 */ | 585 | read_args = process_stdin_with_replace; |
501 | for (i = 0; argv[i]; i++) | 586 | } else |
502 | G.args[i] = argv[i]; | 587 | #endif |
588 | { | ||
589 | /* Allocate pointers for execvp. | ||
590 | * We can statically allocate (argc + n_max_arg + 1) elements | ||
591 | * and do not bother with resizing args[], but on 64-bit machines | ||
592 | * this results in args[] vector which is ~8 times bigger | ||
593 | * than n_max_chars! That is, with n_max_chars == 20k, | ||
594 | * args[] will take 160k (!), which will most likely be | ||
595 | * almost entirely unused. | ||
596 | * | ||
597 | * See store_param() for matching 256-step growth logic | ||
598 | */ | ||
599 | G.args = xmalloc(sizeof(G.args[0]) * ((argc + 0xff) & ~0xff)); | ||
600 | /* Store the command to be executed, part 1 */ | ||
601 | for (i = 0; argv[i]; i++) | ||
602 | G.args[i] = argv[i]; | ||
603 | } | ||
503 | 604 | ||
504 | while (1) { | 605 | while (1) { |
505 | char *rem; | 606 | char *rem; |