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:
Denys Vlasenko
2015-10-09 16:42:57 +02:00
parent 4cd99e7c6c
commit 550bf5b4a4
7 changed files with 61 additions and 61 deletions

View File

@@ -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();
}

View File

@@ -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 */

View File

@@ -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);
}