aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-12 12:27:32 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-12 12:27:32 +0000
commit831a20f51246cd8d54a246ba7e239a062eeb002c (patch)
tree4f3efe440c2db9df016a1aa3dc8d36eb89eb7a2a
parentc98c31783c062377d14b80735b056cf4c53c66e9 (diff)
downloadbusybox-831a20f51246cd8d54a246ba7e239a062eeb002c.tar.gz
pass a copy of argv[i] to NOFORK applets (they may permute it etc).
set/save/restore more shared global variables whan call one applet from another
-rw-r--r--applets/applets.c6
-rw-r--r--libbb/vfork_daemon_rexec.c32
-rw-r--r--shell/hush.c3
-rw-r--r--shell/lash.c26
-rw-r--r--shell/msh.c1
5 files changed, 38 insertions, 30 deletions
diff --git a/applets/applets.c b/applets/applets.c
index bbb545a84..82a7eeea1 100644
--- a/applets/applets.c
+++ b/applets/applets.c
@@ -33,7 +33,7 @@
#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
/* Define usage_messages[] */
-static const char usage_messages[] =
+static const char usage_messages[] = ""
#define MAKE_USAGE
#include "usage.h"
#include "applets.h"
@@ -590,6 +590,10 @@ static int busybox_main(int argc, char **argv)
void run_current_applet_and_exit(int argc, char **argv)
{
+ /* Reinit some shared global data */
+ optind = 1;
+ xfunc_error_retval = EXIT_FAILURE;
+
applet_name = current_applet->name;
if (argc == 2 && !strcmp(argv[1], "--help"))
bb_show_usage();
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index ce5a627ed..7dbc152e2 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -119,11 +119,16 @@ int spawn_and_wait(char **argv)
if (a->nofork)
#endif
{
- int old_sleep = die_sleep;
+ /* Save some shared globals */
+ const struct bb_applet *old_a = current_applet;
int old_x = xfunc_error_retval;
uint32_t old_m = option_mask32;
+ int old_sleep = die_sleep;
+ current_applet = a;
+ applet_name = a->name;
xfunc_error_retval = EXIT_FAILURE;
+ /*option_mask32 = 0; - not needed */
/* special flag for xfunc_die(). If xfunc will "die"
* in NOFORK applet, xfunc_die() sees negative
* die_sleep and longjmp here instead. */
@@ -131,25 +136,24 @@ int spawn_and_wait(char **argv)
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?
-// TODO: what if applet will mangle argv vector?
-// xargs needs argv untouched because it frees argv[i]!
-// 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 */
+ /* Some callers (xargs)
+ * need argv untouched because they free argv[i]! */
+ char *tmp_argv[argc+1];
+ memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
+ /* Finally we can call NOFORK applet's main() */
+ rc = a->main(argc, tmp_argv);
+ } else { /* xfunc died in NOFORK applet */
+ /* in case they meant to return 0... */
if (rc == -111)
rc = 0;
}
- die_sleep = old_sleep;
+ /* Restoring globals */
+ current_applet = old_a;
+ applet_name = old_a->name;
xfunc_error_retval = old_x;
option_mask32 = old_m;
+ die_sleep = old_sleep;
return rc;
}
#if BB_MMU
diff --git a/shell/hush.c b/shell/hush.c
index 1ad61e54e..9af7f5105 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -1119,8 +1119,7 @@ static void pseudo_exec(struct child_prog *child)
/* Count argc for use in a second... */
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
- /**/;
- optind = 1;
+ continue;
debug_printf("running applet %s\n", name);
run_applet_and_exit(name, argc_l, child->argv);
}
diff --git a/shell/lash.c b/shell/lash.c
index c72a65639..5f2dacd18 100644
--- a/shell/lash.c
+++ b/shell/lash.c
@@ -32,6 +32,7 @@
#define ENABLE_LASH_PIPE_N_REDIRECTS 1
#define ENABLE_LASH_JOB_CONTROL 1
+
enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
@@ -310,7 +311,7 @@ static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
const struct built_in_command *x;
printf("\nBuilt-in commands:\n"
- "-------------------\n");
+ "-------------------\n");
for (x = bltins; x->cmd; x++) {
if (x->descr == NULL)
continue;
@@ -408,12 +409,12 @@ static int builtin_read(struct child_prog *child)
** the string resides in a static buffer!)
*/
res = -1;
- if ((s = strdup(string)))
+ s = strdup(string);
+ if (s)
res = putenv(s);
if (res)
bb_perror_msg("read");
- }
- else
+ } else
fgets(string, sizeof(string), stdin);
return res;
@@ -1167,8 +1168,8 @@ static int pseudo_exec(struct child_prog *child)
char **argv_l = child->argv;
int argc_l;
- for (argc_l = 0; *argv_l; argv_l++, argc_l++);
- optind = 1;
+ for (argc_l = 0; *argv_l; argv_l++, argc_l++)
+ continue;
run_applet_and_exit(child->argv[0], argc_l, child->argv);
}
@@ -1234,7 +1235,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
nextin = 0, nextout = 1;
for (i = 0; i < newjob->num_progs; i++) {
- child = & (newjob->progs[i]);
+ child = &(newjob->progs[i]);
if ((i + 1) < newjob->num_progs) {
if (pipe(pipefds) < 0)
@@ -1275,11 +1276,11 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
}
#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
- if (!(child->pid = fork()))
+ child->pid = fork();
#else
- if (!(child->pid = vfork()))
+ child->pid = vfork();
#endif
- {
+ if (!child->pid) {
/* Set the handling for job control signals back to the default. */
signal(SIGINT, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
@@ -1473,8 +1474,9 @@ static void setup_job_control(void)
pid_t shell_pgrp;
/* Loop until we are in the foreground. */
- while ((status = tcgetpgrp (shell_terminal)) >= 0) {
- if (status == (shell_pgrp = getpgrp ())) {
+ while ((status = tcgetpgrp(shell_terminal)) >= 0) {
+ shell_pgrp = getpgrp();
+ if (status == shell_pgrp) {
break;
}
kill(- shell_pgrp, SIGTTIN);
diff --git a/shell/msh.c b/shell/msh.c
index 4d1e84cf0..861abe234 100644
--- a/shell/msh.c
+++ b/shell/msh.c
@@ -3065,7 +3065,6 @@ static const char *rexecve(char *c, char **v, char **envp)
char *name = c;
if (ENABLE_FEATURE_SH_STANDALONE) {
- optind = 1;
if (find_applet_by_name(name)) {
/* We have to exec here since we vforked. Running
* run_applet_and_exit() won't work and bad things