aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-12 12:27:32 +0000
committervda <vda@69ca8d6d-28ef-0310-b511-8ec308f3f277>2007-04-12 12:27:32 +0000
commit5ce9987c2025ffb8eb0b57fed05744f9d94e9111 (patch)
tree4f3efe440c2db9df016a1aa3dc8d36eb89eb7a2a
parent9befed76909bfe7cbda8fdf154c1a10a12e88006 (diff)
downloadbusybox-w32-5ce9987c2025ffb8eb0b57fed05744f9d94e9111.tar.gz
busybox-w32-5ce9987c2025ffb8eb0b57fed05744f9d94e9111.tar.bz2
busybox-w32-5ce9987c2025ffb8eb0b57fed05744f9d94e9111.zip
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 git-svn-id: svn://busybox.net/trunk/busybox@18415 69ca8d6d-28ef-0310-b511-8ec308f3f277
-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 @@
33 33
34#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE 34#if ENABLE_SHOW_USAGE && !ENABLE_FEATURE_COMPRESS_USAGE
35/* Define usage_messages[] */ 35/* Define usage_messages[] */
36static const char usage_messages[] = 36static const char usage_messages[] = ""
37#define MAKE_USAGE 37#define MAKE_USAGE
38#include "usage.h" 38#include "usage.h"
39#include "applets.h" 39#include "applets.h"
@@ -590,6 +590,10 @@ static int busybox_main(int argc, char **argv)
590 590
591void run_current_applet_and_exit(int argc, char **argv) 591void run_current_applet_and_exit(int argc, char **argv)
592{ 592{
593 /* Reinit some shared global data */
594 optind = 1;
595 xfunc_error_retval = EXIT_FAILURE;
596
593 applet_name = current_applet->name; 597 applet_name = current_applet->name;
594 if (argc == 2 && !strcmp(argv[1], "--help")) 598 if (argc == 2 && !strcmp(argv[1], "--help"))
595 bb_show_usage(); 599 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)
119 if (a->nofork) 119 if (a->nofork)
120#endif 120#endif
121 { 121 {
122 int old_sleep = die_sleep; 122 /* Save some shared globals */
123 const struct bb_applet *old_a = current_applet;
123 int old_x = xfunc_error_retval; 124 int old_x = xfunc_error_retval;
124 uint32_t old_m = option_mask32; 125 uint32_t old_m = option_mask32;
126 int old_sleep = die_sleep;
125 127
128 current_applet = a;
129 applet_name = a->name;
126 xfunc_error_retval = EXIT_FAILURE; 130 xfunc_error_retval = EXIT_FAILURE;
131 /*option_mask32 = 0; - not needed */
127 /* special flag for xfunc_die(). If xfunc will "die" 132 /* special flag for xfunc_die(). If xfunc will "die"
128 * in NOFORK applet, xfunc_die() sees negative 133 * in NOFORK applet, xfunc_die() sees negative
129 * die_sleep and longjmp here instead. */ 134 * die_sleep and longjmp here instead. */
@@ -131,25 +136,24 @@ int spawn_and_wait(char **argv)
131 136
132 rc = setjmp(die_jmp); 137 rc = setjmp(die_jmp);
133 if (!rc) { 138 if (!rc) {
134 const struct bb_applet *old_a = current_applet; 139 /* Some callers (xargs)
135 current_applet = a; 140 * need argv untouched because they free argv[i]! */
136 applet_name = a->name; 141 char *tmp_argv[argc+1];
137// what else should we save/restore? 142 memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0]));
138// TODO: what if applet will mangle argv vector? 143 /* Finally we can call NOFORK applet's main() */
139// xargs needs argv untouched because it frees argv[i]! 144 rc = a->main(argc, tmp_argv);
140// shouldn't we pass a copy? 145 } else { /* xfunc died in NOFORK applet */
141 rc = a->main(argc, argv); 146 /* in case they meant to return 0... */
142 current_applet = old_a;
143 applet_name = old_a->name;
144 } else {
145 /* xfunc died in NOFORK applet */
146 if (rc == -111) 147 if (rc == -111)
147 rc = 0; 148 rc = 0;
148 } 149 }
149 150
150 die_sleep = old_sleep; 151 /* Restoring globals */
152 current_applet = old_a;
153 applet_name = old_a->name;
151 xfunc_error_retval = old_x; 154 xfunc_error_retval = old_x;
152 option_mask32 = old_m; 155 option_mask32 = old_m;
156 die_sleep = old_sleep;
153 return rc; 157 return rc;
154 } 158 }
155#if BB_MMU 159#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)
1119 1119
1120 /* Count argc for use in a second... */ 1120 /* Count argc for use in a second... */
1121 for (argc_l = 0; *argv_l; argv_l++, argc_l++) 1121 for (argc_l = 0; *argv_l; argv_l++, argc_l++)
1122 /**/; 1122 continue;
1123 optind = 1;
1124 debug_printf("running applet %s\n", name); 1123 debug_printf("running applet %s\n", name);
1125 run_applet_and_exit(name, argc_l, child->argv); 1124 run_applet_and_exit(name, argc_l, child->argv);
1126 } 1125 }
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 @@
32#define ENABLE_LASH_PIPE_N_REDIRECTS 1 32#define ENABLE_LASH_PIPE_N_REDIRECTS 1
33#define ENABLE_LASH_JOB_CONTROL 1 33#define ENABLE_LASH_JOB_CONTROL 1
34 34
35
35enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */ 36enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */
36#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n" 37#define JOB_STATUS_FORMAT "[%d] %-22s %.40s\n"
37 38
@@ -310,7 +311,7 @@ static int builtin_help(struct child_prog ATTRIBUTE_UNUSED *dummy)
310 const struct built_in_command *x; 311 const struct built_in_command *x;
311 312
312 printf("\nBuilt-in commands:\n" 313 printf("\nBuilt-in commands:\n"
313 "-------------------\n"); 314 "-------------------\n");
314 for (x = bltins; x->cmd; x++) { 315 for (x = bltins; x->cmd; x++) {
315 if (x->descr == NULL) 316 if (x->descr == NULL)
316 continue; 317 continue;
@@ -408,12 +409,12 @@ static int builtin_read(struct child_prog *child)
408 ** the string resides in a static buffer!) 409 ** the string resides in a static buffer!)
409 */ 410 */
410 res = -1; 411 res = -1;
411 if ((s = strdup(string))) 412 s = strdup(string);
413 if (s)
412 res = putenv(s); 414 res = putenv(s);
413 if (res) 415 if (res)
414 bb_perror_msg("read"); 416 bb_perror_msg("read");
415 } 417 } else
416 else
417 fgets(string, sizeof(string), stdin); 418 fgets(string, sizeof(string), stdin);
418 419
419 return res; 420 return res;
@@ -1167,8 +1168,8 @@ static int pseudo_exec(struct child_prog *child)
1167 char **argv_l = child->argv; 1168 char **argv_l = child->argv;
1168 int argc_l; 1169 int argc_l;
1169 1170
1170 for (argc_l = 0; *argv_l; argv_l++, argc_l++); 1171 for (argc_l = 0; *argv_l; argv_l++, argc_l++)
1171 optind = 1; 1172 continue;
1172 run_applet_and_exit(child->argv[0], argc_l, child->argv); 1173 run_applet_and_exit(child->argv[0], argc_l, child->argv);
1173 } 1174 }
1174 1175
@@ -1234,7 +1235,7 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1234 1235
1235 nextin = 0, nextout = 1; 1236 nextin = 0, nextout = 1;
1236 for (i = 0; i < newjob->num_progs; i++) { 1237 for (i = 0; i < newjob->num_progs; i++) {
1237 child = & (newjob->progs[i]); 1238 child = &(newjob->progs[i]);
1238 1239
1239 if ((i + 1) < newjob->num_progs) { 1240 if ((i + 1) < newjob->num_progs) {
1240 if (pipe(pipefds) < 0) 1241 if (pipe(pipefds) < 0)
@@ -1275,11 +1276,11 @@ static int run_command(struct job *newjob, int inbg, int outpipe[2])
1275 } 1276 }
1276 1277
1277#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__) 1278#if !defined(__UCLIBC__) || defined(__ARCH_HAS_MMU__)
1278 if (!(child->pid = fork())) 1279 child->pid = fork();
1279#else 1280#else
1280 if (!(child->pid = vfork())) 1281 child->pid = vfork();
1281#endif 1282#endif
1282 { 1283 if (!child->pid) {
1283 /* Set the handling for job control signals back to the default. */ 1284 /* Set the handling for job control signals back to the default. */
1284 signal(SIGINT, SIG_DFL); 1285 signal(SIGINT, SIG_DFL);
1285 signal(SIGQUIT, SIG_DFL); 1286 signal(SIGQUIT, SIG_DFL);
@@ -1473,8 +1474,9 @@ static void setup_job_control(void)
1473 pid_t shell_pgrp; 1474 pid_t shell_pgrp;
1474 1475
1475 /* Loop until we are in the foreground. */ 1476 /* Loop until we are in the foreground. */
1476 while ((status = tcgetpgrp (shell_terminal)) >= 0) { 1477 while ((status = tcgetpgrp(shell_terminal)) >= 0) {
1477 if (status == (shell_pgrp = getpgrp ())) { 1478 shell_pgrp = getpgrp();
1479 if (status == shell_pgrp) {
1478 break; 1480 break;
1479 } 1481 }
1480 kill(- shell_pgrp, SIGTTIN); 1482 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)
3065 char *name = c; 3065 char *name = c;
3066 3066
3067 if (ENABLE_FEATURE_SH_STANDALONE) { 3067 if (ENABLE_FEATURE_SH_STANDALONE) {
3068 optind = 1;
3069 if (find_applet_by_name(name)) { 3068 if (find_applet_by_name(name)) {
3070 /* We have to exec here since we vforked. Running 3069 /* We have to exec here since we vforked. Running
3071 * run_applet_and_exit() won't work and bad things 3070 * run_applet_and_exit() won't work and bad things