make xfunctions optionally longjump instead of exit.
use it for making NOFORK more practical. touch: make it a NOFORK applet
This commit is contained in:
parent
cd7001f705
commit
3f3aa2a57d
@ -462,7 +462,7 @@ void bb_show_usage(void)
|
|||||||
applet_name, usage_string);
|
applet_name, usage_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(xfunc_error_retval);
|
sleep_and_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ static FILE *cmp_xfopen_input(const char * const filename)
|
|||||||
fp = fopen_or_warn_stdin(filename);
|
fp = fopen_or_warn_stdin(filename);
|
||||||
if (fp)
|
if (fp)
|
||||||
return fp;
|
return fp;
|
||||||
exit(xfunc_error_retval); /* We already output an error message. */
|
sleep_and_die(); /* We already output an error message. */
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char fmt_eof[] = "cmp: EOF on %s\n";
|
static const char fmt_eof[] = "cmp: EOF on %s\n";
|
||||||
|
@ -17,21 +17,16 @@
|
|||||||
* Also, exiting on a failure was a bug. All args should be processed.
|
* Also, exiting on a failure was a bug. All args should be processed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <utime.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "busybox.h"
|
#include "busybox.h"
|
||||||
|
|
||||||
|
/* This is a NOFORK applet. Be very careful! */
|
||||||
|
|
||||||
int touch_main(int argc, char **argv);
|
int touch_main(int argc, char **argv);
|
||||||
int touch_main(int argc, char **argv)
|
int touch_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int status = EXIT_SUCCESS;
|
int status = EXIT_SUCCESS;
|
||||||
bool flags = (getopt32(argc, argv, "c") & 1);
|
int flags = getopt32(argc, argv, "c");
|
||||||
|
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
@ -41,7 +36,7 @@ int touch_main(int argc, char **argv)
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
if (utime(*argv, NULL)) {
|
if (utime(*argv, NULL)) {
|
||||||
if (errno == ENOENT) { /* no such file*/
|
if (errno == ENOENT) { /* no such file */
|
||||||
if (flags) { /* Creation is disabled, so ignore. */
|
if (flags) { /* Creation is disabled, so ignore. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,7 @@ USE_TFTP(APPLET(tftp, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
|||||||
#endif
|
#endif
|
||||||
USE_TIME(APPLET(time, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
USE_TIME(APPLET(time, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
||||||
USE_TOP(APPLET(top, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
USE_TOP(APPLET(top, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
||||||
USE_TOUCH(APPLET_NOEXEC(touch, touch, _BB_DIR_BIN, _BB_SUID_NEVER, touch))
|
USE_TOUCH(APPLET_NOFORK(touch, touch, _BB_DIR_BIN, _BB_SUID_NEVER, touch))
|
||||||
USE_TR(APPLET(tr, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
USE_TR(APPLET(tr, _BB_DIR_USR_BIN, _BB_SUID_NEVER))
|
||||||
USE_TRACEROUTE(APPLET(traceroute, _BB_DIR_USR_BIN, _BB_SUID_MAYBE))
|
USE_TRACEROUTE(APPLET(traceroute, _BB_DIR_USR_BIN, _BB_SUID_MAYBE))
|
||||||
USE_TRUE(APPLET(true, _BB_DIR_BIN, _BB_SUID_NEVER))
|
USE_TRUE(APPLET(true, _BB_DIR_BIN, _BB_SUID_NEVER))
|
||||||
|
@ -620,6 +620,7 @@ extern const char *msg_eol;
|
|||||||
extern smallint logmode;
|
extern smallint logmode;
|
||||||
extern int die_sleep;
|
extern int die_sleep;
|
||||||
extern int xfunc_error_retval;
|
extern int xfunc_error_retval;
|
||||||
|
extern jmp_buf die_jmp;
|
||||||
extern void sleep_and_die(void) ATTRIBUTE_NORETURN;
|
extern void sleep_and_die(void) ATTRIBUTE_NORETURN;
|
||||||
extern void bb_show_usage(void) ATTRIBUTE_NORETURN ATTRIBUTE_EXTERNALLY_VISIBLE;
|
extern void bb_show_usage(void) ATTRIBUTE_NORETURN ATTRIBUTE_EXTERNALLY_VISIBLE;
|
||||||
extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
|
extern void bb_error_msg(const char *s, ...) __attribute__ ((format (printf, 1, 2)));
|
||||||
|
@ -77,7 +77,7 @@ void complain_copyfd_and_die(off_t sz)
|
|||||||
if (sz != -1)
|
if (sz != -1)
|
||||||
bb_error_msg_and_die("short read");
|
bb_error_msg_and_die("short read");
|
||||||
/* if sz == -1, bb_copyfd_XX already complained */
|
/* if sz == -1, bb_copyfd_XX already complained */
|
||||||
exit(xfunc_error_retval);
|
sleep_and_die();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ void bb_copyfd_exact_size(int fd1, int fd2, off_t size)
|
|||||||
if (sz != -1)
|
if (sz != -1)
|
||||||
bb_error_msg_and_die("short read");
|
bb_error_msg_and_die("short read");
|
||||||
/* if sz == -1, bb_copyfd_XX already complained */
|
/* if sz == -1, bb_copyfd_XX already complained */
|
||||||
exit(xfunc_error_retval);
|
sleep_and_die();
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t bb_copyfd_eof(int fd1, int fd2)
|
off_t bb_copyfd_eof(int fd1, int fd2)
|
||||||
|
@ -7,18 +7,19 @@
|
|||||||
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
|
* 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"
|
#include "libbb.h"
|
||||||
|
|
||||||
int die_sleep;
|
int die_sleep;
|
||||||
|
jmp_buf die_jmp;
|
||||||
|
|
||||||
void sleep_and_die(void)
|
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);
|
sleep(die_sleep);
|
||||||
|
}
|
||||||
exit(xfunc_error_retval);
|
exit(xfunc_error_retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,6 +457,7 @@ getopt32(int argc, char **argv, const char *applet_opts, ...)
|
|||||||
|
|
||||||
/* In case getopt32 was already called, reinit some state */
|
/* In case getopt32 was already called, reinit some state */
|
||||||
optind = 1;
|
optind = 1;
|
||||||
|
/* optarg = NULL; opterr = 0; optopt = 0; ?? */
|
||||||
|
|
||||||
/* Note: just "getopt() <= 0" will not work good for
|
/* Note: just "getopt() <= 0" will not work good for
|
||||||
* "fake" short options, like this one:
|
* "fake" short options, like this one:
|
||||||
|
@ -115,11 +115,27 @@ int spawn_and_wait(char **argv)
|
|||||||
char **pp = argv;
|
char **pp = argv;
|
||||||
while (*++pp)
|
while (*++pp)
|
||||||
argc++;
|
argc++;
|
||||||
#ifdef BB_NOMMU
|
#ifndef BB_NOMMU
|
||||||
return a->main(argc, argv);
|
|
||||||
#else
|
|
||||||
if (a->nofork)
|
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 */
|
/* a->noexec is true */
|
||||||
rc = fork();
|
rc = fork();
|
||||||
if (rc)
|
if (rc)
|
||||||
@ -135,6 +151,7 @@ int spawn_and_wait(char **argv)
|
|||||||
return wait4pid(rc);
|
return wait4pid(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if 0 //ndef BB_NOMMU
|
#if 0 //ndef BB_NOMMU
|
||||||
// Die with an error message if we can't daemonize.
|
// Die with an error message if we can't daemonize.
|
||||||
void xdaemon(int nochdir, int noclose)
|
void xdaemon(int nochdir, int noclose)
|
||||||
|
@ -476,7 +476,7 @@ void xprint_and_close_file(FILE *file)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
// copyfd outputs error messages for us.
|
// copyfd outputs error messages for us.
|
||||||
if (bb_copyfd_eof(fileno(file), 1) == -1)
|
if (bb_copyfd_eof(fileno(file), 1) == -1)
|
||||||
exit(xfunc_error_retval);
|
sleep_and_die();
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user