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>
This commit is contained in:
parent
33745b1fc8
commit
6bdfbc4cb5
@ -1219,6 +1219,7 @@ void run_noexec_applet_and_exit(int a, const char *name, char **argv) NORETURN F
|
|||||||
int find_applet_by_name(const char *name) FAST_FUNC;
|
int find_applet_by_name(const char *name) FAST_FUNC;
|
||||||
void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
|
void run_applet_no_and_exit(int a, const char *name, char **argv) NORETURN FAST_FUNC;
|
||||||
#endif
|
#endif
|
||||||
|
void show_usage_if_dash_dash_help(int applet_no, char **argv) FAST_FUNC;
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
void set_task_comm(const char *comm) FAST_FUNC;
|
void set_task_comm(const char *comm) FAST_FUNC;
|
||||||
#else
|
#else
|
||||||
|
@ -905,16 +905,8 @@ int busybox_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if NUM_APPLETS > 0
|
# if NUM_APPLETS > 0
|
||||||
void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
|
void FAST_FUNC show_usage_if_dash_dash_help(int applet_no, char **argv)
|
||||||
{
|
{
|
||||||
int argc = string_array_len(argv);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We do not use argv[0]: do not want to repeat massaging of
|
|
||||||
* "-/sbin/halt" -> "halt", for example.
|
|
||||||
*/
|
|
||||||
applet_name = name;
|
|
||||||
|
|
||||||
/* Special case. POSIX says "test --help"
|
/* Special case. POSIX says "test --help"
|
||||||
* should be no different from e.g. "test --foo".
|
* should be no different from e.g. "test --foo".
|
||||||
* Thus for "test", we skip --help check.
|
* 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
|
|||||||
&& applet_no != APPLET_NO_false
|
&& applet_no != APPLET_NO_false
|
||||||
# endif
|
# endif
|
||||||
) {
|
) {
|
||||||
if (argc == 2 && strcmp(argv[1], "--help") == 0) {
|
if (argv[1] && !argv[2] && strcmp(argv[1], "--help") == 0) {
|
||||||
/* Make "foo --help" exit with 0: */
|
/* Make "foo --help" exit with 0: */
|
||||||
xfunc_error_retval = 0;
|
xfunc_error_retval = 0;
|
||||||
bb_show_usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FAST_FUNC run_applet_no_and_exit(int applet_no, const char *name, char **argv)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We do not use argv[0]: do not want to repeat massaging of
|
||||||
|
* "-/sbin/halt" -> "halt", for example.
|
||||||
|
*/
|
||||||
|
applet_name = name;
|
||||||
|
|
||||||
|
show_usage_if_dash_dash_help(applet_no, argv);
|
||||||
|
|
||||||
if (ENABLE_FEATURE_SUID)
|
if (ENABLE_FEATURE_SUID)
|
||||||
check_suid(applet_no);
|
check_suid(applet_no);
|
||||||
|
|
||||||
|
argc = string_array_len(argv);
|
||||||
xfunc_error_retval = applet_main[applet_no](argc, argv);
|
xfunc_error_retval = applet_main[applet_no](argc, argv);
|
||||||
|
|
||||||
/* Note: applet_main() may also not return (die on a xfunc or such) */
|
/* Note: applet_main() may also not return (die on a xfunc or such) */
|
||||||
xfunc_die();
|
xfunc_die();
|
||||||
}
|
}
|
||||||
|
@ -109,8 +109,13 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
|||||||
char *tmp_argv[argc+1];
|
char *tmp_argv[argc+1];
|
||||||
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
|
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
|
||||||
applet_name = tmp_argv[0];
|
applet_name = tmp_argv[0];
|
||||||
|
|
||||||
|
/* longjmp's (instead of returning) if --help is seen */
|
||||||
|
show_usage_if_dash_dash_help(applet_no, argv);
|
||||||
|
|
||||||
/* Finally we can call NOFORK applet's main() */
|
/* Finally we can call NOFORK applet's main() */
|
||||||
rc = applet_main[applet_no](argc, tmp_argv);
|
rc = applet_main[applet_no](argc, tmp_argv);
|
||||||
|
|
||||||
/* Important for shells: `which CMD` was failing */
|
/* Important for shells: `which CMD` was failing */
|
||||||
fflush_all();
|
fflush_all();
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user