diff options
author | Ron Yorston <rmy@pobox.com> | 2023-04-09 11:24:09 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-04-09 11:24:09 +0100 |
commit | d9f2ea8628452f787e02dd0e496af612a2e94578 (patch) | |
tree | c12be657e31c2e832b41fbff9a77aa0f886d47f0 | |
parent | fa04f2dc766c76f2caa44a4b8429185dde6a66b0 (diff) | |
parent | a26711a2d1464167be4ebc990fe21a3809a2da34 (diff) | |
download | busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.tar.gz busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.tar.bz2 busybox-w32-d9f2ea8628452f787e02dd0e496af612a2e94578.zip |
Merge branch 'busybox' into merge
-rw-r--r-- | archival/cpio.c | 1 | ||||
-rw-r--r-- | archival/unzip.c | 22 | ||||
-rw-r--r-- | coreutils/printf.c | 2 | ||||
-rw-r--r-- | coreutils/sleep.c | 15 | ||||
-rw-r--r-- | findutils/find.c | 39 | ||||
-rw-r--r-- | include/libbb.h | 2 | ||||
-rw-r--r-- | init/bootchartd.c | 2 | ||||
-rw-r--r-- | libbb/hash_md5_sha.c | 28 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 10 | ||||
-rw-r--r-- | modutils/modprobe-small.c | 12 | ||||
-rw-r--r-- | modutils/modutils.c | 12 | ||||
-rw-r--r-- | networking/httpd.c | 76 | ||||
-rw-r--r-- | procps/kill.c | 2 | ||||
-rw-r--r-- | procps/top.c | 25 | ||||
-rw-r--r-- | scripts/basic/fixdep.c | 6 | ||||
-rw-r--r-- | shell/ash.c | 69 | ||||
-rw-r--r-- | shell/ash_test/ash-signals/usage.right | 12 | ||||
-rwxr-xr-x | shell/ash_test/ash-signals/usage.tests | 12 | ||||
-rw-r--r-- | shell/hush.c | 40 | ||||
-rwxr-xr-x | testsuite/find.tests | 6 |
20 files changed, 271 insertions, 122 deletions
diff --git a/archival/cpio.c b/archival/cpio.c index a642bbc35..388ba7c4f 100644 --- a/archival/cpio.c +++ b/archival/cpio.c | |||
@@ -508,7 +508,6 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) | |||
508 | goto dump; | 508 | goto dump; |
509 | } | 509 | } |
510 | /* parent */ | 510 | /* parent */ |
511 | USE_FOR_NOMMU(argv[-optind][0] &= 0x7f); /* undo fork_or_rexec() damage */ | ||
512 | xchdir(*argv++); | 511 | xchdir(*argv++); |
513 | close(pp.wr); | 512 | close(pp.wr); |
514 | xmove_fd(pp.rd, STDIN_FILENO); | 513 | xmove_fd(pp.rd, STDIN_FILENO); |
diff --git a/archival/unzip.c b/archival/unzip.c index ff4f6325c..7b945c250 100644 --- a/archival/unzip.c +++ b/archival/unzip.c | |||
@@ -56,7 +56,7 @@ | |||
56 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o | 56 | //kbuild:lib-$(CONFIG_UNZIP) += unzip.o |
57 | 57 | ||
58 | //usage:#define unzip_trivial_usage | 58 | //usage:#define unzip_trivial_usage |
59 | //usage: "[-lnojpq] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" | 59 | //usage: "[-lnojpqK] FILE[.zip] [FILE]... [-x FILE]... [-d DIR]" |
60 | //usage:#define unzip_full_usage "\n\n" | 60 | //usage:#define unzip_full_usage "\n\n" |
61 | //usage: "Extract FILEs from ZIP archive\n" | 61 | //usage: "Extract FILEs from ZIP archive\n" |
62 | //usage: "\n -l List contents (with -q for short form)" | 62 | //usage: "\n -l List contents (with -q for short form)" |
@@ -66,6 +66,7 @@ | |||
66 | //usage: "\n -p Write to stdout" | 66 | //usage: "\n -p Write to stdout" |
67 | //usage: "\n -t Test" | 67 | //usage: "\n -t Test" |
68 | //usage: "\n -q Quiet" | 68 | //usage: "\n -q Quiet" |
69 | //usage: "\n -K Do not clear SUID bit" | ||
69 | //usage: "\n -x FILE Exclude FILEs" | 70 | //usage: "\n -x FILE Exclude FILEs" |
70 | //usage: "\n -d DIR Extract into DIR" | 71 | //usage: "\n -d DIR Extract into DIR" |
71 | 72 | ||
@@ -497,6 +498,7 @@ int unzip_main(int argc, char **argv) | |||
497 | OPT_l = (1 << 0), | 498 | OPT_l = (1 << 0), |
498 | OPT_x = (1 << 1), | 499 | OPT_x = (1 << 1), |
499 | OPT_j = (1 << 2), | 500 | OPT_j = (1 << 2), |
501 | OPT_K = (1 << 3), | ||
500 | }; | 502 | }; |
501 | unsigned opts; | 503 | unsigned opts; |
502 | smallint quiet = 0; | 504 | smallint quiet = 0; |
@@ -560,9 +562,14 @@ int unzip_main(int argc, char **argv) | |||
560 | * 204372 1 file | 562 | * 204372 1 file |
561 | */ | 563 | */ |
562 | 564 | ||
565 | //TODO: accept and ignore these? | ||
566 | // -a convert to text files with 't' label, -aa: all files | ||
567 | // -b do not convert to text - bbox: we don't convert anything | ||
568 | // -D skip restoration of timestamps for extracted items - bbox: we don't restore these (yet?) | ||
569 | // -X restore user:group ownership | ||
563 | opts = 0; | 570 | opts = 0; |
564 | /* '-' makes getopt return 1 for non-options */ | 571 | /* '-' makes getopt return 1 for non-options */ |
565 | while ((i = getopt(argc, argv, "-d:lnotpqxjv")) != -1) { | 572 | while ((i = getopt(argc, argv, "-d:lnotpqxjvK")) != -1) { |
566 | switch (i) { | 573 | switch (i) { |
567 | case 'd': /* Extract to base directory */ | 574 | case 'd': /* Extract to base directory */ |
568 | base_dir = optarg; | 575 | base_dir = optarg; |
@@ -584,6 +591,7 @@ int unzip_main(int argc, char **argv) | |||
584 | xmove_fd(xopen("/dev/null", O_WRONLY), STDOUT_FILENO); | 591 | xmove_fd(xopen("/dev/null", O_WRONLY), STDOUT_FILENO); |
585 | /*fallthrough*/ | 592 | /*fallthrough*/ |
586 | 593 | ||
594 | // NB: -c extract files to stdout/screen (unlike -p, also prints .zip and file names to stdout) | ||
587 | case 'p': /* Extract files to stdout */ | 595 | case 'p': /* Extract files to stdout */ |
588 | dst_fd = STDOUT_FILENO; | 596 | dst_fd = STDOUT_FILENO; |
589 | /*fallthrough*/ | 597 | /*fallthrough*/ |
@@ -605,6 +613,10 @@ int unzip_main(int argc, char **argv) | |||
605 | opts |= OPT_j; | 613 | opts |= OPT_j; |
606 | break; | 614 | break; |
607 | 615 | ||
616 | case 'K': | ||
617 | opts |= OPT_K; | ||
618 | break; | ||
619 | |||
608 | case 1: | 620 | case 1: |
609 | if (!src_fn) { | 621 | if (!src_fn) { |
610 | /* The zip file */ | 622 | /* The zip file */ |
@@ -822,7 +834,10 @@ int unzip_main(int argc, char **argv) | |||
822 | # endif | 834 | # endif |
823 | if ((cdf.fmt.version_made_by >> 8) == 3) { | 835 | if ((cdf.fmt.version_made_by >> 8) == 3) { |
824 | /* This archive is created on Unix */ | 836 | /* This archive is created on Unix */ |
825 | dir_mode = file_mode = (cdf.fmt.external_attributes >> 16); | 837 | file_mode = (cdf.fmt.external_attributes >> 16); |
838 | if (!(opts & OPT_K)) | ||
839 | file_mode &= ~(mode_t)(S_ISUID | S_ISGID); | ||
840 | dir_mode = file_mode; | ||
826 | } | 841 | } |
827 | } | 842 | } |
828 | #endif | 843 | #endif |
@@ -847,6 +862,7 @@ int unzip_main(int argc, char **argv) | |||
847 | unzip_skip(zip.fmt.extra_len); | 862 | unzip_skip(zip.fmt.extra_len); |
848 | 863 | ||
849 | /* Guard against "/abspath", "/../" and similar attacks */ | 864 | /* Guard against "/abspath", "/../" and similar attacks */ |
865 | // NB: UnZip 6.00 has option -: to disable this | ||
850 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); | 866 | overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); |
851 | 867 | ||
852 | /* Filter zip entries */ | 868 | /* Filter zip entries */ |
diff --git a/coreutils/printf.c b/coreutils/printf.c index da129f909..411edd5b9 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c | |||
@@ -493,7 +493,7 @@ int printf_main(int argc UNUSED_PARAM, char **argv) | |||
493 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) | 493 | if (argv[1] && argv[1][0] == '-' && argv[1][1] == '-' && !argv[1][2]) |
494 | argv++; | 494 | argv++; |
495 | if (!argv[1]) { | 495 | if (!argv[1]) { |
496 | if (ENABLE_ASH_PRINTF | 496 | if ((ENABLE_ASH_PRINTF || ENABLE_HUSH_PRINTF) |
497 | && applet_name[0] != 'p' | 497 | && applet_name[0] != 'p' |
498 | ) { | 498 | ) { |
499 | bb_simple_error_msg("usage: printf FORMAT [ARGUMENT...]"); | 499 | bb_simple_error_msg("usage: printf FORMAT [ARGUMENT...]"); |
diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 442841210..667db558d 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c | |||
@@ -65,15 +65,28 @@ int sleep_main(int argc UNUSED_PARAM, char **argv) | |||
65 | { | 65 | { |
66 | duration_t duration; | 66 | duration_t duration; |
67 | 67 | ||
68 | /* Note: sleep_main may be directly called from ash as a builtin. | ||
69 | * This brings some complications: | ||
70 | * + we can't use xfunc here | ||
71 | * + we can't use bb_show_usage | ||
72 | * + applet_name can be the name of the shell | ||
73 | */ | ||
68 | ++argv; | 74 | ++argv; |
69 | if (!*argv) | 75 | if (!*argv) { |
76 | /* Without this, bare "sleep" in ash shows _ash_ --help */ | ||
77 | if (ENABLE_ASH_SLEEP && applet_name[0] != 's') { | ||
78 | bb_simple_error_msg("sleep: missing operand"); | ||
79 | return EXIT_FAILURE; | ||
80 | } | ||
70 | bb_show_usage(); | 81 | bb_show_usage(); |
82 | } | ||
71 | 83 | ||
72 | /* GNU sleep accepts "inf", "INF", "infinity" and "INFINITY" */ | 84 | /* GNU sleep accepts "inf", "INF", "infinity" and "INFINITY" */ |
73 | if (strncasecmp(argv[0], "inf", 3) == 0) | 85 | if (strncasecmp(argv[0], "inf", 3) == 0) |
74 | for (;;) | 86 | for (;;) |
75 | sleep(INT_MAX); | 87 | sleep(INT_MAX); |
76 | 88 | ||
89 | //FIXME: in ash, "sleep 123qwerty" as a builtin aborts the shell | ||
77 | #if ENABLE_FEATURE_FANCY_SLEEP | 90 | #if ENABLE_FEATURE_FANCY_SLEEP |
78 | duration = 0; | 91 | duration = 0; |
79 | do { | 92 | do { |
diff --git a/findutils/find.c b/findutils/find.c index 2a607d180..a78dd9875 100644 --- a/findutils/find.c +++ b/findutils/find.c | |||
@@ -180,6 +180,13 @@ | |||
180 | //config: Without this option, -exec + is a synonym for -exec ; | 180 | //config: Without this option, -exec + is a synonym for -exec ; |
181 | //config: (IOW: it works correctly, but without expected speedup) | 181 | //config: (IOW: it works correctly, but without expected speedup) |
182 | //config: | 182 | //config: |
183 | //config:config FEATURE_FIND_EXEC_OK | ||
184 | //config: bool "Enable -ok: execute confirmed commands" | ||
185 | //config: default y | ||
186 | //config: depends on FEATURE_FIND_EXEC | ||
187 | //config: help | ||
188 | //config: Support the 'find -ok' option which prompts before executing. | ||
189 | //config: | ||
183 | //config:config FEATURE_FIND_USER | 190 | //config:config FEATURE_FIND_USER |
184 | //config: bool "Enable -user: username/uid matching" | 191 | //config: bool "Enable -user: username/uid matching" |
185 | //config: default y | 192 | //config: default y |
@@ -395,6 +402,9 @@ | |||
395 | //usage: IF_FEATURE_FIND_EXEC_PLUS( | 402 | //usage: IF_FEATURE_FIND_EXEC_PLUS( |
396 | //usage: "\n -exec CMD ARG + Run CMD with {} replaced by list of file names" | 403 | //usage: "\n -exec CMD ARG + Run CMD with {} replaced by list of file names" |
397 | //usage: ) | 404 | //usage: ) |
405 | //usage: IF_FEATURE_FIND_EXEC_OK( | ||
406 | //usage: "\n -ok CMD ARG ; Prompt and run CMD with {} replaced" | ||
407 | //usage: ) | ||
398 | //usage: IF_FEATURE_FIND_DELETE( | 408 | //usage: IF_FEATURE_FIND_DELETE( |
399 | //usage: "\n -delete Delete current file/directory. Turns on -depth option" | 409 | //usage: "\n -delete Delete current file/directory. Turns on -depth option" |
400 | //usage: ) | 410 | //usage: ) |
@@ -467,6 +477,9 @@ IF_FEATURE_FIND_EXEC( ACTS(exec, | |||
467 | char **exec_argv; /* -exec ARGS */ | 477 | char **exec_argv; /* -exec ARGS */ |
468 | unsigned *subst_count; | 478 | unsigned *subst_count; |
469 | int exec_argc; /* count of ARGS */ | 479 | int exec_argc; /* count of ARGS */ |
480 | IF_FEATURE_FIND_EXEC_OK( | ||
481 | int ok; /* -ok */ | ||
482 | ) | ||
470 | IF_FEATURE_FIND_EXEC_PLUS( | 483 | IF_FEATURE_FIND_EXEC_PLUS( |
471 | /* | 484 | /* |
472 | * filelist is NULL if "exec ;" | 485 | * filelist is NULL if "exec ;" |
@@ -802,10 +815,24 @@ static int do_exec(action_exec *ap, const char *fileName) | |||
802 | } | 815 | } |
803 | # endif | 816 | # endif |
804 | 817 | ||
818 | # if ENABLE_FEATURE_FIND_EXEC_OK | ||
819 | if (ap->ok) { | ||
820 | for (i = 0; argv[i]; i++) | ||
821 | fprintf(stderr, "%s ", argv[i]); | ||
822 | fprintf(stderr, "?"); | ||
823 | if (!bb_ask_y_confirmation()) { | ||
824 | rc = 1; /* "false" */ | ||
825 | goto not_ok; | ||
826 | } | ||
827 | } | ||
828 | # endif | ||
805 | rc = spawn_and_wait(argv); | 829 | rc = spawn_and_wait(argv); |
806 | if (rc < 0) | 830 | if (rc < 0) |
807 | bb_simple_perror_msg(argv[0]); | 831 | bb_simple_perror_msg(argv[0]); |
808 | 832 | ||
833 | # if ENABLE_FEATURE_FIND_EXEC_OK | ||
834 | not_ok: | ||
835 | # endif | ||
809 | i = 0; | 836 | i = 0; |
810 | while (argv[i]) | 837 | while (argv[i]) |
811 | free(argv[i++]); | 838 | free(argv[i++]); |
@@ -1120,6 +1147,7 @@ static action*** parse_params(char **argv) | |||
1120 | IF_FEATURE_FIND_DELETE( PARM_delete ,) | 1147 | IF_FEATURE_FIND_DELETE( PARM_delete ,) |
1121 | IF_FEATURE_FIND_EMPTY( PARM_empty ,) | 1148 | IF_FEATURE_FIND_EMPTY( PARM_empty ,) |
1122 | IF_FEATURE_FIND_EXEC( PARM_exec ,) | 1149 | IF_FEATURE_FIND_EXEC( PARM_exec ,) |
1150 | IF_FEATURE_FIND_EXEC_OK(PARM_ok ,) | ||
1123 | IF_FEATURE_FIND_EXECUTABLE(PARM_executable,) | 1151 | IF_FEATURE_FIND_EXECUTABLE(PARM_executable,) |
1124 | IF_FEATURE_FIND_PAREN( PARM_char_brace,) | 1152 | IF_FEATURE_FIND_PAREN( PARM_char_brace,) |
1125 | /* All options/actions starting from here require argument */ | 1153 | /* All options/actions starting from here require argument */ |
@@ -1171,6 +1199,7 @@ static action*** parse_params(char **argv) | |||
1171 | IF_FEATURE_FIND_DELETE( "-delete\0" ) | 1199 | IF_FEATURE_FIND_DELETE( "-delete\0" ) |
1172 | IF_FEATURE_FIND_EMPTY( "-empty\0" ) | 1200 | IF_FEATURE_FIND_EMPTY( "-empty\0" ) |
1173 | IF_FEATURE_FIND_EXEC( "-exec\0" ) | 1201 | IF_FEATURE_FIND_EXEC( "-exec\0" ) |
1202 | IF_FEATURE_FIND_EXEC_OK("-ok\0" ) | ||
1174 | IF_FEATURE_FIND_EXECUTABLE("-executable\0") | 1203 | IF_FEATURE_FIND_EXECUTABLE("-executable\0") |
1175 | IF_FEATURE_FIND_PAREN( "(\0" ) | 1204 | IF_FEATURE_FIND_PAREN( "(\0" ) |
1176 | /* All options/actions starting from here require argument */ | 1205 | /* All options/actions starting from here require argument */ |
@@ -1351,23 +1380,27 @@ static action*** parse_params(char **argv) | |||
1351 | } | 1380 | } |
1352 | #endif | 1381 | #endif |
1353 | #if ENABLE_FEATURE_FIND_EXEC | 1382 | #if ENABLE_FEATURE_FIND_EXEC |
1354 | else if (parm == PARM_exec) { | 1383 | else if (parm == PARM_exec IF_FEATURE_FIND_EXEC_OK(|| parm == PARM_ok)) { |
1355 | int i; | 1384 | int i; |
1356 | action_exec *ap; | 1385 | action_exec *ap; |
1357 | IF_FEATURE_FIND_EXEC_PLUS(int all_subst = 0;) | 1386 | IF_FEATURE_FIND_EXEC_PLUS(int all_subst = 0;) |
1358 | dbg("%d", __LINE__); | 1387 | dbg("%d", __LINE__); |
1359 | G.need_print = 0; | 1388 | G.need_print = 0; |
1360 | ap = ALLOC_ACTION(exec); | 1389 | ap = ALLOC_ACTION(exec); |
1390 | IF_FEATURE_FIND_EXEC_OK(ap->ok = (parm == PARM_ok);) | ||
1361 | ap->exec_argv = ++argv; /* first arg after -exec */ | 1391 | ap->exec_argv = ++argv; /* first arg after -exec */ |
1362 | /*ap->exec_argc = 0; - ALLOC_ACTION did it */ | 1392 | /*ap->exec_argc = 0; - ALLOC_ACTION did it */ |
1363 | while (1) { | 1393 | while (1) { |
1364 | if (!*argv) /* did not see ';' or '+' until end */ | 1394 | if (!*argv) /* did not see ';' or '+' until end */ |
1365 | bb_error_msg_and_die(bb_msg_requires_arg, "-exec"); | 1395 | bb_error_msg_and_die(bb_msg_requires_arg, arg); |
1366 | // find -exec echo Foo ">{}<" ";" | 1396 | // find -exec echo Foo ">{}<" ";" |
1367 | // executes "echo Foo >FILENAME<", | 1397 | // executes "echo Foo >FILENAME<", |
1368 | // find -exec echo Foo ">{}<" "+" | 1398 | // find -exec echo Foo ">{}<" "+" |
1369 | // executes "echo Foo FILENAME1 FILENAME2 FILENAME3...". | 1399 | // executes "echo Foo FILENAME1 FILENAME2 FILENAME3...". |
1370 | if ((argv[0][0] == ';' || argv[0][0] == '+') | 1400 | if ((argv[0][0] == ';' |
1401 | || (argv[0][0] == '+' IF_FEATURE_FIND_EXEC_OK(&& parm != PARM_ok)) | ||
1402 | /* -ok CMD + syntax is not accepted, only with ';' */ | ||
1403 | ) | ||
1371 | && argv[0][1] == '\0' | 1404 | && argv[0][1] == '\0' |
1372 | ) { | 1405 | ) { |
1373 | # if ENABLE_FEATURE_FIND_EXEC_PLUS | 1406 | # if ENABLE_FEATURE_FIND_EXEC_PLUS |
diff --git a/include/libbb.h b/include/libbb.h index 2841d7fbf..7683b3f63 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1377,7 +1377,7 @@ enum { | |||
1377 | # define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus) | 1377 | # define bb_daemonize(flags) bb_daemonize_or_rexec(flags, bogus) |
1378 | #else | 1378 | #else |
1379 | extern bool re_execed; | 1379 | extern bool re_execed; |
1380 | /* Note: re_exec() and fork_or_rexec() do argv[0][0] |= 0x80 on NOMMU! | 1380 | /* Note: re_exec() sets argv[0][0] |= 0x80 on NOMMU! |
1381 | * _Parent_ needs to undo it if it doesn't want to have argv[0] mangled. | 1381 | * _Parent_ needs to undo it if it doesn't want to have argv[0] mangled. |
1382 | */ | 1382 | */ |
1383 | void re_exec(char **argv) NORETURN FAST_FUNC; | 1383 | void re_exec(char **argv) NORETURN FAST_FUNC; |
diff --git a/init/bootchartd.c b/init/bootchartd.c index ae1ee9d9a..0929890a3 100644 --- a/init/bootchartd.c +++ b/init/bootchartd.c | |||
@@ -435,8 +435,6 @@ int bootchartd_main(int argc UNUSED_PARAM, char **argv) | |||
435 | 435 | ||
436 | /* parent */ | 436 | /* parent */ |
437 | 437 | ||
438 | USE_FOR_NOMMU(argv[0][0] &= 0x7f); /* undo fork_or_rexec() damage */ | ||
439 | |||
440 | if (DO_SIGNAL_SYNC) { | 438 | if (DO_SIGNAL_SYNC) { |
441 | /* Wait for logger child to set handlers, then unpause it. | 439 | /* Wait for logger child to set handlers, then unpause it. |
442 | * Otherwise with short-lived PROG (e.g. "bootchartd start true") | 440 | * Otherwise with short-lived PROG (e.g. "bootchartd start true") |
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c index 880ffab01..88baf51dc 100644 --- a/libbb/hash_md5_sha.c +++ b/libbb/hash_md5_sha.c | |||
@@ -23,6 +23,14 @@ static void cpuid(unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) | |||
23 | ); | 23 | ); |
24 | } | 24 | } |
25 | static smallint shaNI; | 25 | static smallint shaNI; |
26 | static int get_shaNI(void) | ||
27 | { | ||
28 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; | ||
29 | cpuid(&eax, &ebx, &ecx, &edx); | ||
30 | ebx = ((ebx >> 28) & 2) - 1; /* bit 29 -> 1 or -1 */ | ||
31 | shaNI = (int)ebx; | ||
32 | return (int)ebx; | ||
33 | } | ||
26 | void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); | 34 | void FAST_FUNC sha1_process_block64_shaNI(sha1_ctx_t *ctx); |
27 | void FAST_FUNC sha256_process_block64_shaNI(sha256_ctx_t *ctx); | 35 | void FAST_FUNC sha256_process_block64_shaNI(sha256_ctx_t *ctx); |
28 | # if defined(__i386__) | 36 | # if defined(__i386__) |
@@ -1175,12 +1183,10 @@ void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) | |||
1175 | #if ENABLE_SHA1_HWACCEL | 1183 | #if ENABLE_SHA1_HWACCEL |
1176 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | 1184 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
1177 | { | 1185 | { |
1178 | if (!shaNI) { | 1186 | int ni = shaNI; |
1179 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; | 1187 | if (!ni) |
1180 | cpuid(&eax, &ebx, &ecx, &edx); | 1188 | ni = get_shaNI(); |
1181 | shaNI = ((ebx >> 29) << 1) - 1; | 1189 | if (ni > 0) |
1182 | } | ||
1183 | if (shaNI > 0) | ||
1184 | ctx->process_block = sha1_process_block64_shaNI; | 1190 | ctx->process_block = sha1_process_block64_shaNI; |
1185 | } | 1191 | } |
1186 | # endif | 1192 | # endif |
@@ -1229,12 +1235,10 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx) | |||
1229 | #if ENABLE_SHA256_HWACCEL | 1235 | #if ENABLE_SHA256_HWACCEL |
1230 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) | 1236 | # if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) |
1231 | { | 1237 | { |
1232 | if (!shaNI) { | 1238 | int ni = shaNI; |
1233 | unsigned eax = 7, ebx = ebx, ecx = 0, edx = edx; | 1239 | if (!ni) |
1234 | cpuid(&eax, &ebx, &ecx, &edx); | 1240 | ni = get_shaNI(); |
1235 | shaNI = ((ebx >> 29) << 1) - 1; | 1241 | if (ni > 0) |
1236 | } | ||
1237 | if (shaNI > 0) | ||
1238 | ctx->process_block = sha256_process_block64_shaNI; | 1242 | ctx->process_block = sha256_process_block64_shaNI; |
1239 | } | 1243 | } |
1240 | # endif | 1244 | # endif |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 62beb6a5d..3845c0892 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -273,10 +273,12 @@ pid_t FAST_FUNC fork_or_rexec(char **argv) | |||
273 | /* fflush_all(); ? - so far all callers had no buffered output to flush */ | 273 | /* fflush_all(); ? - so far all callers had no buffered output to flush */ |
274 | 274 | ||
275 | pid = xvfork(); | 275 | pid = xvfork(); |
276 | if (pid) /* parent */ | 276 | if (pid == 0) /* child - re-exec ourself */ |
277 | return pid; | 277 | re_exec(argv); /* NORETURN */ |
278 | /* child - re-exec ourself */ | 278 | |
279 | re_exec(argv); | 279 | /* parent */ |
280 | argv[0][0] &= 0x7f; /* undo re_rexec() damage */ | ||
281 | return pid; | ||
280 | } | 282 | } |
281 | #endif | 283 | #endif |
282 | 284 | ||
diff --git a/modutils/modprobe-small.c b/modutils/modprobe-small.c index b61651621..77e42e3fb 100644 --- a/modutils/modprobe-small.c +++ b/modutils/modprobe-small.c | |||
@@ -33,6 +33,9 @@ | |||
33 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | 33 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) |
34 | #ifdef __NR_finit_module | 34 | #ifdef __NR_finit_module |
35 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | 35 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
36 | # ifndef MODULE_INIT_COMPRESSED_FILE | ||
37 | # define MODULE_INIT_COMPRESSED_FILE 4 | ||
38 | # endif | ||
36 | #endif | 39 | #endif |
37 | /* linux/include/linux/module.h has limit of 64 chars on module names */ | 40 | /* linux/include/linux/module.h has limit of 64 chars on module names */ |
38 | #undef MODULE_NAME_LEN | 41 | #undef MODULE_NAME_LEN |
@@ -272,7 +275,14 @@ static int load_module(const char *fname, const char *options) | |||
272 | { | 275 | { |
273 | int fd = open(fname, O_RDONLY | O_CLOEXEC); | 276 | int fd = open(fname, O_RDONLY | O_CLOEXEC); |
274 | if (fd >= 0) { | 277 | if (fd >= 0) { |
275 | r = finit_module(fd, options, 0) != 0; | 278 | int flags = is_suffixed_with(fname, ".ko") ? 0 : MODULE_INIT_COMPRESSED_FILE; |
279 | for (;;) { | ||
280 | r = finit_module(fd, options, flags); | ||
281 | if (r == 0 || flags == 0) | ||
282 | break; | ||
283 | /* Loading non-.ko named uncompressed module? Not likely, but let's try it */ | ||
284 | flags = 0; | ||
285 | } | ||
276 | close(fd); | 286 | close(fd); |
277 | } | 287 | } |
278 | } | 288 | } |
diff --git a/modutils/modutils.c b/modutils/modutils.c index f7ad5e805..cbff20961 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c | |||
@@ -12,6 +12,9 @@ | |||
12 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) | 12 | #define init_module(mod, len, opts) syscall(__NR_init_module, mod, len, opts) |
13 | #if defined(__NR_finit_module) | 13 | #if defined(__NR_finit_module) |
14 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) | 14 | # define finit_module(fd, uargs, flags) syscall(__NR_finit_module, fd, uargs, flags) |
15 | # ifndef MODULE_INIT_COMPRESSED_FILE | ||
16 | # define MODULE_INIT_COMPRESSED_FILE 4 | ||
17 | # endif | ||
15 | #endif | 18 | #endif |
16 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) | 19 | #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) |
17 | 20 | ||
@@ -217,7 +220,14 @@ int FAST_FUNC bb_init_module(const char *filename, const char *options) | |||
217 | { | 220 | { |
218 | int fd = open(filename, O_RDONLY | O_CLOEXEC); | 221 | int fd = open(filename, O_RDONLY | O_CLOEXEC); |
219 | if (fd >= 0) { | 222 | if (fd >= 0) { |
220 | rc = finit_module(fd, options, 0) != 0; | 223 | int flags = is_suffixed_with(filename, ".ko") ? 0 : MODULE_INIT_COMPRESSED_FILE; |
224 | for (;;) { | ||
225 | rc = finit_module(fd, options, flags); | ||
226 | if (rc == 0 || flags == 0) | ||
227 | break; | ||
228 | /* Loading non-.ko named uncompressed module? Not likely, but let's try it */ | ||
229 | flags = 0; | ||
230 | } | ||
221 | close(fd); | 231 | close(fd); |
222 | if (rc == 0) | 232 | if (rc == 0) |
223 | return rc; | 233 | return rc; |
diff --git a/networking/httpd.c b/networking/httpd.c index b32498ddb..302d1611d 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -2475,50 +2475,52 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr) | |||
2475 | send_headers_and_exit(HTTP_FORBIDDEN); | 2475 | send_headers_and_exit(HTTP_FORBIDDEN); |
2476 | } | 2476 | } |
2477 | cgi_type = CGI_NORMAL; | 2477 | cgi_type = CGI_NORMAL; |
2478 | } | 2478 | } /* why "else": do not check "cgi-bin/SCRIPT/something" for cases below: */ |
2479 | else | ||
2479 | #endif | 2480 | #endif |
2480 | 2481 | { | |
2481 | if (urlp[-1] == '/') { | 2482 | if (urlp[-1] == '/') { |
2482 | /* When index_page string is appended to <dir>/ URL, it overwrites | 2483 | /* When index_page string is appended to <dir>/ URL, it overwrites |
2483 | * the query string. If we fall back to call /cgi-bin/index.cgi, | 2484 | * the query string. If we fall back to call /cgi-bin/index.cgi, |
2484 | * query string would be lost and not available to the CGI. | 2485 | * query string would be lost and not available to the CGI. |
2485 | * Work around it by making a deep copy. | 2486 | * Work around it by making a deep copy. |
2486 | */ | 2487 | */ |
2487 | if (ENABLE_FEATURE_HTTPD_CGI) | 2488 | if (ENABLE_FEATURE_HTTPD_CGI) |
2488 | g_query = xstrdup(g_query); /* ok for NULL too */ | 2489 | g_query = xstrdup(g_query); /* ok for NULL too */ |
2489 | strcpy(urlp, index_page); | 2490 | strcpy(urlp, index_page); |
2490 | } | 2491 | } |
2491 | if (stat(tptr, &sb) == 0) { | 2492 | if (stat(tptr, &sb) == 0) { |
2492 | /* If URL is a directory with no slash, set up | 2493 | /* If URL is a directory with no slash, set up |
2493 | * "HTTP/1.1 302 Found" "Location: /dir/" reply */ | 2494 | * "HTTP/1.1 302 Found" "Location: /dir/" reply */ |
2494 | if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { | 2495 | if (urlp[-1] != '/' && S_ISDIR(sb.st_mode)) { |
2495 | found_moved_temporarily = urlcopy; | 2496 | found_moved_temporarily = urlcopy; |
2496 | } else { | 2497 | } else { |
2497 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR | 2498 | #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR |
2498 | char *suffix = strrchr(tptr, '.'); | 2499 | char *suffix = strrchr(tptr, '.'); |
2499 | if (suffix) { | 2500 | if (suffix) { |
2500 | Htaccess *cur; | 2501 | Htaccess *cur; |
2501 | for (cur = script_i; cur; cur = cur->next) { | 2502 | for (cur = script_i; cur; cur = cur->next) { |
2502 | if (strcmp(cur->before_colon + 1, suffix) == 0) { | 2503 | if (strcmp(cur->before_colon + 1, suffix) == 0) { |
2503 | cgi_type = CGI_INTERPRETER; | 2504 | cgi_type = CGI_INTERPRETER; |
2504 | break; | 2505 | break; |
2506 | } | ||
2505 | } | 2507 | } |
2506 | } | 2508 | } |
2507 | } | ||
2508 | #endif | 2509 | #endif |
2509 | file_size = sb.st_size; | 2510 | file_size = sb.st_size; |
2510 | last_mod = sb.st_mtime; | 2511 | last_mod = sb.st_mtime; |
2512 | } | ||
2511 | } | 2513 | } |
2512 | } | ||
2513 | #if ENABLE_FEATURE_HTTPD_CGI | 2514 | #if ENABLE_FEATURE_HTTPD_CGI |
2514 | else if (urlp[-1] == '/') { | 2515 | else if (urlp[-1] == '/') { |
2515 | /* It's a dir URL and there is no index.html */ | 2516 | /* It's a dir URL and there is no index.html */ |
2516 | /* Is there cgi-bin/index.cgi? */ | 2517 | /* Is there cgi-bin/index.cgi? */ |
2517 | if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) | 2518 | if (access("/cgi-bin/index.cgi"+1, X_OK) != 0) |
2518 | send_headers_and_exit(HTTP_NOT_FOUND); /* no */ | 2519 | send_headers_and_exit(HTTP_NOT_FOUND); /* no */ |
2519 | cgi_type = CGI_INDEX; | 2520 | cgi_type = CGI_INDEX; |
2520 | } | 2521 | } |
2521 | #endif | 2522 | #endif |
2523 | } | ||
2522 | 2524 | ||
2523 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_CGI | 2525 | #if ENABLE_FEATURE_HTTPD_BASIC_AUTH || ENABLE_FEATURE_HTTPD_CGI |
2524 | /* check_user_passwd() would be confused by added .../index.html, truncate it */ | 2526 | /* check_user_passwd() would be confused by added .../index.html, truncate it */ |
@@ -2787,8 +2789,8 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv) | |||
2787 | /* Run a copy of ourself in inetd mode */ | 2789 | /* Run a copy of ourself in inetd mode */ |
2788 | re_exec(argv_copy); | 2790 | re_exec(argv_copy); |
2789 | } | 2791 | } |
2790 | argv_copy[0][0] &= 0x7f; | ||
2791 | /* parent, or vfork failed */ | 2792 | /* parent, or vfork failed */ |
2793 | argv_copy[0][0] &= 0x7f; /* undo re_rexec() damage */ | ||
2792 | close(n); | 2794 | close(n); |
2793 | } /* while (1) */ | 2795 | } /* while (1) */ |
2794 | /* never reached */ | 2796 | /* never reached */ |
diff --git a/procps/kill.c b/procps/kill.c index 8c2bc2b6f..583d61aaf 100644 --- a/procps/kill.c +++ b/procps/kill.c | |||
@@ -85,8 +85,8 @@ | |||
85 | * This brings some complications: | 85 | * This brings some complications: |
86 | * | 86 | * |
87 | * + we can't use xfunc here | 87 | * + we can't use xfunc here |
88 | * + we can't use applet_name | ||
89 | * + we can't use bb_show_usage | 88 | * + we can't use bb_show_usage |
89 | * + applet_name can be the name of the shell | ||
90 | * (doesn't apply for killall[5], still should be careful b/c NOFORK) | 90 | * (doesn't apply for killall[5], still should be careful b/c NOFORK) |
91 | * | 91 | * |
92 | * kill %n gets translated into kill ' -<process group>' by shell (note space!) | 92 | * kill %n gets translated into kill ' -<process group>' by shell (note space!) |
diff --git a/procps/top.c b/procps/top.c index ff775422c..6d25d9633 100644 --- a/procps/top.c +++ b/procps/top.c | |||
@@ -619,17 +619,15 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
619 | unsigned busy_jifs; | 619 | unsigned busy_jifs; |
620 | #endif | 620 | #endif |
621 | 621 | ||
622 | /* what info of the processes is shown */ | ||
623 | printf(OPT_BATCH_MODE ? "%.*s" : ESC"[7m" "%.*s" ESC"[m", scr_width, | ||
624 | " PID PPID USER STAT VSZ %VSZ" | ||
625 | IF_FEATURE_TOP_SMP_PROCESS(" CPU") | ||
626 | IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU") | ||
627 | " COMMAND"); | ||
628 | lines_rem--; | ||
629 | |||
630 | #if ENABLE_FEATURE_TOP_DECIMALS | 622 | #if ENABLE_FEATURE_TOP_DECIMALS |
631 | # define UPSCALE 1000 | 623 | # define UPSCALE 1000 |
632 | # define CALC_STAT(name, val) div_t name = div((val), 10) | 624 | typedef struct { unsigned quot, rem; } bb_div_t; |
625 | /* Used to have "div_t name = div((val), 10)" here | ||
626 | * (IOW: intended to use libc-compatible way to divide and use | ||
627 | * both result and remainder, but musl does not inline div()...) | ||
628 | * Oh well. Modern compilers detect "N/d, N%d" idiom by themselves: | ||
629 | */ | ||
630 | # define CALC_STAT(name, val) bb_div_t name = { (val) / 10, (val) % 10 } | ||
633 | # define SHOW_STAT(name) name.quot, '0'+name.rem | 631 | # define SHOW_STAT(name) name.quot, '0'+name.rem |
634 | # define FMT "%3u.%c" | 632 | # define FMT "%3u.%c" |
635 | #else | 633 | #else |
@@ -638,6 +636,15 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) | |||
638 | # define SHOW_STAT(name) name | 636 | # define SHOW_STAT(name) name |
639 | # define FMT "%4u%%" | 637 | # define FMT "%4u%%" |
640 | #endif | 638 | #endif |
639 | |||
640 | /* what info of the processes is shown */ | ||
641 | printf(OPT_BATCH_MODE ? "%.*s" : ESC"[7m" "%.*s" ESC"[m", scr_width, | ||
642 | " PID PPID USER STAT VSZ %VSZ" | ||
643 | IF_FEATURE_TOP_SMP_PROCESS(" CPU") | ||
644 | IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU") | ||
645 | " COMMAND"); | ||
646 | lines_rem--; | ||
647 | |||
641 | /* | 648 | /* |
642 | * %VSZ = s->vsz/MemTotal | 649 | * %VSZ = s->vsz/MemTotal |
643 | */ | 650 | */ |
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index 64fd92f06..1ae25c919 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c | |||
@@ -394,7 +394,11 @@ void parse_dep_file(void *map, size_t len) | |||
394 | do p--; while (p != m && !isalnum((unsigned char)*p)); | 394 | do p--; while (p != m && !isalnum((unsigned char)*p)); |
395 | p++; | 395 | p++; |
396 | } | 396 | } |
397 | if (p == m) break; | 397 | if (p < m) { |
398 | /* we've consumed the last filename of this list | ||
399 | already. */ | ||
400 | break; | ||
401 | } | ||
398 | memcpy(s, m, p-m); s[p-m] = 0; | 402 | memcpy(s, m, p-m); s[p-m] = 0; |
399 | if (strrcmp(s, "include/autoconf.h") && | 403 | if (strrcmp(s, "include/autoconf.h") && |
400 | strrcmp(s, "arch/um/include/uml-config.h") && | 404 | strrcmp(s, "arch/um/include/uml-config.h") && |
diff --git a/shell/ash.c b/shell/ash.c index 51bf95377..0443f1a02 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -2049,16 +2049,18 @@ _STPUTC(int c, char *p) | |||
2049 | /* | 2049 | /* |
2050 | * prefix -- see if pfx is a prefix of string. | 2050 | * prefix -- see if pfx is a prefix of string. |
2051 | */ | 2051 | */ |
2052 | static char * | 2052 | static ALWAYS_INLINE char * |
2053 | prefix(const char *string, const char *pfx) | 2053 | prefix(const char *string, const char *pfx) |
2054 | { | 2054 | { |
2055 | return is_prefixed_with(string, pfx); | ||
2056 | #if 0 /* dash implementation: */ | ||
2055 | while (*pfx) { | 2057 | while (*pfx) { |
2056 | if (*pfx++ != *string++) | 2058 | if (*pfx++ != *string++) |
2057 | return NULL; | 2059 | return NULL; |
2058 | } | 2060 | } |
2059 | return (char *) string; | 2061 | return (char *) string; |
2062 | #endif | ||
2060 | } | 2063 | } |
2061 | |||
2062 | /* | 2064 | /* |
2063 | * Check for a valid number. This should be elsewhere. | 2065 | * Check for a valid number. This should be elsewhere. |
2064 | */ | 2066 | */ |
@@ -2296,7 +2298,7 @@ struct localvar { | |||
2296 | #define VNOFUNC 0x40 /* don't call the callback function */ | 2298 | #define VNOFUNC 0x40 /* don't call the callback function */ |
2297 | #define VNOSET 0x80 /* do not set variable - just readonly test */ | 2299 | #define VNOSET 0x80 /* do not set variable - just readonly test */ |
2298 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ | 2300 | #define VNOSAVE 0x100 /* when text is on the heap before setvareq */ |
2299 | #if ENABLE_ASH_RANDOM_SUPPORT | 2301 | #if ENABLE_ASH_RANDOM_SUPPORT || BASH_EPOCH_VARS |
2300 | # define VDYNAMIC 0x200 /* dynamic variable */ | 2302 | # define VDYNAMIC 0x200 /* dynamic variable */ |
2301 | #else | 2303 | #else |
2302 | # define VDYNAMIC 0 | 2304 | # define VDYNAMIC 0 |
@@ -2319,10 +2321,7 @@ change_lc_ctype(const char *value) | |||
2319 | } | 2321 | } |
2320 | #endif | 2322 | #endif |
2321 | #if ENABLE_ASH_MAIL | 2323 | #if ENABLE_ASH_MAIL |
2322 | static void chkmail(void); | ||
2323 | static void changemail(const char *var_value) FAST_FUNC; | 2324 | static void changemail(const char *var_value) FAST_FUNC; |
2324 | #else | ||
2325 | # define chkmail() ((void)0) | ||
2326 | #endif | 2325 | #endif |
2327 | static void changepath(const char *) FAST_FUNC; | 2326 | static void changepath(const char *) FAST_FUNC; |
2328 | #if ENABLE_ASH_RANDOM_SUPPORT | 2327 | #if ENABLE_ASH_RANDOM_SUPPORT |
@@ -3407,7 +3406,7 @@ cdcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
3407 | if (!*dest) | 3406 | if (!*dest) |
3408 | dest = "."; | 3407 | dest = "."; |
3409 | path = bltinlookup("CDPATH"); | 3408 | path = bltinlookup("CDPATH"); |
3410 | while (p = path, (len = padvance(&path, dest)) >= 0) { | 3409 | while (p = path, (len = padvance_magic(&path, dest, 0)) >= 0) { |
3411 | c = *p; | 3410 | c = *p; |
3412 | p = stalloc(len); | 3411 | p = stalloc(len); |
3413 | 3412 | ||
@@ -4454,9 +4453,6 @@ getjob(const char *name, int getctl) | |||
4454 | unsigned num; | 4453 | unsigned num; |
4455 | int c; | 4454 | int c; |
4456 | const char *p; | 4455 | const char *p; |
4457 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 | ||
4458 | char *(*match)(const char *, const char *); | ||
4459 | #endif | ||
4460 | 4456 | ||
4461 | jp = curjob; | 4457 | jp = curjob; |
4462 | p = name; | 4458 | p = name; |
@@ -4498,15 +4494,12 @@ getjob(const char *name, int getctl) | |||
4498 | } | 4494 | } |
4499 | 4495 | ||
4500 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 | 4496 | #if ENABLE_PLATFORM_POSIX || JOBS_WIN32 |
4501 | match = prefix; | ||
4502 | if (*p == '?') { | ||
4503 | match = strstr; | ||
4504 | p++; | ||
4505 | } | ||
4506 | |||
4507 | found = NULL; | 4497 | found = NULL; |
4508 | while (jp) { | 4498 | while (jp) { |
4509 | if (match(jp->ps[0].ps_cmd, p)) { | 4499 | if (*p == '?' |
4500 | ? strstr(jp->ps[0].ps_cmd, p + 1) | ||
4501 | : prefix(jp->ps[0].ps_cmd, p) | ||
4502 | ) { | ||
4510 | if (found) | 4503 | if (found) |
4511 | goto err; | 4504 | goto err; |
4512 | found = jp; | 4505 | found = jp; |
@@ -5802,8 +5795,7 @@ forkchild(struct job *jp, union node *n, int mode) | |||
5802 | 5795 | ||
5803 | closescript(); | 5796 | closescript(); |
5804 | 5797 | ||
5805 | if (mode == FORK_NOJOB /* is it `xxx` ? */ | 5798 | if (n && n->type == NCMD /* is it single cmd? */ |
5806 | && n && n->type == NCMD /* is it single cmd? */ | ||
5807 | /* && n->ncmd.args->type == NARG - always true? */ | 5799 | /* && n->ncmd.args->type == NARG - always true? */ |
5808 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 | 5800 | && n->ncmd.args && strcmp(n->ncmd.args->narg.text, "trap") == 0 |
5809 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ | 5801 | && n->ncmd.args->narg.next == NULL /* "trap" with no arguments */ |
@@ -5897,10 +5889,12 @@ forkchild(struct job *jp, union node *n, int mode) | |||
5897 | ) { | 5889 | ) { |
5898 | TRACE(("Job hack\n")); | 5890 | TRACE(("Job hack\n")); |
5899 | /* "jobs": we do not want to clear job list for it, | 5891 | /* "jobs": we do not want to clear job list for it, |
5900 | * instead we remove only _its_ own_ job from job list. | 5892 | * instead we remove only _its_ own_ job from job list |
5893 | * (if it has one). | ||
5901 | * This makes "jobs .... | cat" more useful. | 5894 | * This makes "jobs .... | cat" more useful. |
5902 | */ | 5895 | */ |
5903 | freejob(curjob); | 5896 | if (jp) |
5897 | freejob(curjob); | ||
5904 | return; | 5898 | return; |
5905 | } | 5899 | } |
5906 | #endif | 5900 | #endif |
@@ -7293,7 +7287,7 @@ evalbackcmd(union node *n, struct backcmd *result | |||
7293 | 7287 | ||
7294 | if (pipe(pip) < 0) | 7288 | if (pipe(pip) < 0) |
7295 | ash_msg_and_raise_perror("can't create pipe"); | 7289 | ash_msg_and_raise_perror("can't create pipe"); |
7296 | /* process substitution uses NULL job/node, like openhere() */ | 7290 | /* process substitution uses NULL job, like openhere() */ |
7297 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; | 7291 | jp = (ctl == CTLBACKQ) ? makejob(/*n,*/ 1) : NULL; |
7298 | #if ENABLE_PLATFORM_MINGW32 | 7292 | #if ENABLE_PLATFORM_MINGW32 |
7299 | memset(&fs, 0, sizeof(fs)); | 7293 | memset(&fs, 0, sizeof(fs)); |
@@ -7302,9 +7296,9 @@ evalbackcmd(union node *n, struct backcmd *result | |||
7302 | fs.fd[0] = pip[0]; | 7296 | fs.fd[0] = pip[0]; |
7303 | fs.fd[1] = pip[1]; | 7297 | fs.fd[1] = pip[1]; |
7304 | fs.fd[2] = ctl; | 7298 | fs.fd[2] = ctl; |
7305 | spawn_forkshell(&fs, jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB); | 7299 | spawn_forkshell(&fs, jp, n, FORK_NOJOB); |
7306 | #else | 7300 | #else |
7307 | if (forkshell(jp, (ctl == CTLBACKQ) ? n : NULL, FORK_NOJOB) == 0) { | 7301 | if (forkshell(jp, n, FORK_NOJOB) == 0) { |
7308 | /* child */ | 7302 | /* child */ |
7309 | FORCE_INT_ON; | 7303 | FORCE_INT_ON; |
7310 | close(pip[ip]); | 7304 | close(pip[ip]); |
@@ -9507,8 +9501,6 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9507 | const struct alias *ap; | 9501 | const struct alias *ap; |
9508 | #endif | 9502 | #endif |
9509 | 9503 | ||
9510 | path = path ? path : pathval(); | ||
9511 | |||
9512 | if (describe_command_verbose) { | 9504 | if (describe_command_verbose) { |
9513 | out1str(command); | 9505 | out1str(command); |
9514 | } | 9506 | } |
@@ -9533,6 +9525,7 @@ describe_command(char *command, const char *path, int describe_command_verbose) | |||
9533 | } | 9525 | } |
9534 | #endif | 9526 | #endif |
9535 | /* Brute force */ | 9527 | /* Brute force */ |
9528 | path = path ? path : pathval(); | ||
9536 | find_command(command, &entry, DO_ABS, path); | 9529 | find_command(command, &entry, DO_ABS, path); |
9537 | 9530 | ||
9538 | switch (entry.cmdtype) { | 9531 | switch (entry.cmdtype) { |
@@ -12311,15 +12304,14 @@ setinputstring(char *string) | |||
12311 | #if ENABLE_ASH_MAIL | 12304 | #if ENABLE_ASH_MAIL |
12312 | 12305 | ||
12313 | /* Hash of mtimes of mailboxes */ | 12306 | /* Hash of mtimes of mailboxes */ |
12307 | /* Cleared to 0 if MAIL or MAILPATH is changed */ | ||
12314 | static unsigned mailtime_hash; | 12308 | static unsigned mailtime_hash; |
12315 | /* Set if MAIL or MAILPATH is changed. */ | ||
12316 | static smallint mail_var_path_changed; | ||
12317 | 12309 | ||
12318 | /* | 12310 | /* |
12319 | * Print appropriate message(s) if mail has arrived. | 12311 | * Print appropriate message(s) if mail has arrived. |
12320 | * If mail_var_path_changed is set, | 12312 | * If mailtime_hash is zero, |
12321 | * then the value of MAIL has mail_var_path_changed, | 12313 | * then the value of MAIL has changed, |
12322 | * so we just update the values. | 12314 | * so we just update the hash value. |
12323 | */ | 12315 | */ |
12324 | static void | 12316 | static void |
12325 | chkmail(void) | 12317 | chkmail(void) |
@@ -12338,10 +12330,9 @@ chkmail(void) | |||
12338 | int len; | 12330 | int len; |
12339 | 12331 | ||
12340 | len = padvance_magic(&mpath, nullstr, 2); | 12332 | len = padvance_magic(&mpath, nullstr, 2); |
12341 | if (!len) | 12333 | if (len < 0) |
12342 | break; | 12334 | break; |
12343 | p = stackblock(); | 12335 | p = stackblock(); |
12344 | break; | ||
12345 | if (*p == '\0') | 12336 | if (*p == '\0') |
12346 | continue; | 12337 | continue; |
12347 | for (q = p; *q; q++) | 12338 | for (q = p; *q; q++) |
@@ -12357,21 +12348,24 @@ chkmail(void) | |||
12357 | /* Very simplistic "hash": just a sum of all mtimes */ | 12348 | /* Very simplistic "hash": just a sum of all mtimes */ |
12358 | new_hash += (unsigned)statb.st_mtime; | 12349 | new_hash += (unsigned)statb.st_mtime; |
12359 | } | 12350 | } |
12360 | if (!mail_var_path_changed && mailtime_hash != new_hash) { | 12351 | if (mailtime_hash != new_hash) { |
12361 | if (mailtime_hash != 0) | 12352 | if (mailtime_hash != 0) |
12362 | out2str("you have mail\n"); | 12353 | out2str("you have mail\n"); |
12363 | mailtime_hash = new_hash; | 12354 | mailtime_hash = new_hash; |
12364 | } | 12355 | } |
12365 | mail_var_path_changed = 0; | ||
12366 | popstackmark(&smark); | 12356 | popstackmark(&smark); |
12367 | } | 12357 | } |
12368 | 12358 | ||
12369 | static void FAST_FUNC | 12359 | static void FAST_FUNC |
12370 | changemail(const char *val UNUSED_PARAM) | 12360 | changemail(const char *val UNUSED_PARAM) |
12371 | { | 12361 | { |
12372 | mail_var_path_changed = 1; | 12362 | mailtime_hash = 0; |
12373 | } | 12363 | } |
12374 | 12364 | ||
12365 | #else | ||
12366 | |||
12367 | # define chkmail() ((void)0) | ||
12368 | |||
12375 | #endif /* ASH_MAIL */ | 12369 | #endif /* ASH_MAIL */ |
12376 | 12370 | ||
12377 | 12371 | ||
@@ -14707,7 +14701,7 @@ static char * | |||
14707 | find_dot_file(char *basename) | 14701 | find_dot_file(char *basename) |
14708 | { | 14702 | { |
14709 | char *fullname; | 14703 | char *fullname; |
14710 | const char *path = pathval(); | 14704 | const char *path; |
14711 | struct stat statb; | 14705 | struct stat statb; |
14712 | int len; | 14706 | int len; |
14713 | 14707 | ||
@@ -14715,6 +14709,7 @@ find_dot_file(char *basename) | |||
14715 | if (strchr(basename, '/') IF_PLATFORM_MINGW32(|| strchr(basename, '\\'))) | 14709 | if (strchr(basename, '/') IF_PLATFORM_MINGW32(|| strchr(basename, '\\'))) |
14716 | return basename; | 14710 | return basename; |
14717 | 14711 | ||
14712 | path = pathval(); | ||
14718 | while ((len = padvance(&path, basename)) >= 0) { | 14713 | while ((len = padvance(&path, basename)) >= 0) { |
14719 | fullname = stackblock(); | 14714 | fullname = stackblock(); |
14720 | if ((!pathopt || *pathopt == 'f') | 14715 | if ((!pathopt || *pathopt == 'f') |
diff --git a/shell/ash_test/ash-signals/usage.right b/shell/ash_test/ash-signals/usage.right index c0dbd6c3c..df1ed2dd7 100644 --- a/shell/ash_test/ash-signals/usage.right +++ b/shell/ash_test/ash-signals/usage.right | |||
@@ -6,6 +6,18 @@ trap -- 'a' INT | |||
6 | trap -- 'a' USR1 | 6 | trap -- 'a' USR1 |
7 | trap -- 'a' USR2 | 7 | trap -- 'a' USR2 |
8 | ___ | 8 | ___ |
9 | trap -- 'a' EXIT trap -- 'a' INT trap -- 'a' USR1 trap -- 'a' USR2 | ||
10 | ___ | ||
11 | trap -- 'a' EXIT | ||
12 | trap -- 'a' INT | ||
13 | trap -- 'a' USR1 | ||
14 | trap -- 'a' USR2 | ||
15 | ___ | ||
16 | trap -- 'a' EXIT | ||
17 | trap -- 'a' INT | ||
18 | trap -- 'a' USR1 | ||
19 | trap -- 'a' USR2 | ||
20 | ___ | ||
9 | ___ | 21 | ___ |
10 | trap -- 'a' USR1 | 22 | trap -- 'a' USR1 |
11 | trap -- 'a' USR2 | 23 | trap -- 'a' USR2 |
diff --git a/shell/ash_test/ash-signals/usage.tests b/shell/ash_test/ash-signals/usage.tests index d29c6e74a..34e24cceb 100755 --- a/shell/ash_test/ash-signals/usage.tests +++ b/shell/ash_test/ash-signals/usage.tests | |||
@@ -10,6 +10,18 @@ trap "a" EXIT INT USR1 USR2 | |||
10 | echo ___ | 10 | echo ___ |
11 | trap | 11 | trap |
12 | 12 | ||
13 | # show them by command substitution | ||
14 | echo ___ | ||
15 | echo $(trap) | ||
16 | |||
17 | # show them by pipe | ||
18 | echo ___ | ||
19 | trap | cat | ||
20 | |||
21 | # show them by process substitution | ||
22 | echo ___ | ||
23 | cat <(trap) | ||
24 | |||
13 | # clear one | 25 | # clear one |
14 | echo ___ | 26 | echo ___ |
15 | trap 0 INT | 27 | trap 0 INT |
diff --git a/shell/hush.c b/shell/hush.c index e6be70078..a938cc790 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -7468,6 +7468,9 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
7468 | if (!cur->flg_export || cur->flg_read_only) | 7468 | if (!cur->flg_export || cur->flg_read_only) |
7469 | cnt += 2; | 7469 | cnt += 2; |
7470 | } | 7470 | } |
7471 | # if ENABLE_HUSH_LINENO_VAR | ||
7472 | cnt += 2; | ||
7473 | # endif | ||
7471 | # if ENABLE_HUSH_FUNCTIONS | 7474 | # if ENABLE_HUSH_FUNCTIONS |
7472 | for (funcp = G.top_func; funcp; funcp = funcp->next) | 7475 | for (funcp = G.top_func; funcp; funcp = funcp->next) |
7473 | cnt += 3; | 7476 | cnt += 3; |
@@ -7489,6 +7492,10 @@ static void re_execute_shell(char ***to_free, const char *s, | |||
7489 | *pp++ = cur->varstr; | 7492 | *pp++ = cur->varstr; |
7490 | } | 7493 | } |
7491 | } | 7494 | } |
7495 | # if ENABLE_HUSH_LINENO_VAR | ||
7496 | *pp++ = (char *) "-L"; | ||
7497 | *pp++ = utoa(G.execute_lineno); | ||
7498 | # endif | ||
7492 | # if ENABLE_HUSH_FUNCTIONS | 7499 | # if ENABLE_HUSH_FUNCTIONS |
7493 | for (funcp = G.top_func; funcp; funcp = funcp->next) { | 7500 | for (funcp = G.top_func; funcp; funcp = funcp->next) { |
7494 | *pp++ = (char *) "-F"; | 7501 | *pp++ = (char *) "-F"; |
@@ -10260,6 +10267,20 @@ int hush_main(int argc, char **argv) | |||
10260 | INIT_G(); | 10267 | INIT_G(); |
10261 | if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */ | 10268 | if (EXIT_SUCCESS != 0) /* if EXIT_SUCCESS == 0, it is already done */ |
10262 | G.last_exitcode = EXIT_SUCCESS; | 10269 | G.last_exitcode = EXIT_SUCCESS; |
10270 | #if !BB_MMU | ||
10271 | /* "Big heredoc" support via "sh -< STRING" invocation. | ||
10272 | * Check it first (do not bother to run the usual init code, | ||
10273 | * it is not needed for this case). | ||
10274 | */ | ||
10275 | if (argv[1] | ||
10276 | && argv[1][0] == '-' && argv[1][1] == '<' /*&& !argv[1][2]*/ | ||
10277 | /*&& argv[2] && !argv[3] - we don't check some conditions */ | ||
10278 | ) { | ||
10279 | full_write1_str(argv[2]); | ||
10280 | _exit(0); | ||
10281 | } | ||
10282 | G.argv0_for_re_execing = argv[0]; | ||
10283 | #endif | ||
10263 | #if ENABLE_HUSH_TRAP | 10284 | #if ENABLE_HUSH_TRAP |
10264 | # if ENABLE_HUSH_FUNCTIONS | 10285 | # if ENABLE_HUSH_FUNCTIONS |
10265 | G.return_exitcode = -1; | 10286 | G.return_exitcode = -1; |
@@ -10270,9 +10291,6 @@ int hush_main(int argc, char **argv) | |||
10270 | #if ENABLE_HUSH_FAST | 10291 | #if ENABLE_HUSH_FAST |
10271 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ | 10292 | G.count_SIGCHLD++; /* ensure it is != G.handled_SIGCHLD */ |
10272 | #endif | 10293 | #endif |
10273 | #if !BB_MMU | ||
10274 | G.argv0_for_re_execing = argv[0]; | ||
10275 | #endif | ||
10276 | 10294 | ||
10277 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ | 10295 | cached_getpid = getpid(); /* for tcsetpgrp() during init */ |
10278 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ | 10296 | G.root_pid = cached_getpid; /* for $PID (NOMMU can override via -$HEXPID:HEXPPID:...) */ |
@@ -10388,7 +10406,10 @@ int hush_main(int argc, char **argv) | |||
10388 | int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ | 10406 | int opt = getopt(argc, argv, "+" /* stop at 1st non-option */ |
10389 | "cexinsl" | 10407 | "cexinsl" |
10390 | #if !BB_MMU | 10408 | #if !BB_MMU |
10391 | "<:$:R:V:" | 10409 | "$:R:V:" |
10410 | # if ENABLE_HUSH_LINENO_VAR | ||
10411 | "L:" | ||
10412 | # endif | ||
10392 | # if ENABLE_HUSH_FUNCTIONS | 10413 | # if ENABLE_HUSH_FUNCTIONS |
10393 | "F:" | 10414 | "F:" |
10394 | # endif | 10415 | # endif |
@@ -10438,9 +10459,6 @@ int hush_main(int argc, char **argv) | |||
10438 | flags |= OPT_login; | 10459 | flags |= OPT_login; |
10439 | break; | 10460 | break; |
10440 | #if !BB_MMU | 10461 | #if !BB_MMU |
10441 | case '<': /* "big heredoc" support */ | ||
10442 | full_write1_str(optarg); | ||
10443 | _exit(0); | ||
10444 | case '$': { | 10462 | case '$': { |
10445 | unsigned long long empty_trap_mask; | 10463 | unsigned long long empty_trap_mask; |
10446 | 10464 | ||
@@ -10490,6 +10508,11 @@ int hush_main(int argc, char **argv) | |||
10490 | case 'V': | 10508 | case 'V': |
10491 | set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0); | 10509 | set_local_var(xstrdup(optarg), opt == 'R' ? SETFLAG_MAKE_RO : 0); |
10492 | break; | 10510 | break; |
10511 | # if ENABLE_HUSH_LINENO_VAR | ||
10512 | case 'L': | ||
10513 | G.parse_lineno = xatou(optarg); | ||
10514 | break; | ||
10515 | # endif | ||
10493 | # if ENABLE_HUSH_FUNCTIONS | 10516 | # if ENABLE_HUSH_FUNCTIONS |
10494 | case 'F': { | 10517 | case 'F': { |
10495 | struct function *funcp = new_function(optarg); | 10518 | struct function *funcp = new_function(optarg); |
@@ -11276,6 +11299,9 @@ static int FAST_FUNC builtin_local(char **argv) | |||
11276 | bb_error_msg("%s: not in a function", argv[0]); | 11299 | bb_error_msg("%s: not in a function", argv[0]); |
11277 | return EXIT_FAILURE; /* bash compat */ | 11300 | return EXIT_FAILURE; /* bash compat */ |
11278 | } | 11301 | } |
11302 | //TODO? ash and bash support "local -" special form, | ||
11303 | //which saves/restores $- around function call (including async returns, such as ^C) | ||
11304 | //(IOW: it makes "set +/-..." effects local) | ||
11279 | argv++; | 11305 | argv++; |
11280 | /* Since all builtins run in a nested variable level, | 11306 | /* Since all builtins run in a nested variable level, |
11281 | * need to use level - 1 here. Or else the variable will be removed at once | 11307 | * need to use level - 1 here. Or else the variable will be removed at once |
diff --git a/testsuite/find.tests b/testsuite/find.tests index 138236c81..d763ca6f2 100755 --- a/testsuite/find.tests +++ b/testsuite/find.tests | |||
@@ -28,6 +28,12 @@ testing "find -exec exitcode 2" \ | |||
28 | "0\n" \ | 28 | "0\n" \ |
29 | "" "" | 29 | "" "" |
30 | SKIP= | 30 | SKIP= |
31 | optional FEATURE_FIND_EXEC_OK | ||
32 | testing "find -ok" \ | ||
33 | "cd find.tempdir && find testfile -ok true {} ';' 2>&1; echo \$?" \ | ||
34 | "true testfile ?0\n" \ | ||
35 | "" "y" | ||
36 | SKIP= | ||
31 | # Surprisingly, "-exec false ;" results in exitcode 0! "-exec false +" is different!!! | 37 | # Surprisingly, "-exec false ;" results in exitcode 0! "-exec false +" is different!!! |
32 | optional FEATURE_FIND_EXEC | 38 | optional FEATURE_FIND_EXEC |
33 | testing "find -exec exitcode 3" \ | 39 | testing "find -exec exitcode 3" \ |