From c6758a07c68033627a692cda27aebc8f6a662e7f Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Tue, 10 Apr 2007 21:40:19 +0000 Subject: make compressed help code NOMMU- and NOFORK-friendly - no forking anymore, bunzip2 unpack routine now does all it in memory. --- libbb/crc32.c | 7 ++- libbb/vfork_daemon_rexec.c | 144 +++++++++++++++------------------------------ libbb/xfuncs.c | 9 +++ 3 files changed, 59 insertions(+), 101 deletions(-) (limited to 'libbb') 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) { -- cgit v1.1