diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:38:30 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:38:30 +0000 |
commit | 335b63d8d1876ce4e172ebcc9d64544785682244 (patch) | |
tree | 14183fd728ce51ae10baee70f7d8f72c39d30649 /libbb | |
parent | 07c394e69b0cfa7cd30e97ffc6edb0d857905f45 (diff) | |
download | busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.tar.gz busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.tar.bz2 busybox-w32-335b63d8d1876ce4e172ebcc9d64544785682244.zip |
make a few struct bb_applet members conditional
rename sllep_and_die -> xfunc_die
make fflush_stdout_and_exit NOFORK-safe
fix some buglets found by randomconfig
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/copyfd.c | 4 | ||||
-rw-r--r-- | libbb/error_msg_and_die.c | 21 | ||||
-rw-r--r-- | libbb/fflush_stdout_and_exit.c | 14 | ||||
-rw-r--r-- | libbb/herror_msg_and_die.c | 5 | ||||
-rw-r--r-- | libbb/perror_msg_and_die.c | 6 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 23 | ||||
-rw-r--r-- | libbb/xconnect.c | 2 | ||||
-rw-r--r-- | libbb/xfuncs.c | 2 |
8 files changed, 49 insertions, 28 deletions
diff --git a/libbb/copyfd.c b/libbb/copyfd.c index e0596d5f6..aa8fbb967 100644 --- a/libbb/copyfd.c +++ b/libbb/copyfd.c | |||
@@ -74,7 +74,7 @@ void complain_copyfd_and_die(off_t sz) | |||
74 | if (sz != -1) | 74 | if (sz != -1) |
75 | bb_error_msg_and_die("short read"); | 75 | bb_error_msg_and_die("short read"); |
76 | /* if sz == -1, bb_copyfd_XX already complained */ | 76 | /* if sz == -1, bb_copyfd_XX already complained */ |
77 | sleep_and_die(); | 77 | xfunc_die(); |
78 | } | 78 | } |
79 | #endif | 79 | #endif |
80 | 80 | ||
@@ -94,7 +94,7 @@ void bb_copyfd_exact_size(int fd1, int fd2, off_t size) | |||
94 | if (sz != -1) | 94 | if (sz != -1) |
95 | bb_error_msg_and_die("short read"); | 95 | bb_error_msg_and_die("short read"); |
96 | /* if sz == -1, bb_copyfd_XX already complained */ | 96 | /* if sz == -1, bb_copyfd_XX already complained */ |
97 | sleep_and_die(); | 97 | xfunc_die(); |
98 | } | 98 | } |
99 | 99 | ||
100 | off_t bb_copyfd_eof(int fd1, int fd2) | 100 | off_t bb_copyfd_eof(int fd1, int fd2) |
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c index 39178a3ce..4a9049364 100644 --- a/libbb/error_msg_and_die.c +++ b/libbb/error_msg_and_die.c | |||
@@ -10,14 +10,25 @@ | |||
10 | #include "libbb.h" | 10 | #include "libbb.h" |
11 | 11 | ||
12 | int die_sleep; | 12 | int die_sleep; |
13 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS | ||
13 | jmp_buf die_jmp; | 14 | jmp_buf die_jmp; |
15 | #endif | ||
14 | 16 | ||
15 | void sleep_and_die(void) | 17 | void xfunc_die(void) |
16 | { | 18 | { |
17 | if (die_sleep) { | 19 | if (die_sleep) { |
18 | /* Special case: don't die, but jump */ | 20 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { |
19 | if (die_sleep < 0) | 21 | /* Special case. We arrive here if NOFORK applet |
20 | longjmp(die_jmp, xfunc_error_retval); | 22 | * calls xfunc, which then decides to die. |
23 | * We don't die, but jump instead back to caller. | ||
24 | * NOFORK applets still cannot carelessly call xfuncs: | ||
25 | * p = xmalloc(10); | ||
26 | * q = xmalloc(10); // BUG! if this dies, we leak p! | ||
27 | */ | ||
28 | /* -111 means "zero" (longjmp can't pass 0) | ||
29 | * spawn_and_wait() catches -111. */ | ||
30 | longjmp(die_jmp, xfunc_error_retval ? xfunc_error_retval : -111); | ||
31 | } | ||
21 | sleep(die_sleep); | 32 | sleep(die_sleep); |
22 | } | 33 | } |
23 | exit(xfunc_error_retval); | 34 | exit(xfunc_error_retval); |
@@ -30,5 +41,5 @@ void bb_error_msg_and_die(const char *s, ...) | |||
30 | va_start(p, s); | 41 | va_start(p, s); |
31 | bb_verror_msg(s, p, NULL); | 42 | bb_verror_msg(s, p, NULL); |
32 | va_end(p); | 43 | va_end(p); |
33 | sleep_and_die(); | 44 | xfunc_die(); |
34 | } | 45 | } |
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c index ae68222b4..d79827f45 100644 --- a/libbb/fflush_stdout_and_exit.c +++ b/libbb/fflush_stdout_and_exit.c | |||
@@ -13,13 +13,17 @@ | |||
13 | 13 | ||
14 | #include "libbb.h" | 14 | #include "libbb.h" |
15 | 15 | ||
16 | // TODO: make it safe to call from NOFORK applets | ||
17 | // Currently, it can exit(0). Even if it is made to do longjmp trick | ||
18 | // (see sleep_and_die internals), zero cannot be passed thru this way! | ||
19 | |||
20 | void fflush_stdout_and_exit(int retval) | 16 | void fflush_stdout_and_exit(int retval) |
21 | { | 17 | { |
22 | if (fflush(stdout)) | 18 | if (fflush(stdout)) |
23 | sleep_and_die(); | 19 | xfunc_die(); |
20 | |||
21 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS && die_sleep < 0) { | ||
22 | /* We are in NOFORK applet. Do not exit() directly, | ||
23 | * but use xfunc_die() */ | ||
24 | xfunc_error_retval = retval; | ||
25 | xfunc_die(); | ||
26 | } | ||
27 | |||
24 | exit(retval); | 28 | exit(retval); |
25 | } | 29 | } |
diff --git a/libbb/herror_msg_and_die.c b/libbb/herror_msg_and_die.c index a7a22caf7..8c77378d7 100644 --- a/libbb/herror_msg_and_die.c +++ b/libbb/herror_msg_and_die.c | |||
@@ -7,9 +7,6 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <stdarg.h> | ||
11 | #include <stdlib.h> | ||
12 | |||
13 | #include "libbb.h" | 10 | #include "libbb.h" |
14 | 11 | ||
15 | void bb_herror_msg_and_die(const char *s, ...) | 12 | void bb_herror_msg_and_die(const char *s, ...) |
@@ -19,5 +16,5 @@ void bb_herror_msg_and_die(const char *s, ...) | |||
19 | va_start(p, s); | 16 | va_start(p, s); |
20 | bb_vherror_msg(s, p); | 17 | bb_vherror_msg(s, p); |
21 | va_end(p); | 18 | va_end(p); |
22 | sleep_and_die(); | 19 | xfunc_die(); |
23 | } | 20 | } |
diff --git a/libbb/perror_msg_and_die.c b/libbb/perror_msg_and_die.c index 7521e7157..3a06b654b 100644 --- a/libbb/perror_msg_and_die.c +++ b/libbb/perror_msg_and_die.c | |||
@@ -7,10 +7,6 @@ | |||
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <stdio.h> | ||
11 | #include <errno.h> | ||
12 | #include <string.h> | ||
13 | #include <stdlib.h> | ||
14 | #include "libbb.h" | 10 | #include "libbb.h" |
15 | 11 | ||
16 | void bb_perror_msg_and_die(const char *s, ...) | 12 | void bb_perror_msg_and_die(const char *s, ...) |
@@ -20,5 +16,5 @@ void bb_perror_msg_and_die(const char *s, ...) | |||
20 | va_start(p, s); | 16 | va_start(p, s); |
21 | bb_vperror_msg(s, p); | 17 | bb_vperror_msg(s, p); |
22 | va_end(p); | 18 | va_end(p); |
23 | sleep_and_die(); | 19 | xfunc_die(); |
24 | } | 20 | } |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 286ee2678..dabd1a6d6 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <paths.h> | 18 | #include <paths.h> |
19 | #include "busybox.h" /* for struct BB_applet */ | 19 | #include "busybox.h" /* for struct bb_applet */ |
20 | 20 | ||
21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, | 21 | /* This does a fork/exec in one call, using vfork(). Returns PID of new child, |
22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ | 22 | * -1 for failure. Runs argv[0], searching path if that has no / in it. */ |
@@ -104,8 +104,9 @@ int spawn_and_wait(char **argv) | |||
104 | { | 104 | { |
105 | int rc; | 105 | int rc; |
106 | 106 | ||
107 | if (ENABLE_FEATURE_EXEC_PREFER_APPLETS) { | 107 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS |
108 | const struct BB_applet *a = find_applet_by_name(argv[0]); | 108 | { |
109 | const struct bb_applet *a = find_applet_by_name(argv[0]); | ||
109 | if (a && (a->nofork | 110 | if (a && (a->nofork |
110 | #ifndef BB_NOMMU | 111 | #ifndef BB_NOMMU |
111 | || a->noexec /* NOEXEC cannot be used on NOMMU */ | 112 | || a->noexec /* NOEXEC cannot be used on NOMMU */ |
@@ -120,19 +121,27 @@ int spawn_and_wait(char **argv) | |||
120 | #endif | 121 | #endif |
121 | { | 122 | { |
122 | int old_sleep = die_sleep; | 123 | int old_sleep = die_sleep; |
124 | int old_x = xfunc_error_retval; | ||
123 | die_sleep = -1; /* special flag */ | 125 | die_sleep = -1; /* special flag */ |
124 | /* sleep_and_die() checks for it */ | 126 | /* xfunc_die() checks for it */ |
127 | |||
125 | rc = setjmp(die_jmp); | 128 | rc = setjmp(die_jmp); |
126 | if (!rc) { | 129 | if (!rc) { |
127 | const struct BB_applet *old_a = current_applet; | 130 | const struct bb_applet *old_a = current_applet; |
128 | current_applet = a; | 131 | current_applet = a; |
129 | applet_name = a->name; | 132 | applet_name = a->name; |
130 | // what else should we save/restore? | 133 | // what else should we save/restore? |
131 | rc = a->main(argc, argv); | 134 | rc = a->main(argc, argv); |
132 | current_applet = old_a; | 135 | current_applet = old_a; |
133 | applet_name = old_a->name; | 136 | applet_name = old_a->name; |
137 | } else { | ||
138 | /* xfunc died in NOFORK applet */ | ||
139 | if (rc == -111) | ||
140 | rc = 0; | ||
134 | } | 141 | } |
142 | |||
135 | die_sleep = old_sleep; | 143 | die_sleep = old_sleep; |
144 | xfunc_error_retval = old_x; | ||
136 | return rc; | 145 | return rc; |
137 | } | 146 | } |
138 | #ifndef BB_NOMMU /* MMU only */ | 147 | #ifndef BB_NOMMU /* MMU only */ |
@@ -145,9 +154,13 @@ int spawn_and_wait(char **argv) | |||
145 | run_current_applet_and_exit(argc, argv); | 154 | run_current_applet_and_exit(argc, argv); |
146 | #endif | 155 | #endif |
147 | } | 156 | } |
157 | |||
148 | } | 158 | } |
149 | rc = spawn(argv); | 159 | rc = spawn(argv); |
150 | w: | 160 | w: |
161 | #else /* !FEATURE_EXEC_PREFER_APPLETS */ | ||
162 | rc = spawn(argv); | ||
163 | #endif /* FEATURE_EXEC_PREFER_APPLETS */ | ||
151 | return wait4pid(rc); | 164 | return wait4pid(rc); |
152 | } | 165 | } |
153 | 166 | ||
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 8466325c7..e7d510678 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -166,7 +166,7 @@ USE_FEATURE_IPV6(sa_family_t af,) | |||
166 | if (rc || !result) { | 166 | if (rc || !result) { |
167 | bb_error_msg("bad address '%s'", org_host); | 167 | bb_error_msg("bad address '%s'", org_host); |
168 | if (ai_flags & DIE_ON_ERROR) | 168 | if (ai_flags & DIE_ON_ERROR) |
169 | sleep_and_die(); | 169 | xfunc_die(); |
170 | goto ret; | 170 | goto ret; |
171 | } | 171 | } |
172 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 172 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); |
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index fa4a15236..b9d013a24 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -476,7 +476,7 @@ void xprint_and_close_file(FILE *file) | |||
476 | fflush(stdout); | 476 | fflush(stdout); |
477 | // copyfd outputs error messages for us. | 477 | // copyfd outputs error messages for us. |
478 | if (bb_copyfd_eof(fileno(file), 1) == -1) | 478 | if (bb_copyfd_eof(fileno(file), 1) == -1) |
479 | sleep_and_die(); | 479 | xfunc_die(); |
480 | 480 | ||
481 | fclose(file); | 481 | fclose(file); |
482 | } | 482 | } |