diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-12 12:27:32 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-12 12:27:32 +0000 |
| commit | 831a20f51246cd8d54a246ba7e239a062eeb002c (patch) | |
| tree | 4f3efe440c2db9df016a1aa3dc8d36eb89eb7a2a | |
| parent | c98c31783c062377d14b80735b056cf4c53c66e9 (diff) | |
| download | busybox-w32-831a20f51246cd8d54a246ba7e239a062eeb002c.tar.gz busybox-w32-831a20f51246cd8d54a246ba7e239a062eeb002c.tar.bz2 busybox-w32-831a20f51246cd8d54a246ba7e239a062eeb002c.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
| -rw-r--r-- | applets/applets.c | 6 | ||||
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 32 | ||||
| -rw-r--r-- | shell/hush.c | 3 | ||||
| -rw-r--r-- | shell/lash.c | 26 | ||||
| -rw-r--r-- | shell/msh.c | 1 |
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[] */ |
| 36 | static const char usage_messages[] = | 36 | static 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 | ||
| 591 | void run_current_applet_and_exit(int argc, char **argv) | 591 | void 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 | |||
| 35 | enum { MAX_READ = 128 }; /* size of input buffer for 'read' builtin */ | 36 | enum { 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 |
