diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-09 16:42:57 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-10-09 16:42:57 +0200 |
| commit | 550bf5b4a418378cd8f9fbbf5252fe57acdacb5a (patch) | |
| tree | 7ed13e04cf415be6830363953220d7cffd4580b8 /libbb | |
| parent | 4cd99e7c6c1af77721b890ed5ae26d747796c4bd (diff) | |
| download | busybox-w32-550bf5b4a418378cd8f9fbbf5252fe57acdacb5a.tar.gz busybox-w32-550bf5b4a418378cd8f9fbbf5252fe57acdacb5a.tar.bz2 busybox-w32-550bf5b4a418378cd8f9fbbf5252fe57acdacb5a.zip | |
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>
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/fflush_stdout_and_exit.c | 13 | ||||
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 39 | ||||
| -rw-r--r-- | libbb/xfunc_die.c | 26 |
3 files changed, 33 insertions, 45 deletions
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index 9ad5dbf96..b4bed865f 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c | |||
| @@ -15,15 +15,10 @@ | |||
| 15 | 15 | ||
| 16 | void FAST_FUNC fflush_stdout_and_exit(int retval) | 16 | void FAST_FUNC fflush_stdout_and_exit(int retval) |
| 17 | { | 17 | { |
| 18 | xfunc_error_retval = retval; | ||
| 18 | if (fflush(stdout)) | 19 | if (fflush(stdout)) |
| 19 | bb_perror_msg_and_die(bb_msg_standard_output); | 20 | bb_perror_msg_and_die(bb_msg_standard_output); |
| 20 | 21 | /* In case we are in NOFORK applet. Do not exit() directly, | |
| 21 | if (ENABLE_FEATURE_PREFER_APPLETS && die_sleep < 0) { | 22 | * but use xfunc_die() */ |
| 22 | /* We are in NOFORK applet. Do not exit() directly, | 23 | xfunc_die(); |
| 23 | * but use xfunc_die() */ | ||
| 24 | xfunc_error_retval = retval; | ||
| 25 | xfunc_die(); | ||
| 26 | } | ||
| 27 | |||
| 28 | exit(retval); | ||
| 29 | } | 24 | } |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index ed1f86f0c..d6ca7b263 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
| @@ -69,28 +69,44 @@ pid_t FAST_FUNC xspawn(char **argv) | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | #if ENABLE_FEATURE_PREFER_APPLETS | 71 | #if ENABLE_FEATURE_PREFER_APPLETS |
| 72 | static jmp_buf die_jmp; | ||
| 73 | static void jump(void) | ||
| 74 | { | ||
| 75 | /* Special case. We arrive here if NOFORK applet | ||
| 76 | * calls xfunc, which then decides to die. | ||
| 77 | * We don't die, but jump instead back to caller. | ||
| 78 | * NOFORK applets still cannot carelessly call xfuncs: | ||
| 79 | * p = xmalloc(10); | ||
| 80 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
| 81 | */ | ||
| 82 | /* | 0x100 allows to pass zero exitcode (longjmp can't pass 0). | ||
| 83 | * This works because exitcodes are bytes, | ||
| 84 | * run_nofork_applet() ensures that by "& 0xff" */ | ||
| 85 | longjmp(die_jmp, xfunc_error_retval | 0x100); | ||
| 86 | } | ||
| 87 | |||
| 72 | struct nofork_save_area { | 88 | struct nofork_save_area { |
| 73 | jmp_buf die_jmp; | 89 | jmp_buf die_jmp; |
| 90 | void (*die_func)(void); | ||
| 74 | const char *applet_name; | 91 | const char *applet_name; |
| 75 | uint32_t option_mask32; | 92 | uint32_t option_mask32; |
| 76 | int die_sleep; | ||
| 77 | uint8_t xfunc_error_retval; | 93 | uint8_t xfunc_error_retval; |
| 78 | }; | 94 | }; |
| 79 | static void save_nofork_data(struct nofork_save_area *save) | 95 | static void save_nofork_data(struct nofork_save_area *save) |
| 80 | { | 96 | { |
| 81 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); | 97 | memcpy(&save->die_jmp, &die_jmp, sizeof(die_jmp)); |
| 98 | save->die_func = die_func; | ||
| 82 | save->applet_name = applet_name; | 99 | save->applet_name = applet_name; |
| 83 | save->xfunc_error_retval = xfunc_error_retval; | ||
| 84 | save->option_mask32 = option_mask32; | 100 | save->option_mask32 = option_mask32; |
| 85 | save->die_sleep = die_sleep; | 101 | save->xfunc_error_retval = xfunc_error_retval; |
| 86 | } | 102 | } |
| 87 | static void restore_nofork_data(struct nofork_save_area *save) | 103 | static void restore_nofork_data(struct nofork_save_area *save) |
| 88 | { | 104 | { |
| 89 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); | 105 | memcpy(&die_jmp, &save->die_jmp, sizeof(die_jmp)); |
| 106 | die_func = save->die_func; | ||
| 90 | applet_name = save->applet_name; | 107 | applet_name = save->applet_name; |
| 91 | xfunc_error_retval = save->xfunc_error_retval; | ||
| 92 | option_mask32 = save->option_mask32; | 108 | option_mask32 = save->option_mask32; |
| 93 | die_sleep = save->die_sleep; | 109 | xfunc_error_retval = save->xfunc_error_retval; |
| 94 | } | 110 | } |
| 95 | 111 | ||
| 96 | int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | 112 | 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) | |||
| 133 | while (argv[argc]) | 149 | while (argv[argc]) |
| 134 | argc++; | 150 | argc++; |
| 135 | 151 | ||
| 136 | /* Special flag for xfunc_die(). If xfunc will "die" | 152 | /* If xfunc "dies" in NOFORK applet, die_func longjmp's here instead */ |
| 137 | * in NOFORK applet, xfunc_die() sees negative | 153 | die_func = jump; |
| 138 | * die_sleep and longjmp here instead. */ | ||
| 139 | die_sleep = -1; | ||
| 140 | |||
| 141 | rc = setjmp(die_jmp); | 154 | rc = setjmp(die_jmp); |
| 142 | if (!rc) { | 155 | if (!rc) { |
| 143 | /* Some callers (xargs) | 156 | /* Some callers (xargs) |
| @@ -146,10 +159,8 @@ int FAST_FUNC run_nofork_applet(int applet_no, char **argv) | |||
| 146 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | 159 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); |
| 147 | /* Finally we can call NOFORK applet's main() */ | 160 | /* Finally we can call NOFORK applet's main() */ |
| 148 | rc = applet_main[applet_no](argc, tmp_argv); | 161 | rc = applet_main[applet_no](argc, tmp_argv); |
| 149 | } else { /* xfunc died in NOFORK applet */ | 162 | } else { |
| 150 | /* in case they meant to return 0... */ | 163 | /* xfunc died in NOFORK applet */ |
| 151 | if (rc == -2222) | ||
| 152 | rc = 0; | ||
| 153 | } | 164 | } |
| 154 | 165 | ||
| 155 | /* Restoring some globals */ | 166 | /* Restoring some globals */ |
diff --git a/libbb/xfunc_die.c b/libbb/xfunc_die.c index 204e5e49d..73f7998e5 100644 --- a/libbb/xfunc_die.c +++ b/libbb/xfunc_die.c | |||
| @@ -7,34 +7,16 @@ | |||
| 7 | * Licensed under GPLv2, see file LICENSE in this source tree. | 7 | * Licensed under GPLv2, see file LICENSE in this source tree. |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | /* Keeping it separate allows to NOT suck in stdio for VERY small applets. | 10 | /* Keeping it separate allows to NOT pull in stdio for VERY small applets. |
| 11 | * Try building busybox with only "true" enabled... */ | 11 | * Try building busybox with only "true" enabled... */ |
| 12 | 12 | ||
| 13 | #include "libbb.h" | 13 | #include "libbb.h" |
| 14 | 14 | ||
| 15 | int die_sleep; | 15 | void (*die_func)(void); |
| 16 | #if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH | ||
| 17 | jmp_buf die_jmp; | ||
| 18 | #endif | ||
| 19 | 16 | ||
| 20 | void FAST_FUNC xfunc_die(void) | 17 | void FAST_FUNC xfunc_die(void) |
| 21 | { | 18 | { |
| 22 | if (die_sleep) { | 19 | if (die_func) |
| 23 | if ((ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH) | 20 | die_func(); |
| 24 | && die_sleep < 0 | ||
| 25 | ) { | ||
| 26 | /* Special case. We arrive here if NOFORK applet | ||
| 27 | * calls xfunc, which then decides to die. | ||
| 28 | * We don't die, but jump instead back to caller. | ||
| 29 | * NOFORK applets still cannot carelessly call xfuncs: | ||
| 30 | * p = xmalloc(10); | ||
| 31 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
| 32 | */ | ||
| 33 | /* -2222 means "zero" (longjmp can't pass 0) | ||
| 34 | * run_nofork_applet() catches -2222. */ | ||
| 35 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -2222); | ||
| 36 | } | ||
| 37 | sleep(die_sleep); | ||
| 38 | } | ||
| 39 | exit(xfunc_error_retval); | 21 | exit(xfunc_error_retval); |
| 40 | } | 22 | } |
