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 | |
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>
-rw-r--r-- | include/libbb.h | 3 | ||||
-rw-r--r-- | init/init.c | 9 | ||||
-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 | ||||
-rw-r--r-- | loginutils/getty.c | 7 | ||||
-rw-r--r-- | shell/hush.c | 25 |
7 files changed, 61 insertions, 61 deletions
diff --git a/include/libbb.h b/include/libbb.h index d79843a2d..2f24ecbc3 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -1127,9 +1127,8 @@ enum { | |||
1127 | extern const char *msg_eol; | 1127 | extern const char *msg_eol; |
1128 | extern smallint syslog_level; | 1128 | extern smallint syslog_level; |
1129 | extern smallint logmode; | 1129 | extern smallint logmode; |
1130 | extern int die_sleep; | ||
1131 | extern uint8_t xfunc_error_retval; | 1130 | extern uint8_t xfunc_error_retval; |
1132 | extern jmp_buf die_jmp; | 1131 | extern void (*die_func)(void); |
1133 | extern void xfunc_die(void) NORETURN FAST_FUNC; | 1132 | extern void xfunc_die(void) NORETURN FAST_FUNC; |
1134 | extern void bb_show_usage(void) NORETURN FAST_FUNC; | 1133 | extern void bb_show_usage(void) NORETURN FAST_FUNC; |
1135 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; | 1134 | extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; |
diff --git a/init/init.c b/init/init.c index b2fe85635..80c5d0f74 100644 --- a/init/init.c +++ b/init/init.c | |||
@@ -1015,6 +1015,11 @@ void handle_sigsegv(int sig, siginfo_t *info, void *ucontext) | |||
1015 | } | 1015 | } |
1016 | #endif | 1016 | #endif |
1017 | 1017 | ||
1018 | static void sleep_much(void) | ||
1019 | { | ||
1020 | sleep(30 * 24*60*60); | ||
1021 | } | ||
1022 | |||
1018 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 1023 | int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
1019 | int init_main(int argc UNUSED_PARAM, char **argv) | 1024 | int init_main(int argc UNUSED_PARAM, char **argv) |
1020 | { | 1025 | { |
@@ -1051,12 +1056,12 @@ int init_main(int argc UNUSED_PARAM, char **argv) | |||
1051 | 1056 | ||
1052 | /* If, say, xmalloc would ever die, we don't want to oops kernel | 1057 | /* If, say, xmalloc would ever die, we don't want to oops kernel |
1053 | * by exiting. | 1058 | * by exiting. |
1054 | * NB: we set die_sleep *after* PID 1 check and bb_show_usage. | 1059 | * NB: we set die_func *after* PID 1 check and bb_show_usage. |
1055 | * Otherwise, for example, "init u" ("please rexec yourself" | 1060 | * Otherwise, for example, "init u" ("please rexec yourself" |
1056 | * command for sysvinit) will show help text (which isn't too bad), | 1061 | * command for sysvinit) will show help text (which isn't too bad), |
1057 | * *and sleep forever* (which is bad!) | 1062 | * *and sleep forever* (which is bad!) |
1058 | */ | 1063 | */ |
1059 | die_sleep = 30 * 24*60*60; | 1064 | die_func = sleep_much; |
1060 | 1065 | ||
1061 | /* Figure out where the default console should be */ | 1066 | /* Figure out where the default console should be */ |
1062 | console_init(); | 1067 | console_init(); |
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 | } |
diff --git a/loginutils/getty.c b/loginutils/getty.c index 174542841..762d5c773 100644 --- a/loginutils/getty.c +++ b/loginutils/getty.c | |||
@@ -520,6 +520,11 @@ static void alarm_handler(int sig UNUSED_PARAM) | |||
520 | _exit(EXIT_SUCCESS); | 520 | _exit(EXIT_SUCCESS); |
521 | } | 521 | } |
522 | 522 | ||
523 | static void sleep10(void) | ||
524 | { | ||
525 | sleep(10); | ||
526 | } | ||
527 | |||
523 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 528 | int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
524 | int getty_main(int argc UNUSED_PARAM, char **argv) | 529 | int getty_main(int argc UNUSED_PARAM, char **argv) |
525 | { | 530 | { |
@@ -599,7 +604,7 @@ int getty_main(int argc UNUSED_PARAM, char **argv) | |||
599 | close(n--); | 604 | close(n--); |
600 | 605 | ||
601 | /* Logging. We want special flavor of error_msg_and_die */ | 606 | /* Logging. We want special flavor of error_msg_and_die */ |
602 | die_sleep = 10; | 607 | die_func = sleep10; |
603 | msg_eol = "\r\n"; | 608 | msg_eol = "\r\n"; |
604 | /* most likely will internally use fd #3 in CLOEXEC mode: */ | 609 | /* most likely will internally use fd #3 in CLOEXEC mode: */ |
605 | openlog(applet_name, LOG_PID, LOG_AUTH); | 610 | openlog(applet_name, LOG_PID, LOG_AUTH); |
diff --git a/shell/hush.c b/shell/hush.c index f085ed3eb..0d107715f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1479,10 +1479,11 @@ static sighandler_t install_sighandler(int sig, sighandler_t handler) | |||
1479 | 1479 | ||
1480 | #if ENABLE_HUSH_JOB | 1480 | #if ENABLE_HUSH_JOB |
1481 | 1481 | ||
1482 | static void xfunc_has_died(void); | ||
1482 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ | 1483 | /* After [v]fork, in child: do not restore tty pgrp on xfunc death */ |
1483 | # define disable_restore_tty_pgrp_on_exit() (die_sleep = 0) | 1484 | # define disable_restore_tty_pgrp_on_exit() (die_func = NULL) |
1484 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ | 1485 | /* After [v]fork, in parent: restore tty pgrp on xfunc death */ |
1485 | # define enable_restore_tty_pgrp_on_exit() (die_sleep = -1) | 1486 | # define enable_restore_tty_pgrp_on_exit() (die_func = xfunc_has_died) |
1486 | 1487 | ||
1487 | /* Restores tty foreground process group, and exits. | 1488 | /* Restores tty foreground process group, and exits. |
1488 | * May be called as signal handler for fatal signal | 1489 | * May be called as signal handler for fatal signal |
@@ -1587,6 +1588,15 @@ static void hush_exit(int exitcode) | |||
1587 | #endif | 1588 | #endif |
1588 | } | 1589 | } |
1589 | 1590 | ||
1591 | static void xfunc_has_died(void) NORETURN; | ||
1592 | static void xfunc_has_died(void) | ||
1593 | { | ||
1594 | /* xfunc has failed! die die die */ | ||
1595 | /* no EXIT traps, this is an escape hatch! */ | ||
1596 | G.exiting = 1; | ||
1597 | hush_exit(xfunc_error_retval); | ||
1598 | } | ||
1599 | |||
1590 | 1600 | ||
1591 | //TODO: return a mask of ALL handled sigs? | 1601 | //TODO: return a mask of ALL handled sigs? |
1592 | static int check_and_run_traps(void) | 1602 | static int check_and_run_traps(void) |
@@ -7866,12 +7876,7 @@ int hush_main(int argc, char **argv) | |||
7866 | /* Initialize some more globals to non-zero values */ | 7876 | /* Initialize some more globals to non-zero values */ |
7867 | cmdedit_update_prompt(); | 7877 | cmdedit_update_prompt(); |
7868 | 7878 | ||
7869 | if (setjmp(die_jmp)) { | 7879 | die_func = xfunc_has_died; |
7870 | /* xfunc has failed! die die die */ | ||
7871 | /* no EXIT traps, this is an escape hatch! */ | ||
7872 | G.exiting = 1; | ||
7873 | hush_exit(xfunc_error_retval); | ||
7874 | } | ||
7875 | 7880 | ||
7876 | /* Shell is non-interactive at first. We need to call | 7881 | /* Shell is non-interactive at first. We need to call |
7877 | * install_special_sighandlers() if we are going to execute "sh <script>", | 7882 | * install_special_sighandlers() if we are going to execute "sh <script>", |
@@ -8129,9 +8134,7 @@ int hush_main(int argc, char **argv) | |||
8129 | /* Grab control of the terminal */ | 8134 | /* Grab control of the terminal */ |
8130 | tcsetpgrp(G_interactive_fd, getpid()); | 8135 | tcsetpgrp(G_interactive_fd, getpid()); |
8131 | } | 8136 | } |
8132 | /* -1 is special - makes xfuncs longjmp, not exit | 8137 | enable_restore_tty_pgrp_on_exit(); |
8133 | * (we reset die_sleep = 0 whereever we [v]fork) */ | ||
8134 | enable_restore_tty_pgrp_on_exit(); /* sets die_sleep = -1 */ | ||
8135 | 8138 | ||
8136 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 | 8139 | # if ENABLE_HUSH_SAVEHISTORY && MAX_HISTORY > 0 |
8137 | { | 8140 | { |