aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-10-09 16:42:57 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-10-09 16:42:57 +0200
commit550bf5b4a418378cd8f9fbbf5252fe57acdacb5a (patch)
tree7ed13e04cf415be6830363953220d7cffd4580b8
parent4cd99e7c6c1af77721b890ed5ae26d747796c4bd (diff)
downloadbusybox-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.h3
-rw-r--r--init/init.c9
-rw-r--r--libbb/fflush_stdout_and_exit.c13
-rw-r--r--libbb/vfork_daemon_rexec.c39
-rw-r--r--libbb/xfunc_die.c26
-rw-r--r--loginutils/getty.c7
-rw-r--r--shell/hush.c25
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 {
1127extern const char *msg_eol; 1127extern const char *msg_eol;
1128extern smallint syslog_level; 1128extern smallint syslog_level;
1129extern smallint logmode; 1129extern smallint logmode;
1130extern int die_sleep;
1131extern uint8_t xfunc_error_retval; 1130extern uint8_t xfunc_error_retval;
1132extern jmp_buf die_jmp; 1131extern void (*die_func)(void);
1133extern void xfunc_die(void) NORETURN FAST_FUNC; 1132extern void xfunc_die(void) NORETURN FAST_FUNC;
1134extern void bb_show_usage(void) NORETURN FAST_FUNC; 1133extern void bb_show_usage(void) NORETURN FAST_FUNC;
1135extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2))) FAST_FUNC; 1134extern 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
1018static void sleep_much(void)
1019{
1020 sleep(30 * 24*60*60);
1021}
1022
1018int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1023int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1019int init_main(int argc UNUSED_PARAM, char **argv) 1024int 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
16void FAST_FUNC fflush_stdout_and_exit(int retval) 16void 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
72static jmp_buf die_jmp;
73static 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
72struct nofork_save_area { 88struct 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};
79static void save_nofork_data(struct nofork_save_area *save) 95static 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}
87static void restore_nofork_data(struct nofork_save_area *save) 103static 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
96int FAST_FUNC run_nofork_applet(int applet_no, char **argv) 112int 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
15int die_sleep; 15void (*die_func)(void);
16#if ENABLE_FEATURE_PREFER_APPLETS || ENABLE_HUSH
17jmp_buf die_jmp;
18#endif
19 16
20void FAST_FUNC xfunc_die(void) 17void 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
523static void sleep10(void)
524{
525 sleep(10);
526}
527
523int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 528int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
524int getty_main(int argc UNUSED_PARAM, char **argv) 529int 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
1482static 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
1591static void xfunc_has_died(void) NORETURN;
1592static 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?
1592static int check_and_run_traps(void) 1602static 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 {