aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:38:30 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-10 21:38:30 +0000
commit335b63d8d1876ce4e172ebcc9d64544785682244 (patch)
tree14183fd728ce51ae10baee70f7d8f72c39d30649 /libbb
parent07c394e69b0cfa7cd30e97ffc6edb0d857905f45 (diff)
downloadbusybox-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.c4
-rw-r--r--libbb/error_msg_and_die.c21
-rw-r--r--libbb/fflush_stdout_and_exit.c14
-rw-r--r--libbb/herror_msg_and_die.c5
-rw-r--r--libbb/perror_msg_and_die.c6
-rw-r--r--libbb/vfork_daemon_rexec.c23
-rw-r--r--libbb/xconnect.c2
-rw-r--r--libbb/xfuncs.c2
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
100off_t bb_copyfd_eof(int fd1, int fd2) 100off_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
12int die_sleep; 12int die_sleep;
13#if ENABLE_FEATURE_EXEC_PREFER_APPLETS
13jmp_buf die_jmp; 14jmp_buf die_jmp;
15#endif
14 16
15void sleep_and_die(void) 17void 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
20void fflush_stdout_and_exit(int retval) 16void 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
15void bb_herror_msg_and_die(const char *s, ...) 12void 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
16void bb_perror_msg_and_die(const char *s, ...) 12void 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}