aboutsummaryrefslogtreecommitdiff
path: root/libbb/vfork_daemon_rexec.c
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 /libbb/vfork_daemon_rexec.c
parentc98c31783c062377d14b80735b056cf4c53c66e9 (diff)
downloadbusybox-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.c32
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