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 /libbb | |
| 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
Diffstat (limited to 'libbb')
| -rw-r--r-- | libbb/vfork_daemon_rexec.c | 32 |
1 files changed, 18 insertions, 14 deletions
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 |
