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:
@@ -15,15 +15,10 @@
|
||||
|
||||
void FAST_FUNC fflush_stdout_and_exit(int retval)
|
||||
{
|
||||
xfunc_error_retval = retval;
|
||||
if (fflush(stdout))
|
||||
bb_perror_msg_and_die(bb_msg_standard_output);
|
||||
|
||||
if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) {
|
||||
/* We are in NOFORK applet. Do not exit() directly,
|
||||
* but use xfunc_die() */
|
||||
xfunc_error_retval = retval;
|
||||
xfunc_die();
|
||||
}
|
||||
|
||||
exit(retval);
|
||||
/* In case we are in NOFORK applet. Do not exit() directly,
|
||||
* but use xfunc_die() */
|
||||
xfunc_die();
|
||||
}
|
||||
|
@@ -69,28 +69,44 @@ pid_t FAST_FUNC xspawn(char **argv)
|
||||
}
|
||||
|
||||
#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 {
|
||||
jmp_buf die_jmp;
|
||||
void (*die_func)(void);
|
||||
const char *applet_name;
|
||||
uint32_t option_mask32;
|
||||
int die_sleep;
|
||||
uint8_t xfunc_error_retval;
|
||||
};
|
||||
static void save_nofork_data(struct nofork_save_area *save)
|
||||
{
|
||||
memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp));
|
||||
save->die_func = die_func;
|
||||
save->applet_name = applet_name;
|
||||
save->xfunc_error_retval = xfunc_error_retval;
|
||||
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)
|
||||
{
|
||||
memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp));
|
||||
die_func = save->die_func;
|
||||
applet_name = save->applet_name;
|
||||
xfunc_error_retval = save->xfunc_error_retval;
|
||||
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)
|
||||
@@ -133,11 +149,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv)
|
||||
while (argv[argc])
|
||||
argc++;
|
||||
|
||||
/* 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;
|
||||
|
||||
/* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */
|
||||
die_func = jump;
|
||||
rc = setjmp(die_jmp);
|
||||
if (!rc) {
|
||||
/* 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]));
|
||||
/* Finally we can call NOFORK applet's main() */
|
||||
rc = applet_main[applet_no](argc, tmp_argv);
|
||||
} else { /* xfunc died in NOFORK applet */
|
||||
/* in case they meant to return 0... */
|
||||
if (rc == -2222)
|
||||
rc = 0;
|
||||
} else {
|
||||
/* xfunc died in NOFORK applet */
|
||||
}
|
||||
|
||||
/* Restoring some globals */
|
||||
|
@@ -7,34 +7,16 @@
|
||||
* 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... */
|
||||
|
||||
#include "libbb.h"
|
||||
|
||||
int die_sleep;
|
||||
#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
|
||||
jmp_buf die_jmp;
|
||||
#endif
|
||||
void (*die_func)(void);
|
||||
|
||||
void FAST_FUNC xfunc_die(void)
|
||||
{
|
||||
if (die_sleep) {
|
||||
if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH)
|
||||
&& 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);
|
||||
}
|
||||
if (die_func)
|
||||
die_func();
|
||||
exit(xfunc_error_retval);
|
||||
}
|
||||
|
Reference in New Issue
Block a user