Rename two config options:

FEATURE_SH_STANDALONE_SHELL => FEATURE_SH_STANDALONE
FEATURE_EXEC_PREFER_APPLETS => FEATURE_PREFER_APPLETS
Make SH_STANDALONE depend on PREFER_APPLETS.
getopt.c: more randomconfig-induced fixes
This commit is contained in:
Denis Vlasenko 2007-04-10 23:03:30 +00:00
parent 8905496444
commit 80d14beae9
17 changed files with 67 additions and 40 deletions

View File

@ -238,7 +238,7 @@ config SELINUX
Most people will leave this set to 'N'. Most people will leave this set to 'N'.
config FEATURE_EXEC_PREFER_APPLETS config FEATURE_PREFER_APPLETS
bool "exec prefers applets" bool "exec prefers applets"
default n default n
help help
@ -462,10 +462,10 @@ config INSTALL_APPLET_HARDLINKS
config INSTALL_APPLET_DONT config INSTALL_APPLET_DONT
bool "not installed" bool "not installed"
depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE_SHELL || FEATURE_EXEC_PREFER_APPLETS depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE || FEATURE_PREFER_APPLETS
help help
Do not install applet links. Useful when using the -install feature Do not install applet links. Useful when using the -install feature
or a standalone shell for rescue pruposes. or a standalone shell for rescue purposes.
endchoice endchoice

View File

@ -35,7 +35,7 @@ CONFIG_FEATURE_SYSLOG=y
# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set
# CONFIG_FEATURE_HAVE_RPC is not set # CONFIG_FEATURE_HAVE_RPC is not set
# CONFIG_SELINUX is not set # CONFIG_SELINUX is not set
# CONFIG_FEATURE_EXEC_PREFER_APPLETS is not set # CONFIG_FEATURE_PREFER_APPLETS is not set
CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
# #
@ -657,7 +657,7 @@ CONFIG_MSH=y
# Bourne Shell Options # Bourne Shell Options
# #
CONFIG_FEATURE_SH_EXTRA_QUIET=y CONFIG_FEATURE_SH_EXTRA_QUIET=y
# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set # CONFIG_FEATURE_SH_STANDALONE is not set
# #
# System Logging Utilities # System Logging Utilities

View File

@ -56,8 +56,8 @@ s - suid type:
# define APPLET(name,l,s) { #name, name##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, # define APPLET(name,l,s) { #name, name##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) },
# define APPLET_NOUSAGE(name,main,l,s) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, # define APPLET_NOUSAGE(name,main,l,s) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) },
# define APPLET_ODDNAME(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) }, # define APPLET_ODDNAME(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) },
# define APPLET_NOEXEC(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_EXEC_PREFER_APPLETS(,1) }, # define APPLET_NOEXEC(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_PREFER_APPLETS(,1) },
# define APPLET_NOFORK(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_EXEC_PREFER_APPLETS(,1 ,1) }, # define APPLET_NOFORK(name,main,l,s,name2) { #name, main##_main USE_FEATURE_INSTALLER(,l) USE_FEATURE_SUID(,s) USE_FEATURE_PREFER_APPLETS(,1 ,1) },
#endif #endif
#if ENABLE_INSTALL_NO_USR #if ENABLE_INSTALL_NO_USR

View File

@ -37,7 +37,7 @@ struct bb_applet {
#if ENABLE_FEATURE_SUID #if ENABLE_FEATURE_SUID
__extension__ enum bb_suid_t need_suid:8; __extension__ enum bb_suid_t need_suid:8;
#endif #endif
#if ENABLE_FEATURE_EXEC_PREFER_APPLETS #if ENABLE_FEATURE_PREFER_APPLETS
/* true if instead if fork(); exec("applet"); waitpid(); /* true if instead if fork(); exec("applet"); waitpid();
* one can do fork(); exit(applet_main(argc,argv)); waitpid(); */ * one can do fork(); exit(applet_main(argc,argv)); waitpid(); */
unsigned char noexec; unsigned char noexec;

View File

@ -502,7 +502,7 @@ int execable_file(const char *name);
char *find_execable(const char *filename); char *find_execable(const char *filename);
int exists_execable(const char *filename); int exists_execable(const char *filename);
#if ENABLE_FEATURE_EXEC_PREFER_APPLETS #if ENABLE_FEATURE_PREFER_APPLETS
int bb_execvp(const char *file, char *const argv[]); int bb_execvp(const char *file, char *const argv[]);
#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd) #define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
#define BB_EXECLP(prog,cmd,...) \ #define BB_EXECLP(prog,cmd,...) \
@ -609,7 +609,8 @@ llist_t *llist_rev(llist_t *list);
int write_pidfile(const char *path); int write_pidfile(const char *path);
#define remove_pidfile(f) ((void)unlink(f)) #define remove_pidfile(f) ((void)unlink(f))
#else #else
#define write_pidfile(f) TRUE /* Why? #defining it to 1 gives "warning: statement with no effect"... */
static ATTRIBUTE_ALWAYS_INLINE int write_pidfile(const char *path) { return 1; }
#define remove_pidfile(f) ((void)0) #define remove_pidfile(f) ((void)0)
#endif #endif

View File

@ -13,7 +13,6 @@
* that too seems silly. * that too seems silly.
*/ */
#include <stdlib.h>
#include "libbb.h" #include "libbb.h"
int xfunc_error_retval = EXIT_FAILURE; int xfunc_error_retval = EXIT_FAILURE;

View File

@ -10,14 +10,14 @@
#include "libbb.h" #include "libbb.h"
int die_sleep; int die_sleep;
#if ENABLE_FEATURE_EXEC_PREFER_APPLETS #if ENABLE_FEATURE_PREFER_APPLETS
jmp_buf die_jmp; jmp_buf die_jmp;
#endif #endif
void xfunc_die(void) void xfunc_die(void)
{ {
if (die_sleep) { if (die_sleep) {
if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) {
/* Special case. We arrive here if NOFORK applet /* Special case. We arrive here if NOFORK applet
* calls xfunc, which then decides to die. * calls xfunc, which then decides to die.
* We don't die, but jump instead back to caller. * We don't die, but jump instead back to caller.

View File

@ -60,7 +60,7 @@ int exists_execable(const char *filename)
return 0; return 0;
} }
#if ENABLE_FEATURE_EXEC_PREFER_APPLETS #if ENABLE_FEATURE_PREFER_APPLETS
/* just like the real execvp, but try to launch an applet named 'file' first /* just like the real execvp, but try to launch an applet named 'file' first
*/ */
int bb_execvp(const char *file, char *const argv[]) int bb_execvp(const char *file, char *const argv[])

View File

@ -18,7 +18,7 @@ void fflush_stdout_and_exit(int retval)
if (fflush(stdout)) if (fflush(stdout))
xfunc_die(); xfunc_die();
if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) {
/* We are in NOFORK applet. Do not exit() directly, /* We are in NOFORK applet. Do not exit() directly,
* but use xfunc_die() */ * but use xfunc_die() */
xfunc_error_retval = retval; xfunc_error_retval = retval;

View File

@ -102,7 +102,7 @@ int wait_pid(int *wstat, int pid)
int spawn_and_wait(char **argv) int spawn_and_wait(char **argv)
{ {
#if ENABLE_FEATURE_EXEC_PREFER_APPLETS #if ENABLE_FEATURE_PREFER_APPLETS
int rc; int rc;
const struct bb_applet *a = find_applet_by_name(argv[0]); const struct bb_applet *a = find_applet_by_name(argv[0]);
@ -121,8 +121,13 @@ int spawn_and_wait(char **argv)
{ {
int old_sleep = die_sleep; int old_sleep = die_sleep;
int old_x = xfunc_error_retval; int old_x = xfunc_error_retval;
die_sleep = -1; /* special flag */ uint32_t old_m = option_mask32;
/* xfunc_die() checks for it */
xfunc_error_retval = EXIT_FAILURE;
/* special flag for xfunc_die(). If xfunc will "die"
* in NOFORK applet, xfunc_die() sees negative
* die_sleep and longjmp here instead. */
die_sleep = -1;
rc = setjmp(die_jmp); rc = setjmp(die_jmp);
if (!rc) { if (!rc) {
@ -144,6 +149,7 @@ int spawn_and_wait(char **argv)
die_sleep = old_sleep; die_sleep = old_sleep;
xfunc_error_retval = old_x; xfunc_error_retval = old_x;
option_mask32 = old_m;
return rc; return rc;
} }
#ifndef BB_NOMMU /* MMU only */ #ifndef BB_NOMMU /* MMU only */
@ -159,7 +165,7 @@ int spawn_and_wait(char **argv)
rc = spawn(argv); rc = spawn(argv);
w: w:
return wait4pid(rc); return wait4pid(rc);
#else /* !FEATURE_EXEC_PREFER_APPLETS */ #else /* !FEATURE_PREFER_APPLETS */
return wait4pid(spawn(argv)); return wait4pid(spawn(argv));
#endif #endif
} }

View File

@ -29,7 +29,7 @@ CONFIG_FEATURE_SUID_CONFIG=y
CONFIG_FEATURE_SUID_CONFIG_QUIET=y CONFIG_FEATURE_SUID_CONFIG_QUIET=y
# CONFIG_FEATURE_HAVE_RPC is not set # CONFIG_FEATURE_HAVE_RPC is not set
# CONFIG_SELINUX is not set # CONFIG_SELINUX is not set
# CONFIG_FEATURE_EXEC_PREFER_APPLETS is not set # CONFIG_FEATURE_PREFER_APPLETS is not set
CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe"
# #
@ -658,7 +658,7 @@ CONFIG_ASH_RANDOM_SUPPORT=y
# Bourne Shell Options # Bourne Shell Options
# #
CONFIG_FEATURE_SH_EXTRA_QUIET=y CONFIG_FEATURE_SH_EXTRA_QUIET=y
# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set # CONFIG_FEATURE_SH_STANDALONE is not set
# #
# System Logging Utilities # System Logging Utilities

View File

@ -216,10 +216,10 @@ config FEATURE_SH_EXTRA_QUIET
help help
Remove the busybox introduction when starting a shell. Remove the busybox introduction when starting a shell.
config FEATURE_SH_STANDALONE_SHELL config FEATURE_SH_STANDALONE
bool "Standalone shell" bool "Standalone shell"
default n default n
depends on MSH || LASH || HUSH || ASH depends on (MSH || LASH || HUSH || ASH) && FEATURE_PREFER_APPLETS
help help
This option causes the selected busybox shell to use busybox applets This option causes the selected busybox shell to use busybox applets
in preference to executables in the PATH whenever possible. For in preference to executables in the PATH whenever possible. For

View File

@ -6531,7 +6531,7 @@ tryexec(char *cmd, char **argv, char **envp)
{ {
int repeated = 0; int repeated = 0;
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
if (strchr(cmd, '/') == NULL) { if (strchr(cmd, '/') == NULL) {
const struct bb_applet *a; const struct bb_applet *a;
@ -6596,7 +6596,7 @@ shellexec(char **argv, const char *path, int idx)
clearredir(1); clearredir(1);
envp = environment(); envp = environment();
if (strchr(argv[0], '/') if (strchr(argv[0], '/')
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
|| find_applet_by_name(argv[0]) || find_applet_by_name(argv[0])
#endif #endif
) { ) {
@ -11116,7 +11116,7 @@ find_command(char *name, struct cmdentry *entry, int act, const char *path)
return; return;
} }
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
if (find_applet_by_name(name)) { if (find_applet_by_name(name)) {
entry->cmdtype = CMDNORMAL; entry->cmdtype = CMDNORMAL;
entry->u.index = -1; entry->u.index = -1;
@ -11341,7 +11341,7 @@ helpcmd(int argc, char **argv)
col = 0; col = 0;
} }
} }
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
for (i = 0; i < NUM_APPLETS; i++) { for (i = 0; i < NUM_APPLETS; i++) {
col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name); col += out1fmt("%c%s", ((col == 0) ? '\t' : ' '), applets[i].name);
if (col > 60) { if (col > 60) {

View File

@ -1112,7 +1112,7 @@ static void pseudo_exec(struct child_prog *child)
* really dislike relying on /proc for things. We could exec ourself * really dislike relying on /proc for things. We could exec ourself
* from global_argv[0], but if we are in a chroot, we may not be able * from global_argv[0], but if we are in a chroot, we may not be able
* to find ourself... */ * to find ourself... */
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
{ {
int argc_l; int argc_l;
char** argv_l = child->argv; char** argv_l = child->argv;

View File

@ -1164,7 +1164,7 @@ static int pseudo_exec(struct child_prog *child)
* /bin/foo invocation will fork and exec /bin/foo, even if * /bin/foo invocation will fork and exec /bin/foo, even if
* /bin/foo is a symlink to busybox. * /bin/foo is a symlink to busybox.
*/ */
if (ENABLE_FEATURE_SH_STANDALONE_SHELL) { if (ENABLE_FEATURE_SH_STANDALONE) {
char **argv_l = child->argv; char **argv_l = child->argv;
int argc_l; int argc_l;

View File

@ -37,7 +37,7 @@
# define DEFAULT_SHELL "/proc/self/exe" # define DEFAULT_SHELL "/proc/self/exe"
# define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe" # define CONFIG_BUSYBOX_EXEC_PATH "/proc/self/exe"
# define BB_BANNER "busybox standalone" # define BB_BANNER "busybox standalone"
# define ENABLE_FEATURE_SH_STANDALONE_SHELL 0 # define ENABLE_FEATURE_SH_STANDALONE 0
# define bb_msg_memory_exhausted "memory exhausted" # define bb_msg_memory_exhausted "memory exhausted"
# define xmalloc(size) malloc(size) # define xmalloc(size) malloc(size)
# define msh_main(argc,argv) main(argc,argv) # define msh_main(argc,argv) main(argc,argv)
@ -3064,7 +3064,7 @@ static const char *rexecve(char *c, char **v, char **envp)
int eacces = 0, asis = 0; int eacces = 0, asis = 0;
char *name = c; char *name = c;
if (ENABLE_FEATURE_SH_STANDALONE_SHELL) { if (ENABLE_FEATURE_SH_STANDALONE) {
optind = 1; optind = 1;
if (find_applet_by_name(name)) { if (find_applet_by_name(name)) {
/* We have to exec here since we vforked. Running /* We have to exec here since we vforked. Running
@ -3195,7 +3195,7 @@ static int dohelp(struct op *t)
} }
x++; x++;
} }
#if ENABLE_FEATURE_SH_STANDALONE_SHELL #if ENABLE_FEATURE_SH_STANDALONE
{ {
const struct bb_applet *applet = applets; const struct bb_applet *applet = applets;

View File

@ -38,8 +38,10 @@
mode */ mode */
enum { enum {
NON_OPT = 1, NON_OPT = 1,
#if ENABLE_GETOPT_LONG
/* LONG_OPT is the code that is returned when a long option is found. */ /* LONG_OPT is the code that is returned when a long option is found. */
LONG_OPT = 2 LONG_OPT = 2
#endif
}; };
/* For finding activated option flags. Must match getopt32 call! */ /* For finding activated option flags. Must match getopt32 call! */
@ -51,8 +53,10 @@ enum {
OPT_s = 0x10, // -s OPT_s = 0x10, // -s
OPT_T = 0x20, // -T OPT_T = 0x20, // -T
OPT_u = 0x40, // -u OPT_u = 0x40, // -u
#if ENABLE_GETOPT_LONG
OPT_a = 0x80, // -a OPT_a = 0x80, // -a
OPT_l = 0x100, // -l OPT_l = 0x100, // -l
#endif
SHELL_IS_TCSH = 0x8000, /* hijack this bit for other purposes */ SHELL_IS_TCSH = 0x8000, /* hijack this bit for other purposes */
}; };
@ -137,31 +141,45 @@ static const char *normalize(const char *arg)
* optstr must contain the short options, and longopts the long options. * optstr must contain the short options, and longopts the long options.
* Other settings are found in global variables. * Other settings are found in global variables.
*/ */
static int generate_output(char * argv[],int argc,const char *optstr, #if !ENABLE_GETOPT_LONG
const struct option *longopts) #define generate_output(argv,argc,optstr,longopts) generate_output(argv,argc,optstr)
#endif
static int generate_output(char **argv, int argc, const char *optstr, const struct option *longopts)
{ {
int exit_code = 0; /* We assume everything will be OK */ int exit_code = 0; /* We assume everything will be OK */
unsigned opt; unsigned opt;
#if ENABLE_GETOPT_LONG
int longindex; int longindex;
#endif
const char *charptr; const char *charptr;
if (quiet_errors) /* No error reporting from getopt(3) */ if (quiet_errors) /* No error reporting from getopt(3) */
opterr = 0; opterr = 0;
optind = 0; /* Reset getopt(3) */ optind = 0; /* Reset getopt(3) */
while ((opt = (alternative ? while (1) {
getopt_long_only(argc,argv,optstr,longopts,&longindex) : opt =
getopt_long(argc,argv,optstr,longopts,&longindex))) #if ENABLE_GETOPT_LONG
!= EOF) alternative ?
getopt_long_only(argc, argv, optstr, longopts, &longindex) :
getopt_long(argc, argv, optstr, longopts, &longindex);
#else
getopt(argc, argv, optstr);
#endif
if (opt == EOF)
break;
if (opt == '?' || opt == ':' ) if (opt == '?' || opt == ':' )
exit_code = 1; exit_code = 1;
else if (!quiet_output) { else if (!quiet_output) {
#if ENABLE_GETOPT_LONG
if (opt == LONG_OPT) { if (opt == LONG_OPT) {
printf(" --%s", longopts[longindex].name); printf(" --%s", longopts[longindex].name);
if (longopts[longindex].has_arg) if (longopts[longindex].has_arg)
printf(" %s", printf(" %s",
normalize(optarg ? optarg : "")); normalize(optarg ? optarg : ""));
} else if (opt == NON_OPT) } else
#endif
if (opt == NON_OPT)
printf(" %s", normalize(optarg)); printf(" %s", normalize(optarg));
else { else {
printf(" -%c", opt); printf(" -%c", opt);
@ -171,6 +189,7 @@ static int generate_output(char * argv[],int argc,const char *optstr,
normalize(optarg ? optarg : "")); normalize(optarg ? optarg : ""));
} }
} }
}
if (!quiet_output) { if (!quiet_output) {
printf(" --"); printf(" --");
@ -181,6 +200,7 @@ static int generate_output(char * argv[],int argc,const char *optstr,
return exit_code; return exit_code;
} }
#if ENABLE_GETOPT_LONG
/* /*
* Register several long options. options is a string of long options, * Register several long options. options is a string of long options,
* separated by commas or whitespace. * separated by commas or whitespace.
@ -224,6 +244,7 @@ static struct option *add_long_options(struct option *long_options, char *option
} }
return long_options; return long_options;
} }
#endif
static void set_shell(const char *new_shell) static void set_shell(const char *new_shell)
{ {
@ -262,13 +283,13 @@ static const struct option longopts[] = {
int getopt_main(int argc, char *argv[]); int getopt_main(int argc, char *argv[]);
int getopt_main(int argc, char *argv[]) int getopt_main(int argc, char *argv[])
{ {
struct option *long_options = NULL;
char *optstr = NULL; char *optstr = NULL;
char *name = NULL; char *name = NULL;
unsigned opt; unsigned opt;
const char *compatible; const char *compatible;
char *s_arg; char *s_arg;
#if ENABLE_GETOPT_LONG #if ENABLE_GETOPT_LONG
struct option *long_options = NULL;
llist_t *l_arg = NULL; llist_t *l_arg = NULL;
#endif #endif