diff options
author | Peter Korsgaard <jacmet@sunsite.dk> | 2011-11-09 19:44:37 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-11-09 19:44:37 +0100 |
commit | 743edac6c84ac207d0bb4c3124b0e8fe450a38b4 (patch) | |
tree | d74290b238665a3369e191dd85e7a4b38f74aadb | |
parent | 7e21f0491cf3e72835cd9b515734caec56d41e70 (diff) | |
download | busybox-w32-743edac6c84ac207d0bb4c3124b0e8fe450a38b4.tar.gz busybox-w32-743edac6c84ac207d0bb4c3124b0e8fe450a38b4.tar.bz2 busybox-w32-743edac6c84ac207d0bb4c3124b0e8fe450a38b4.zip |
bb_daemonize_or_rexec(): add flag to double-fork; use it in start-stop-daemon
Add a DAEMON_DOUBLE_FORK flag to make bb_daemonize double-fork so it isn't a
session leader, and hence doesn't get a controlling tty on Linux if a tty is
ever opened, similar to how libdaemon's daemon_fork or the big
start-stop-daemon does it - And use it in start-stop-daemon.
For details, see http://www.win.tue.nl/~aeb/linux/lk/lk-10.html#ss10.3
Signed-off-by: Peter Korsgaard <jacmet@sunsite.dk>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | debianutils/start_stop_daemon.c | 2 | ||||
-rw-r--r-- | include/libbb.h | 1 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 10 |
3 files changed, 11 insertions, 2 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 02609c04f..495ed0a09 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -474,7 +474,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
474 | *--argv = startas; | 474 | *--argv = startas; |
475 | if (opt & OPT_BACKGROUND) { | 475 | if (opt & OPT_BACKGROUND) { |
476 | #if BB_MMU | 476 | #if BB_MMU |
477 | bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS); | 477 | bb_daemonize(DAEMON_DEVNULL_STDIO + DAEMON_CLOSE_EXTRA_FDS + DAEMON_DOUBLE_FORK); |
478 | /* DAEMON_DEVNULL_STDIO is superfluous - | 478 | /* DAEMON_DEVNULL_STDIO is superfluous - |
479 | * it's always done by bb_daemonize() */ | 479 | * it's always done by bb_daemonize() */ |
480 | #else | 480 | #else |
diff --git a/include/libbb.h b/include/libbb.h index 53224fa35..09e8d28e7 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -966,6 +966,7 @@ enum { | |||
966 | DAEMON_DEVNULL_STDIO = 2, | 966 | DAEMON_DEVNULL_STDIO = 2, |
967 | DAEMON_CLOSE_EXTRA_FDS = 4, | 967 | DAEMON_CLOSE_EXTRA_FDS = 4, |
968 | DAEMON_ONLY_SANITIZE = 8, /* internal use */ | 968 | DAEMON_ONLY_SANITIZE = 8, /* internal use */ |
969 | DAEMON_DOUBLE_FORK = 16, /* double fork to avoid controlling tty */ | ||
969 | }; | 970 | }; |
970 | #if BB_MMU | 971 | #if BB_MMU |
971 | enum { re_execed = 0 }; | 972 | enum { re_execed = 0 }; |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index a75eafbd3..ed1f86f0c 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -253,11 +253,19 @@ void FAST_FUNC bb_daemonize_or_rexec(int flags, char **argv) | |||
253 | if (!(flags & DAEMON_ONLY_SANITIZE)) { | 253 | if (!(flags & DAEMON_ONLY_SANITIZE)) { |
254 | if (fork_or_rexec(argv)) | 254 | if (fork_or_rexec(argv)) |
255 | exit(EXIT_SUCCESS); /* parent */ | 255 | exit(EXIT_SUCCESS); /* parent */ |
256 | /* if daemonizing, make sure we detach from stdio & ctty */ | 256 | /* if daemonizing, detach from stdio & ctty */ |
257 | setsid(); | 257 | setsid(); |
258 | dup2(fd, 0); | 258 | dup2(fd, 0); |
259 | dup2(fd, 1); | 259 | dup2(fd, 1); |
260 | dup2(fd, 2); | 260 | dup2(fd, 2); |
261 | if (flags & DAEMON_DOUBLE_FORK) { | ||
262 | /* On Linux, session leader can acquire ctty | ||
263 | * unknowingly, by opening a tty. | ||
264 | * Prevent this: stop being a session leader. | ||
265 | */ | ||
266 | if (fork_or_rexec(argv)) | ||
267 | exit(EXIT_SUCCESS); /* parent */ | ||
268 | } | ||
261 | } | 269 | } |
262 | while (fd > 2) { | 270 | while (fd > 2) { |
263 | close(fd--); | 271 | close(fd--); |