aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-09 21:35:07 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-09 21:35:07 +0000
commit3f3aa2a57dc648ade9083f3b3ad83cce8206b912 (patch)
treed5c648f583bb2edef25f05c2bed303df3d1a61f6 /libbb
parentcd7001f7055c3fc2d6298ab9e3befe91e951c652 (diff)
downloadbusybox-3f3aa2a57dc648ade9083f3b3ad83cce8206b912.tar.gz
make xfunctions optionally longjump instead of exit.
use it for making NOFORK more practical. touch: make it a NOFORK applet
Diffstat (limited to 'libbb')
-rw-r--r--libbb/copyfd.c4
-rw-r--r--libbb/error_msg_and_die.c11
-rw-r--r--libbb/getopt32.c1
-rw-r--r--libbb/vfork_daemon_rexec.c25
-rw-r--r--libbb/xfuncs.c2
5 files changed, 31 insertions, 12 deletions
diff --git a/libbb/copyfd.c b/libbb/copyfd.c
index 0d0ec2232..805b80187 100644
--- a/libbb/copyfd.c
+++ b/libbb/copyfd.c
@@ -77,7 +77,7 @@ void complain_copyfd_and_die(off_t sz)
if (sz != -1)
bb_error_msg_and_die("short read");
/* if sz == -1, bb_copyfd_XX already complained */
- exit(xfunc_error_retval);
+ sleep_and_die();
}
#endif
@@ -97,7 +97,7 @@ void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
if (sz != -1)
bb_error_msg_and_die("short read");
/* if sz == -1, bb_copyfd_XX already complained */
- exit(xfunc_error_retval);
+ sleep_and_die();
}
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 7c5a4ebe9..39178a3ce 100644
--- a/libbb/error_msg_and_die.c
+++ b/libbb/error_msg_and_die.c
@@ -7,18 +7,19 @@
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
*/
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
#include "libbb.h"
int die_sleep;
+jmp_buf die_jmp;
void sleep_and_die(void)
{
- if (die_sleep)
+ if (die_sleep) {
+ /* Special case: don't die, but jump */
+ if (die_sleep < 0)
+ longjmp(die_jmp, xfunc_error_retval);
sleep(die_sleep);
+ }
exit(xfunc_error_retval);
}
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index dec97d743..28b47974e 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -457,6 +457,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
/* In case getopt32 was already called, reinit some state */
optind = 1;
+ /* optarg = NULL; opterr = 0; optopt = 0; ?? */
/* Note: just "getopt() <= 0" will not work good for
* "fake" short options, like this one:
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index d25693917..286ee2678 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -115,11 +115,27 @@ int spawn_and_wait(char **argv)
char **pp = argv;
while (*++pp)
argc++;
-#ifdef BB_NOMMU
- return a->main(argc, argv);
-#else
+#ifndef BB_NOMMU
if (a->nofork)
- return a->main(argc, argv);
+#endif
+ {
+ int old_sleep = die_sleep;
+ die_sleep = -1; /* special flag */
+ /* sleep_and_die() checks for it */
+ rc = setjmp(die_jmp);
+ if (!rc) {
+ const struct BB_applet *old_a = current_applet;
+ current_applet = a;
+ applet_name = a->name;
+// what else should we save/restore?
+ rc = a->main(argc, argv);
+ current_applet = old_a;
+ applet_name = old_a->name;
+ }
+ die_sleep = old_sleep;
+ return rc;
+ }
+#ifndef BB_NOMMU /* MMU only */
/* a->noexec is true */
rc = fork();
if (rc)
@@ -135,6 +151,7 @@ int spawn_and_wait(char **argv)
return wait4pid(rc);
}
+
#if 0 //ndef BB_NOMMU
// Die with an error message if we can't daemonize.
void xdaemon(int nochdir, int noclose)
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 0cf2005ac..fa4a15236 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -476,7 +476,7 @@ void xprint_and_close_file(FILE *file)
fflush(stdout);
// copyfd outputs error messages for us.
if (bb_copyfd_eof(fileno(file), 1) == -1)
- exit(xfunc_error_retval);
+ sleep_and_die();
fclose(file);
}