diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:40:19 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-10 21:40:19 +0000 |
commit | c6758a07c68033627a692cda27aebc8f6a662e7f (patch) | |
tree | 51bc0b498a5e16f8041604d913e25708cc76058f /libbb/vfork_daemon_rexec.c | |
parent | 335b63d8d1876ce4e172ebcc9d64544785682244 (diff) | |
download | busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.gz busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.tar.bz2 busybox-w32-c6758a07c68033627a692cda27aebc8f6a662e7f.zip |
make compressed help code NOMMU- and NOFORK-friendly -
no forking anymore, bunzip2 unpack routine now does all it in memory.
Diffstat (limited to 'libbb/vfork_daemon_rexec.c')
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 144 |
1 files changed, 46 insertions, 98 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index dabd1a6d6..cf88a2b28 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -102,120 +102,68 @@ int wait_pid(int *wstat, int pid) | |||
102 | 102 | ||
103 | int spawn_and_wait(char **argv) | 103 | int spawn_and_wait(char **argv) |
104 | { | 104 | { |
105 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS | ||
105 | int rc; | 106 | int rc; |
107 | const struct bb_applet *a = find_applet_by_name(argv[0]); | ||
106 | 108 | ||
107 | #if ENABLE_FEATURE_EXEC_PREFER_APPLETS | 109 | if (a && (a->nofork |
108 | { | ||
109 | const struct bb_applet *a = find_applet_by_name(argv[0]); | ||
110 | if (a && (a->nofork | ||
111 | #ifndef BB_NOMMU | 110 | #ifndef BB_NOMMU |
112 | || a->noexec /* NOEXEC cannot be used on NOMMU */ | 111 | || a->noexec /* NOEXEC cannot be used on NOMMU */ |
113 | #endif | 112 | #endif |
114 | )) { | 113 | )) { |
115 | int argc = 1; | 114 | int argc = 1; |
116 | char **pp = argv; | 115 | char **pp = argv; |
117 | while (*++pp) | 116 | while (*++pp) |
118 | argc++; | 117 | argc++; |
119 | #ifndef BB_NOMMU | 118 | #ifndef BB_NOMMU |
120 | if (a->nofork) | 119 | if (a->nofork) |
121 | #endif | 120 | #endif |
122 | { | 121 | { |
123 | int old_sleep = die_sleep; | 122 | int old_sleep = die_sleep; |
124 | int old_x = xfunc_error_retval; | 123 | int old_x = xfunc_error_retval; |
125 | die_sleep = -1; /* special flag */ | 124 | die_sleep = -1; /* special flag */ |
126 | /* xfunc_die() checks for it */ | 125 | /* xfunc_die() checks for it */ |
127 | 126 | ||
128 | rc = setjmp(die_jmp); | 127 | rc = setjmp(die_jmp); |
129 | if (!rc) { | 128 | if (!rc) { |
130 | const struct bb_applet *old_a = current_applet; | 129 | const struct bb_applet *old_a = current_applet; |
131 | current_applet = a; | 130 | current_applet = a; |
132 | applet_name = a->name; | 131 | applet_name = a->name; |
133 | // what else should we save/restore? | 132 | // what else should we save/restore? |
134 | rc = a->main(argc, argv); | 133 | // TODO: what if applet will mangle argv vector? |
135 | current_applet = old_a; | 134 | // xargs needs argv untouched because it frees the vector! |
136 | applet_name = old_a->name; | 135 | // shouldn't we pass a copy? |
137 | } else { | 136 | rc = a->main(argc, argv); |
138 | /* xfunc died in NOFORK applet */ | 137 | current_applet = old_a; |
139 | if (rc == -111) | 138 | applet_name = old_a->name; |
140 | rc = 0; | 139 | } else { |
141 | } | 140 | /* xfunc died in NOFORK applet */ |
142 | 141 | if (rc == -111) | |
143 | die_sleep = old_sleep; | 142 | rc = 0; |
144 | xfunc_error_retval = old_x; | ||
145 | return rc; | ||
146 | } | 143 | } |
144 | |||
145 | die_sleep = old_sleep; | ||
146 | xfunc_error_retval = old_x; | ||
147 | return rc; | ||
148 | } | ||
147 | #ifndef BB_NOMMU /* MMU only */ | 149 | #ifndef BB_NOMMU /* MMU only */ |
148 | /* a->noexec is true */ | 150 | /* a->noexec is true */ |
149 | rc = fork(); | 151 | rc = fork(); |
150 | if (rc) | 152 | if (rc) |
151 | goto w; | 153 | goto w; |
152 | /* child */ | 154 | /* child */ |
153 | current_applet = a; | 155 | current_applet = a; |
154 | run_current_applet_and_exit(argc, argv); | 156 | run_current_applet_and_exit(argc, argv); |
155 | #endif | 157 | #endif |
156 | } | ||
157 | |||
158 | } | 158 | } |
159 | rc = spawn(argv); | 159 | rc = spawn(argv); |
160 | w: | 160 | w: |
161 | #else /* !FEATURE_EXEC_PREFER_APPLETS */ | ||
162 | rc = spawn(argv); | ||
163 | #endif /* FEATURE_EXEC_PREFER_APPLETS */ | ||
164 | return wait4pid(rc); | 161 | return wait4pid(rc); |
165 | } | 162 | #else /* !FEATURE_EXEC_PREFER_APPLETS */ |
166 | 163 | return wait4pid(spawn(argv)); | |
167 | |||
168 | #if 0 //ndef BB_NOMMU | ||
169 | // Die with an error message if we can't daemonize. | ||
170 | void xdaemon(int nochdir, int noclose) | ||
171 | { | ||
172 | if (daemon(nochdir, noclose)) | ||
173 | bb_perror_msg_and_die("daemon"); | ||
174 | } | ||
175 | #endif | 164 | #endif |
176 | |||
177 | #if 0 // def BB_NOMMU | ||
178 | void vfork_daemon_rexec(int nochdir, int noclose, char **argv) | ||
179 | { | ||
180 | int fd; | ||
181 | |||
182 | /* Maybe we are already re-execed and come here again? */ | ||
183 | if (re_execed) | ||
184 | return; | ||
185 | |||
186 | setsid(); | ||
187 | |||
188 | if (!nochdir) | ||
189 | xchdir("/"); | ||
190 | |||
191 | if (!noclose) { | ||
192 | /* if "/dev/null" doesn't exist, bail out! */ | ||
193 | fd = xopen(bb_dev_null, O_RDWR); | ||
194 | dup2(fd, STDIN_FILENO); | ||
195 | dup2(fd, STDOUT_FILENO); | ||
196 | dup2(fd, STDERR_FILENO); | ||
197 | while (fd > 2) | ||
198 | close(fd--); | ||
199 | } | ||
200 | |||
201 | switch (vfork()) { | ||
202 | case 0: /* child */ | ||
203 | /* Make certain we are not a session leader, or else we | ||
204 | * might reacquire a controlling terminal */ | ||
205 | if (vfork()) | ||
206 | _exit(0); | ||
207 | /* High-order bit of first char in argv[0] is a hidden | ||
208 | * "we have (alrealy) re-execed, don't do it again" flag */ | ||
209 | argv[0][0] |= 0x80; | ||
210 | execv(CONFIG_BUSYBOX_EXEC_PATH, argv); | ||
211 | bb_perror_msg_and_die("exec %s", CONFIG_BUSYBOX_EXEC_PATH); | ||
212 | case -1: /* error */ | ||
213 | bb_perror_msg_and_die("vfork"); | ||
214 | default: /* parent */ | ||
215 | exit(0); | ||
216 | } | ||
217 | } | 165 | } |
218 | #endif /* BB_NOMMU */ | 166 | |
219 | 167 | ||
220 | #ifdef BB_NOMMU | 168 | #ifdef BB_NOMMU |
221 | void forkexit_or_rexec(char **argv) | 169 | void forkexit_or_rexec(char **argv) |