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/vfork_daemon_rexec.c | |
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/vfork_daemon_rexec.c')
-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 |