diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-02-18 23:30:24 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-02-18 23:30:24 +0100 |
| commit | 6bdfbc4cb5470f63d4905e89f89a9829af354316 (patch) | |
| tree | 573f2b655d4944d4e5e9e7627f18c8a4bb1ebeaa /libbb | |
| parent | 33745b1fc8cc6d41f4e708d67800d296668af2ce (diff) | |
| download | busybox-w32-6bdfbc4cb5470f63d4905e89f89a9829af354316.tar.gz busybox-w32-6bdfbc4cb5470f63d4905e89f89a9829af354316.tar.bz2 busybox-w32-6bdfbc4cb5470f63d4905e89f89a9829af354316.zip | |
libbb: fix '--help' handling in FEATURE_SH_NOFORK=y
Most BusyBox applets respond to the '--help' option by printing
a usage message. This is normally handled by busybox_main() so
applet main routines don't have support for '--help'.
In standalone shell mode with FEATURE_SH_NOFORK enabled nofork
applets are invoked directly, bypassing busybox_main(). This
results in inconsistent handling of '--help':
- applets which call getopt() report "unrecognized option '--help'"
and print help anyway;
- realpath says "--help: No such file or directory" and doesn't
print help;
- usleep says "invalid number '--help'" and doesn't print help.
Avoid inconsistency by checking for '--help' in run_nofork_applet().
Bug found by Ron Yorston.
function old new delta
show_usage_if_dash_dash_help - 70 +70
run_nofork_applet 347 362 +15
run_applet_no_and_exit 432 365 -67
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 1/1 up/down: 85/-67) Total: 18 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/appletlib.c | 29 | ||||
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 5 |
2 files changed, 24 insertions, 10 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index 542211255..67c540abb 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
| @@ -905,16 +905,8 @@ int busybox_main(int argc UNUSED_PARAM, char **argv) | |||
| 905 | # endif | 905 | # endif |
| 906 | 906 | ||
| 907 | # if NUM_APPLETS > 0 | 907 | # if NUM_APPLETS > 0 |
| 908 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | 908 | void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv) |
| 909 | { | 909 | { |
| 910 | int argc = string_array_len(argv); | ||
| 911 | |||
| 912 | /* | ||
| 913 | * We do not use argv[0]: do not want to repeat massaging of | ||
| 914 | * "-/sbin/halt" -> "halt", for example. | ||
| 915 | */ | ||
| 916 | applet_name = name; | ||
| 917 | |||
| 918 | /* Special case. POSIX says "test --help" | 910 | /* Special case. POSIX says "test --help" |
| 919 | * should be no different from e.g. "test --foo". | 911 | * should be no different from e.g. "test --foo". |
| 920 | * Thus for "test", we skip --help check. | 912 | * Thus for "test", we skip --help check. |
| @@ -931,15 +923,32 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **ar | |||
| 931 | && applet_no != APPLET_NO_false | 923 | && applet_no != APPLET_NO_false |
| 932 | # endif | 924 | # endif |
| 933 | ) { | 925 | ) { |
| 934 | if (argc == 2 && strcmp(argv[1], "--help") == 0) { | 926 | if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) { |
| 935 | /* Make "foo --help" exit with 0: */ | 927 | /* Make "foo --help" exit with 0: */ |
| 936 | xfunc_error_retval = 0; | 928 | xfunc_error_retval = 0; |
| 937 | bb_show_usage(); | 929 | bb_show_usage(); |
| 938 | } | 930 | } |
| 939 | } | 931 | } |
| 932 | } | ||
| 933 | |||
| 934 | void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv) | ||
| 935 | { | ||
| 936 | int argc; | ||
| 937 | |||
| 938 | /* | ||
| 939 | * We do not use argv[0]: do not want to repeat massaging of | ||
| 940 | * "-/sbin/halt" -> "halt", for example. | ||
| 941 | */ | ||
| 942 | applet_name = name; | ||
| 943 | |||
| 944 | show_usage_if_dash_dash_help(applet_no, argv); | ||
| 945 | |||
| 940 | if (ENABLE_FEATURE_SUID) | 946 | if (ENABLE_FEATURE_SUID) |
| 941 | check_suid(applet_no); | 947 | check_suid(applet_no); |
| 948 | |||
| 949 | argc = string_array_len(argv); | ||
| 942 | xfunc_error_retval = applet_main[applet_no](argc, argv); | 950 | xfunc_error_retval = applet_main[applet_no](argc, argv); |
| 951 | |||
| 943 | /* Note: applet_main() may also not return (die on a xfunc or such) */ | 952 | /* Note: applet_main() may also not return (die on a xfunc or such) */ |
| 944 | xfunc_die(); | 953 | xfunc_die(); |
| 945 | } | 954 | } |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 65271e84f..a49fe8e01 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
| @@ -109,8 +109,13 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
| 109 | char *tmp_argv[argc+1]; | 109 | char *tmp_argv[argc+1]; |
| 110 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 110 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
| 111 | applet_name = tmp_argv[0]; | 111 | applet_name = tmp_argv[0]; |
| 112 | |||
| 113 | /* longjmp's (instead of returning) if --help is seen */ | ||
| 114 | show_usage_if_dash_dash_help(applet_no, argv); | ||
| 115 | |||
| 112 | /* Finally we can call NOFORK applet's main() */ | 116 | /* Finally we can call NOFORK applet's main() */ |
| 113 | rc = applet_main[applet_no](argc, tmp_argv); | 117 | rc = applet_main[applet_no](argc, tmp_argv); |
| 118 | |||
| 114 | /* Important for shells: `which CMD` was failing */ | 119 | /* Important for shells: `which CMD` was failing */ |
| 115 | fflush_all(); | 120 | fflush_all(); |
| 116 | } else { | 121 | } else { |
