diff options
author | Ron Yorston <rmy@pobox.com> | 2024-08-17 11:38:30 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2024-08-17 11:57:45 +0100 |
commit | b21899038683bd646446d3db9e84f64ea669d2ed (patch) | |
tree | 086a63f81d5b637efaf87792fc0bf1da77e9662e | |
parent | 027fb22e28fecc588d9e088a8d7d77fb63c7dc7b (diff) | |
download | busybox-w32-b21899038683bd646446d3db9e84f64ea669d2ed.tar.gz busybox-w32-b21899038683bd646446d3db9e84f64ea669d2ed.tar.bz2 busybox-w32-b21899038683bd646446d3db9e84f64ea669d2ed.zip |
which,ash: code shrink detection of standalone shell
Commit 6d87be4d7 (which,ash: changes to which/command/type) let
'which' detect when it's run from a standalone shell by having
the shell pass the undocumented '-s' option.
A better solution is to alter argv[0] when 'which' is run from a
standalone shell. This is possible because the code path through
run_noexec_applet_and_exit() and which_main() doesn't actually
use argv[0].
- No special treatment is required in ash when 'which' has no
arguments or the '--help' option.
- tryexec() no longer needs an extra element before the start of
argv. The commit 027fb22e2 can be reverted and the allocation
of argv in evalcommand() simplified.
- 'which' no longer needs to handle the '-s' option.
Saves 96-104 bytes.
-rw-r--r-- | debianutils/which.c | 17 | ||||
-rw-r--r-- | shell/ash.c | 22 |
2 files changed, 11 insertions, 28 deletions
diff --git a/debianutils/which.c b/debianutils/which.c index 6815768ab..fd3f53d3e 100644 --- a/debianutils/which.c +++ b/debianutils/which.c | |||
@@ -32,13 +32,6 @@ | |||
32 | 32 | ||
33 | #include "libbb.h" | 33 | #include "libbb.h" |
34 | 34 | ||
35 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
36 | enum { | ||
37 | OPT_a = (1 << 0), | ||
38 | OPT_s = (1 << 1) | ||
39 | }; | ||
40 | #endif | ||
41 | |||
42 | int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 35 | int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
43 | int which_main(int argc UNUSED_PARAM, char **argv) | 36 | int which_main(int argc UNUSED_PARAM, char **argv) |
44 | { | 37 | { |
@@ -47,7 +40,8 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |||
47 | /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */ | 40 | /* This sizeof(): bb_default_root_path is shorter than BB_PATH_ROOT_PATH */ |
48 | char buf[sizeof(BB_PATH_ROOT_PATH)]; | 41 | char buf[sizeof(BB_PATH_ROOT_PATH)]; |
49 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | 42 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE |
50 | int sh_standalone; | 43 | /* 'Which' in argv[0] indicates we were run from a standalone shell */ |
44 | int sh_standalone = argv[0][0] == 'W'; | ||
51 | #endif | 45 | #endif |
52 | 46 | ||
53 | env_path = getenv("PATH"); | 47 | env_path = getenv("PATH"); |
@@ -55,14 +49,7 @@ int which_main(int argc UNUSED_PARAM, char **argv) | |||
55 | /* env_path must be writable, and must not alloc, so... */ | 49 | /* env_path must be writable, and must not alloc, so... */ |
56 | env_path = strcpy(buf, bb_default_root_path); | 50 | env_path = strcpy(buf, bb_default_root_path); |
57 | 51 | ||
58 | #if ENABLE_PLATFORM_MINGW32 && ENABLE_FEATURE_SH_STANDALONE | ||
59 | /* '-s' option indicates we were run from a standalone shell */ | ||
60 | getopt32(argv, "^" "as" "\0" "-1"/*at least one arg*/); | ||
61 | sh_standalone = option_mask32 & OPT_s; | ||
62 | option_mask32 &= ~OPT_s; | ||
63 | #else | ||
64 | getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); | 52 | getopt32(argv, "^" "a" "\0" "-1"/*at least one arg*/); |
65 | #endif | ||
66 | argv += optind; | 53 | argv += optind; |
67 | 54 | ||
68 | do { | 55 | do { |
diff --git a/shell/ash.c b/shell/ash.c index 94aabbc4c..aa291b99d 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -9104,14 +9104,9 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) const char *cmd, char **argv, c | |||
9104 | /* mingw-w64's getopt() uses __argv[0] as the program name */ | 9104 | /* mingw-w64's getopt() uses __argv[0] as the program name */ |
9105 | __argv[0] = (char *)cmd; | 9105 | __argv[0] = (char *)cmd; |
9106 | /* 'which' wants to know if it was invoked from a standalone | 9106 | /* 'which' wants to know if it was invoked from a standalone |
9107 | * shell. Use the spare element of argv to add a flag, but | 9107 | * shell. 'Which' in argv[0] indicates this. */ |
9108 | * not if the first argument is '--help', that's a special | 9108 | if (strcmp(argv[0], "which") == 0) { |
9109 | * case. */ | 9109 | argv[0] = (char *)"Which"; |
9110 | if (strcmp(argv[0], "which") == 0 && | ||
9111 | (argv[1] == NULL || strcmp(argv[1], "--help") != 0)) { | ||
9112 | --argv; | ||
9113 | argv[0] = argv[1]; | ||
9114 | argv[1] = (char *)"-s"; | ||
9115 | } | 9110 | } |
9116 | # else | 9111 | # else |
9117 | if (APPLET_IS_NOEXEC(applet_no)) { | 9112 | if (APPLET_IS_NOEXEC(applet_no)) { |
@@ -11585,9 +11580,13 @@ evalcommand(union node *cmd, int flags) | |||
11585 | 11580 | ||
11586 | localvar_stop = pushlocalvars(vlocal); | 11581 | localvar_stop = pushlocalvars(vlocal); |
11587 | 11582 | ||
11583 | #if ENABLE_PLATFORM_MINGW32 | ||
11584 | argv = nargv = stalloc(sizeof(char *) * (argc + 1)); | ||
11585 | #else | ||
11588 | /* Reserve one extra spot at the front for shellexec. */ | 11586 | /* Reserve one extra spot at the front for shellexec. */ |
11589 | nargv = stalloc(sizeof(char *) * (argc + 2)); | 11587 | nargv = stalloc(sizeof(char *) * (argc + 2)); |
11590 | argv = ++nargv; | 11588 | argv = ++nargv; |
11589 | #endif | ||
11591 | for (sp = arglist.list; sp; sp = sp->next) { | 11590 | for (sp = arglist.list; sp; sp = sp->next) { |
11592 | TRACE(("evalcommand arg: %s\n", sp->text)); | 11591 | TRACE(("evalcommand arg: %s\n", sp->text)); |
11593 | *nargv++ = sp->text; | 11592 | *nargv++ = sp->text; |
@@ -16791,8 +16790,7 @@ argv_size(struct datasize ds, char **p) | |||
16791 | ds.funcstringsize += align_len(*p); | 16790 | ds.funcstringsize += align_len(*p); |
16792 | p++; | 16791 | p++; |
16793 | } | 16792 | } |
16794 | // Allow for argv[-1] used by tryexec(). | 16793 | ds.funcblocksize += sizeof(char *); |
16795 | ds.funcblocksize += 2 * sizeof(char *); | ||
16796 | } | 16794 | } |
16797 | return ds; | 16795 | return ds; |
16798 | } | 16796 | } |
@@ -16806,8 +16804,6 @@ argv_copy(char **p) | |||
16806 | #endif | 16804 | #endif |
16807 | 16805 | ||
16808 | if (p) { | 16806 | if (p) { |
16809 | // argv[-1] for tryexec() | ||
16810 | funcblock = (char *) funcblock + sizeof(char *); | ||
16811 | while (*p) { | 16807 | while (*p) { |
16812 | new = funcblock; | 16808 | new = funcblock; |
16813 | funcblock = (char *) funcblock + sizeof(char *); | 16809 | funcblock = (char *) funcblock + sizeof(char *); |
@@ -16818,7 +16814,7 @@ argv_copy(char **p) | |||
16818 | new = funcblock; | 16814 | new = funcblock; |
16819 | funcblock = (char *) funcblock + sizeof(char *); | 16815 | funcblock = (char *) funcblock + sizeof(char *); |
16820 | *new = NULL; | 16816 | *new = NULL; |
16821 | return start + 1; | 16817 | return start; |
16822 | } | 16818 | } |
16823 | return NULL; | 16819 | return NULL; |
16824 | } | 16820 | } |