runsvdir: do not exit if we are pid 1.

This commit is contained in:
Denis Vlasenko 2008-10-29 03:42:44 +00:00
parent 40fdcbb270
commit 9657596dd6

View File

@ -115,10 +115,16 @@ static void runsv(int no, const char *name)
/* child */ /* child */
if (set_pgrp) if (set_pgrp)
setsid(); setsid();
/* man execv:
* Signals set to be caught by the calling process image
* shall be set to the default action in the new process image.
* Therefore, we do not need this: */
#if 0
bb_signals(0 bb_signals(0
+ (1 << SIGHUP) | (1 << SIGHUP)
+ (1 << SIGTERM) | (1 << SIGTERM)
, SIG_DFL); , SIG_DFL);
#endif
execvp(prog[0], prog); execvp(prog[0], prog);
fatal2_cannot("start runsv ", name); fatal2_cannot("start runsv ", name);
} }
@ -227,7 +233,19 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
set_pgrp = getopt32(argv, "P"); set_pgrp = getopt32(argv, "P");
argv += optind; argv += optind;
bb_signals_recursive((1 << SIGTERM) | (1 << SIGHUP), record_signo); bb_signals(0
| (1 << SIGTERM)
| (1 << SIGHUP)
/* For busybox's init, SIGTERM == reboot,
* SIGUSR1 == halt
* SIGUSR2 == poweroff
* so we need to intercept SIGUSRn too.
* Note that we do not implement actual reboot
* (killall(TERM) + umount, etc), we just pause
* respawing and avoid exiting (-> making kernel oops).
* The user is responsible for the rest. */
| (getpid() == 1 ? ((1 << SIGUSR1) | (1 << SIGUSR2)) : 0)
, record_signo);
svdir = *argv++; svdir = *argv++;
#if ENABLE_FEATURE_RUNSVDIR_LOG #if ENABLE_FEATURE_RUNSVDIR_LOG
@ -256,7 +274,7 @@ int runsvdir_main(int argc UNUSED_PARAM, char **argv)
rplog = NULL; rplog = NULL;
warnx("log service disabled"); warnx("log service disabled");
} }
run: run:
#endif #endif
curdir = open_read("."); curdir = open_read(".");
if (curdir == -1) if (curdir == -1)
@ -319,8 +337,9 @@ run:
} }
pfd[0].revents = 0; pfd[0].revents = 0;
#endif #endif
sig_block(SIGCHLD);
deadline = (need_rescan ? 1 : 5); deadline = (need_rescan ? 1 : 5);
do_sleep:
sig_block(SIGCHLD);
#if ENABLE_FEATURE_RUNSVDIR_LOG #if ENABLE_FEATURE_RUNSVDIR_LOG
if (rplog) if (rplog)
poll(pfd, 1, deadline*1000); poll(pfd, 1, deadline*1000);
@ -333,24 +352,32 @@ run:
if (pfd[0].revents & POLLIN) { if (pfd[0].revents & POLLIN) {
char ch; char ch;
while (read(logpipe.rd, &ch, 1) > 0) { while (read(logpipe.rd, &ch, 1) > 0) {
if (ch) { if (ch < ' ')
ch = ' ';
for (i = 6; i < rploglen; i++) for (i = 6; i < rploglen; i++)
rplog[i-1] = rplog[i]; rplog[i-1] = rplog[i];
rplog[rploglen-1] = ch; rplog[rploglen-1] = ch;
} }
} }
}
#endif #endif
switch (bb_got_signal) { switch (bb_got_signal) {
case SIGHUP: case SIGHUP:
for (i = 0; i < svnum; i++) for (i = 0; i < svnum; i++)
if (sv[i].pid) if (sv[i].pid)
kill(sv[i].pid, SIGTERM); kill(sv[i].pid, SIGTERM);
// N.B. fall through /* fall through */
case SIGTERM: case SIGTERM:
_exit((SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS); /* exit, unless we are init */
if (getpid() != 1)
goto ret;
default:
/* so we are init. do not exit,
* and pause respawning - we may be rebooting... */
bb_got_signal = 0;
deadline = 60;
goto do_sleep;
} }
} }
/* not reached */ ret:
return 0; return (SIGHUP == bb_got_signal) ? 111 : EXIT_SUCCESS;
} }