summaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/crc32.c7
-rw-r--r--libbb/vfork_daemon_rexec.c144
-rw-r--r--libbb/xfuncs.c9
3 files changed, 59 insertions, 101 deletions
diff --git a/libbb/crc32.c b/libbb/crc32.c
index 1e4a57e..acbc458 100644
--- a/libbb/crc32.c
+++ b/libbb/crc32.c
@@ -16,14 +16,15 @@
#include "libbb.h"
-uint32_t *crc32_filltable(int endian)
+uint32_t *crc32_filltable(uint32_t *crc_table, int endian)
{
-
- uint32_t *crc_table = xmalloc(256 * sizeof(uint32_t));
uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320;
uint32_t c;
int i, j;
+ if (!crc_table)
+ crc_table = xmalloc(256 * sizeof(uint32_t));
+
for (i = 0; i < 256; i++) {
c = endian ? (i << 24) : i;
for (j = 8; j; j--) {
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index dabd1a6..cf88a2b 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -102,120 +102,68 @@ int wait_pid(int *wstat, int pid)
int spawn_and_wait(char **argv)
{
+#if ENABLE_FEATURE_EXEC_PREFER_APPLETS
int rc;
+ const struct bb_applet *a = find_applet_by_name(argv[0]);
-#if ENABLE_FEATURE_EXEC_PREFER_APPLETS
- {
- const struct bb_applet *a = find_applet_by_name(argv[0]);
- if (a && (a->nofork
+ if (a && (a->nofork
#ifndef BB_NOMMU
- || a->noexec /* NOEXEC cannot be used on NOMMU */
+ || a->noexec /* NOEXEC cannot be used on NOMMU */
#endif
- )) {
- int argc = 1;
- char **pp = argv;
- while (*++pp)
- argc++;
+ )) {
+ int argc = 1;
+ char **pp = argv;
+ while (*++pp)
+ argc++;
#ifndef BB_NOMMU
- if (a->nofork)
+ if (a->nofork)
#endif
- {
- int old_sleep = die_sleep;
- int old_x = xfunc_error_retval;
- die_sleep = -1; /* special flag */
- /* xfunc_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;
+ {
+ int old_sleep = die_sleep;
+ int old_x = xfunc_error_retval;
+ die_sleep = -1; /* special flag */
+ /* xfunc_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;
- } else {
- /* xfunc died in NOFORK applet */
- if (rc == -111)
- rc = 0;
- }
-
- die_sleep = old_sleep;
- xfunc_error_retval = old_x;
- return rc;
+// TODO: what if applet will mangle argv vector?
+// xargs needs argv untouched because it frees the vector!
+// shouldn't we pass a copy?
+ rc = a->main(argc, argv);
+ current_applet = old_a;
+ applet_name = old_a->name;
+ } else {
+ /* xfunc died in NOFORK applet */
+ if (rc == -111)
+ rc = 0;
}
+
+ die_sleep = old_sleep;
+ xfunc_error_retval = old_x;
+ return rc;
+ }
#ifndef BB_NOMMU /* MMU only */
- /* a->noexec is true */
- rc = fork();
- if (rc)
- goto w;
- /* child */
- current_applet = a;
- run_current_applet_and_exit(argc, argv);
+ /* a->noexec is true */
+ rc = fork();
+ if (rc)
+ goto w;
+ /* child */
+ current_applet = a;
+ run_current_applet_and_exit(argc, argv);
#endif
- }
-
}
rc = spawn(argv);
w:
-#else /* !FEATURE_EXEC_PREFER_APPLETS */
- rc = spawn(argv);
-#endif /* FEATURE_EXEC_PREFER_APPLETS */
return wait4pid(rc);
-}
-
-
-#if 0 //ndef BB_NOMMU
-// Die with an error message if we can't daemonize.
-void xdaemon(int nochdir, int noclose)
-{
- if (daemon(nochdir, noclose))
- bb_perror_msg_and_die("daemon");
-}
+#else /* !FEATURE_EXEC_PREFER_APPLETS */
+ return wait4pid(spawn(argv));
#endif
-
-#if 0 // def BB_NOMMU
-void vfork_daemon_rexec(int nochdir, int noclose, char **argv)
-{
- int fd;
-
- /* Maybe we are already re-execed and come here again? */
- if (re_execed)
- return;
-
- setsid();
-
- if (!nochdir)
- xchdir("/");
-
- if (!noclose) {
- /* if "/dev/null" doesn't exist, bail out! */
- fd = xopen(bb_dev_null, O_RDWR);
- dup2(fd, STDIN_FILENO);
- dup2(fd, STDOUT_FILENO);
- dup2(fd, STDERR_FILENO);
- while (fd > 2)
- close(fd--);
- }
-
- switch (vfork()) {
- case 0: /* child */
- /* Make certain we are not a session leader, or else we
- * might reacquire a controlling terminal */
- if (vfork())
- _exit(0);
- /* High-order bit of first char in argv[0] is a hidden
- * "we have (alrealy) re-execed, don't do it again" flag */
- argv[0][0] |= 0x80;
- execv(CONFIG_BUSYBOX_EXEC_PATH, argv);
- bb_perror_msg_and_die("exec %s", CONFIG_BUSYBOX_EXEC_PATH);
- case -1: /* error */
- bb_perror_msg_and_die("vfork");
- default: /* parent */
- exit(0);
- }
}
-#endif /* BB_NOMMU */
+
#ifdef BB_NOMMU
void forkexit_or_rexec(char **argv)
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index b9d013a..dde91a2 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -20,6 +20,15 @@
* Since dmalloc's prototypes overwrite the impls here as they are
* included after these prototypes in libbb.h, all is well.
*/
+// Warn if we can't allocate size bytes of memory.
+void *malloc_or_warn(size_t size)
+{
+ void *ptr = malloc(size);
+ if (ptr == NULL && size != 0)
+ bb_error_msg(bb_msg_memory_exhausted);
+ return ptr;
+}
+
// Die if we can't allocate size bytes of memory.
void *xmalloc(size_t size)
{