15 |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
* Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
16 |
*/ |
*/ |
17 |
|
|
|
#include <paths.h> |
|
18 |
#include "busybox.h" /* uses applet tables */ |
#include "busybox.h" /* uses applet tables */ |
19 |
|
|
20 |
/* This does a fork/exec in one call, using vfork(). Returns PID of new child, |
/* This does a fork/exec in one call, using vfork(). Returns PID of new child, |
25 |
volatile int failed; |
volatile int failed; |
26 |
pid_t pid; |
pid_t pid; |
27 |
|
|
28 |
// Ain't it a good place to fflush(NULL)? |
fflush_all(); |
29 |
|
|
30 |
/* Be nice to nommu machines. */ |
/* Be nice to nommu machines. */ |
31 |
failed = 0; |
failed = 0; |
41 |
* (but don't run atexit() stuff, which would screw up parent.) |
* (but don't run atexit() stuff, which would screw up parent.) |
42 |
*/ |
*/ |
43 |
failed = errno; |
failed = errno; |
44 |
|
/* mount, for example, does not want the message */ |
45 |
|
/*bb_perror_msg("can't execute '%s'", argv[0]);*/ |
46 |
_exit(111); |
_exit(111); |
47 |
} |
} |
48 |
/* parent */ |
/* parent */ |
252 |
bb_perror_msg_and_die("exec %s", bb_busybox_exec_path); |
bb_perror_msg_and_die("exec %s", bb_busybox_exec_path); |
253 |
} |
} |
254 |
|
|
255 |
void FAST_FUNC forkexit_or_rexec(char **argv) |
pid_t FAST_FUNC fork_or_rexec(char **argv) |
256 |
{ |
{ |
257 |
pid_t pid; |
pid_t pid; |
258 |
/* Maybe we are already re-execed and come here again? */ |
/* Maybe we are already re-execed and come here again? */ |
259 |
if (re_execed) |
if (re_execed) |
260 |
return; |
return 0; |
|
|
|
261 |
pid = vfork(); |
pid = vfork(); |
262 |
if (pid < 0) /* wtf? */ |
if (pid < 0) /* wtf? */ |
263 |
bb_perror_msg_and_die("vfork"); |
bb_perror_msg_and_die("vfork"); |
264 |
if (pid) /* parent */ |
if (pid) /* parent */ |
265 |
exit(EXIT_SUCCESS); |
return pid; |
266 |
/* child - re-exec ourself */ |
/* child - re-exec ourself */ |
267 |
re_exec(argv); |
re_exec(argv); |
268 |
} |
} |
269 |
#else |
#else |
270 |
/* Dance around (void)...*/ |
/* Dance around (void)...*/ |
271 |
#undef forkexit_or_rexec |
#undef fork_or_rexec |
272 |
void FAST_FUNC forkexit_or_rexec(void) |
pid_t FAST_FUNC fork_or_rexec(void) |
273 |
{ |
{ |
274 |
pid_t pid; |
pid_t pid; |
275 |
pid = fork(); |
pid = fork(); |
276 |
if (pid < 0) /* wtf? */ |
if (pid < 0) /* wtf? */ |
277 |
bb_perror_msg_and_die("fork"); |
bb_perror_msg_and_die("fork"); |
278 |
if (pid) /* parent */ |
return pid; |
|
exit(EXIT_SUCCESS); |
|
|
/* child */ |
|
279 |
} |
} |
280 |
#define forkexit_or_rexec(argv) forkexit_or_rexec() |
#define fork_or_rexec(argv) fork_or_rexec() |
281 |
#endif |
#endif |
282 |
|
|
283 |
/* Due to a #define in libbb.h on MMU systems we actually have 1 argument - |
/* Due to a #define in libbb.h on MMU systems we actually have 1 argument - |
308 |
fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ |
fd = dup(fd); /* have 0,1,2 open at least to /dev/null */ |
309 |
|
|
310 |
if (!(flags & DAEMON_ONLY_SANITIZE)) { |
if (!(flags & DAEMON_ONLY_SANITIZE)) { |
311 |
forkexit_or_rexec(argv); |
if (fork_or_rexec(argv)) |
312 |
|
exit(EXIT_SUCCESS); /* parent */ |
313 |
/* if daemonizing, make sure we detach from stdio & ctty */ |
/* if daemonizing, make sure we detach from stdio & ctty */ |
314 |
setsid(); |
setsid(); |
315 |
dup2(fd, 0); |
dup2(fd, 0); |