remove global "jmp_buf die_jmp" from !FEATURE_PREFER_APPLETS builds
function old new delta xfunc_has_died - 21 +21 sleep_much - 12 +12 sleep10 - 9 +9 die_func - 4 +4 fflush_stdout_and_exit 35 36 +1 builtin_type 121 119 -2 die_sleep 4 - -4 xfunc_die 60 24 -36 hush_main 1128 1011 -117 die_jmp 156 - -156 ------------------------------------------------------------------------------ (add/remove: 4/2 grow/shrink: 1/3 up/down: 47/-315) Total: -268 bytes text data bss dec hex filename 939992 992 17652 958636 ea0ac busybox_old 939880 992 17496 958368 e9fa0 busybox_unstripped Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
4cd99e7c6c
commit
550bf5b4a4
@ -1127,9 +1127,8 @@ enum {
|
|||||||
extern const char *msg_eol;
|
extern const char *msg_eol;
|
||||||
extern smallint syslog_level;
|
extern smallint syslog_level;
|
||||||
extern smallint logmode;
|
extern smallint logmode;
|
||||||
extern int die_sleep;
|
|
||||||
extern uint8_t xfunc_error_retval;
|
extern uint8_t xfunc_error_retval;
|
||||||
extern jmp_buf die_jmp;
|
extern void (*die_func)(void);
|
||||||
extern void xfunc_die(void) NORETURN FAST_FUNC;
|
extern void xfunc_die(void) NORETURN FAST_FUNC;
|
||||||
extern void bb_show_usage(void) NORETURN FAST_FUNC;
|
extern void bb_show_usage(void) NORETURN FAST_FUNC;
|
||||||
extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
|
extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC;
|
||||||
|
@ -1015,6 +1015,11 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void sleep_much(void)
|
||||||
|
{
|
||||||
|
sleep(30 * 24*60*60);
|
||||||
|
}
|
||||||
|
|
||||||
int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int init_main(int argc UNUSED_PARAM, char **argv)
|
int init_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
@ -1051,12 +1056,12 @@ int init_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
|
|
||||||
/* If, say, xmalloc would ever die, we don't want to oops kernel
|
/* If, say, xmalloc would ever die, we don't want to oops kernel
|
||||||
* by exiting.
|
* by exiting.
|
||||||
* NB: we set die_sleep *after* PID 1 check and bb_show_usage.
|
* NB: we set die_func *after* PID 1 check and bb_show_usage.
|
||||||
* Otherwise, for example, "init u" ("please rexec yourself"
|
* Otherwise, for example, "init u" ("please rexec yourself"
|
||||||
* command for sysvinit) will show help text (which isn't too bad),
|
* command for sysvinit) will show help text (which isn't too bad),
|
||||||
* *and sleep forever* (which is bad!)
|
* *and sleep forever* (which is bad!)
|
||||||
*/
|
*/
|
||||||
die_sleep = 30 * 24*60*60;
|
die_func = sleep_much;
|
||||||
|
|
||||||
/* Figure out where the default console should be */
|
/* Figure out where the default console should be */
|
||||||
console_init();
|
console_init();
|
||||||
|
@ -15,15 +15,10 @@
|
|||||||
|
|
||||||
void FAST_FUNC fflush_stdout_and_exit(int retval)
|
void FAST_FUNC fflush_stdout_and_exit(int retval)
|
||||||
{
|
{
|
||||||
|
xfunc_error_retval = retval;
|
||||||
if (fflush(stdout))
|
if (fflush(stdout))
|
||||||
bb_perror_msg_and_die(bb_msg_standard_output);
|
bb_perror_msg_and_die(bb_msg_standard_output);
|
||||||
|
/* In case we are in NOFORK applet. Do not exit() directly,
|
||||||
if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) {
|
|
||||||
/* We are in NOFORK applet. Do not exit() directly,
|
|
||||||
* but use xfunc_die() */
|
* but use xfunc_die() */
|
||||||
xfunc_error_retval = retval;
|
|
||||||
xfunc_die();
|
xfunc_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(retval);
|
|
||||||
}
|
|
||||||
|
@ -69,28 +69,44 @@ pid_t FAST_FUNC xspawn(char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLE_FEATURE_PREFER_APPLETS
|
#if ENABLE_FEATURE_PREFER_APPLETS
|
||||||
|
static jmp_buf die_jmp;
|
||||||
|
static void jump(void)
|
||||||
|
{
|
||||||
|
/* Special case. We arrive here if NOFORK applet
|
||||||
|
* calls xfunc, which then decides to die.
|
||||||
|
* We don't die, but jump instead back to caller.
|
||||||
|
* NOFORK applets still cannot carelessly call xfuncs:
|
||||||
|
* p = xmalloc(10);
|
||||||
|
* q = xmalloc(10); // BUG! if this dies, we leak p!
|
||||||
|
*/
|
||||||
|
/* | 0x100 allows to pass zero exitcode (longjmp can't pass 0).
|
||||||
|
* This works because exitcodes are bytes,
|
||||||
|
* run_nofork_applet() ensures that by "& 0xff" */
|
||||||
|
longjmp(die_jmp, xfunc_error_retval | 0x100);
|
||||||
|
}
|
||||||
|
|
||||||
struct nofork_save_area {
|
struct nofork_save_area {
|
||||||
jmp_buf die_jmp;
|
jmp_buf die_jmp;
|
||||||
|
void (*die_func)(void);
|
||||||
const char *applet_name;
|
const char *applet_name;
|
||||||
uint32_t option_mask32;
|
uint32_t option_mask32;
|
||||||
int die_sleep;
|
|
||||||
uint8_t xfunc_error_retval;
|
uint8_t xfunc_error_retval;
|
||||||
};
|
};
|
||||||
static void save_nofork_data(struct nofork_save_area *save)
|
static void save_nofork_data(struct nofork_save_area *save)
|
||||||
{
|
{
|
||||||
memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
|
memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
|
||||||
|
save->die_func = die_func;
|
||||||
save->applet_name = applet_name;
|
save->applet_name = applet_name;
|
||||||
save->xfunc_error_retval = xfunc_error_retval;
|
|
||||||
save->option_mask32 = option_mask32;
|
save->option_mask32 = option_mask32;
|
||||||
save->die_sleep = die_sleep;
|
save->xfunc_error_retval = xfunc_error_retval;
|
||||||
}
|
}
|
||||||
static void restore_nofork_data(struct nofork_save_area *save)
|
static void restore_nofork_data(struct nofork_save_area *save)
|
||||||
{
|
{
|
||||||
memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
|
memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
|
||||||
|
die_func = save->die_func;
|
||||||
applet_name = save->applet_name;
|
applet_name = save->applet_name;
|
||||||
xfunc_error_retval = save->xfunc_error_retval;
|
|
||||||
option_mask32 = save->option_mask32;
|
option_mask32 = save->option_mask32;
|
||||||
die_sleep = save->die_sleep;
|
xfunc_error_retval = save->xfunc_error_retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
||||||
@ -133,11 +149,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
|||||||
while (argv[argc])
|
while (argv[argc])
|
||||||
argc++;
|
argc++;
|
||||||
|
|
||||||
/* Special flag for xfunc_die(). If xfunc will "die"
|
/* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */
|
||||||
* in NOFORK applet, xfunc_die() sees negative
|
die_func = jump;
|
||||||
* die_sleep and longjmp here instead. */
|
|
||||||
die_sleep = -1;
|
|
||||||
|
|
||||||
rc = setjmp(die_jmp);
|
rc = setjmp(die_jmp);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
/* Some callers (xargs)
|
/* Some callers (xargs)
|
||||||
@ -146,10 +159,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
|||||||
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
|
memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
|
||||||
/* 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);
|
||||||
} else { /* xfunc died in NOFORK applet */
|
} else {
|
||||||
/* in case they meant to return 0... */
|
/* xfunc died in NOFORK applet */
|
||||||
if (rc == -2222)
|
|
||||||
rc = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restoring some globals */
|
/* Restoring some globals */
|
||||||
|
@ -7,34 +7,16 @@
|
|||||||
* Licensed under GPLv2, see file LICENSE in this source tree.
|
* Licensed under GPLv2, see file LICENSE in this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Keeping it separate allows to NOT suck in stdio for VERY small applets.
|
/* Keeping it separate allows to NOT pull in stdio for VERY small applets.
|
||||||
* Try building busybox with only "true" enabled... */
|
* Try building busybox with only "true" enabled... */
|
||||||
|
|
||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
|
|
||||||
int die_sleep;
|
void (*die_func)(void);
|
||||||
#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
|
|
||||||
jmp_buf die_jmp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FAST_FUNC xfunc_die(void)
|
void FAST_FUNC xfunc_die(void)
|
||||||
{
|
{
|
||||||
if (die_sleep) {
|
if (die_func)
|
||||||
if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
|
die_func();
|
||||||
&& die_sleep < 0
|
|
||||||
) {
|
|
||||||
/* Special case. We arrive here if NOFORK applet
|
|
||||||
* calls xfunc, which then decides to die.
|
|
||||||
* We don't die, but jump instead back to caller.
|
|
||||||
* NOFORK applets still cannot carelessly call xfuncs:
|
|
||||||
* p = xmalloc(10);
|
|
||||||
* q = xmalloc(10); // BUG! if this dies, we leak p!
|
|
||||||
*/
|
|
||||||
/* -2222 means "zero" (longjmp can't pass 0)
|
|
||||||
* run_nofork_applet() catches -2222. */
|
|
||||||
longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222);
|
|
||||||
}
|
|
||||||
sleep(die_sleep);
|
|
||||||
}
|
|
||||||
exit(xfunc_error_retval);
|
exit(xfunc_error_retval);
|
||||||
}
|
}
|
||||||
|
@ -520,6 +520,11 @@ static void alarm_handler(int sig UNUSED_PARAM)
|
|||||||
_exit(EXIT_SUCCESS);
|
_exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sleep10(void)
|
||||||
|
{
|
||||||
|
sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||||
int getty_main(int argc UNUSED_PARAM, char **argv)
|
int getty_main(int argc UNUSED_PARAM, char **argv)
|
||||||
{
|
{
|
||||||
@ -599,7 +604,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
|
|||||||
close(n--);
|
close(n--);
|
||||||
|
|
||||||
/* Logging. We want special flavor of error_msg_and_die */
|
/* Logging. We want special flavor of error_msg_and_die */
|
||||||
die_sleep = 10;
|
die_func = sleep10;
|
||||||
msg_eol = "\r\n";
|
msg_eol = "\r\n";
|
||||||
/* most likely will internally use fd #3 in CLOEXEC mode: */
|
/* most likely will internally use fd #3 in CLOEXEC mode: */
|
||||||
openlog(applet_name, LOG_PID, LOG_AUTH);
|
openlog(applet_name, LOG_PID, LOG_AUTH);
|
||||||
|
25
shell/hush.c
25
shell/hush.c
@ -1479,10 +1479,11 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler)
|
|||||||
|
|
||||||
#if ENABLE_HUSH_JOB
|
#if ENABLE_HUSH_JOB
|
||||||
|
|
||||||
|
static void xfunc_has_died(void);
|
||||||
/* After [v]fork, in child: do not restore tty pgrp on xfunc death */
|
/* After [v]fork, in child: do not restore tty pgrp on xfunc death */
|
||||||
# define disable_restore_tty_pgrp_on_exit() (die_sleep = 0)
|
# define disable_restore_tty_pgrp_on_exit() (die_func = NULL)
|
||||||
/* After [v]fork, in parent: restore tty pgrp on xfunc death */
|
/* After [v]fork, in parent: restore tty pgrp on xfunc death */
|
||||||
# define enable_restore_tty_pgrp_on_exit() (die_sleep = -1)
|
# define enable_restore_tty_pgrp_on_exit() (die_func = xfunc_has_died)
|
||||||
|
|
||||||
/* Restores tty foreground process group, and exits.
|
/* Restores tty foreground process group, and exits.
|
||||||
* May be called as signal handler for fatal signal
|
* May be called as signal handler for fatal signal
|
||||||
@ -1587,6 +1588,15 @@ static void hush_exit(int exitcode)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void xfunc_has_died(void) NORETURN;
|
||||||
|
static void xfunc_has_died(void)
|
||||||
|
{
|
||||||
|
/* xfunc has failed! die die die */
|
||||||
|
/* no EXIT traps, this is an escape hatch! */
|
||||||
|
G.exiting = 1;
|
||||||
|
hush_exit(xfunc_error_retval);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//TODO: return a mask of ALL handled sigs?
|
//TODO: return a mask of ALL handled sigs?
|
||||||
static int check_and_run_traps(void)
|
static int check_and_run_traps(void)
|
||||||
@ -7866,12 +7876,7 @@ int hush_main(int argc, char **argv)
|
|||||||
/* Initialize some more globals to non-zero values */
|
/* Initialize some more globals to non-zero values */
|
||||||
cmdedit_update_prompt();
|
cmdedit_update_prompt();
|
||||||
|
|
||||||
if (setjmp(die_jmp)) {
|
die_func = xfunc_has_died;
|
||||||
/* xfunc has failed! die die die */
|
|
||||||
/* no EXIT traps, this is an escape hatch! */
|
|
||||||
G.exiting = 1;
|
|
||||||
hush_exit(xfunc_error_retval);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Shell is non-interactive at first. We need to call
|
/* Shell is non-interactive at first. We need to call
|
||||||
* install_special_sighandlers() if we are going to execute "sh <script>",
|
* install_special_sighandlers() if we are going to execute "sh <script>",
|
||||||
@ -8129,9 +8134,7 @@ int hush_main(int argc, char **argv)
|
|||||||
/* Grab control of the terminal */
|
/* Grab control of the terminal */
|
||||||
tcsetpgrp(G_interactive_fd, getpid());
|
tcsetpgrp(G_interactive_fd, getpid());
|
||||||
}
|
}
|
||||||
/* -1 is special - makes xfuncs longjmp, not exit
|
enable_restore_tty_pgrp_on_exit();
|
||||||
* (we reset die_sleep = 0 whereever we [v]fork) */
|
|
||||||
enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */
|
|
||||||
|
|
||||||
# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
|
# if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user