- }
- if (getuid() != 0)
- exit(1);
- openlog("init", LOG_CONS|LOG_ODELAY, LOG_AUTH);
- if (setsid() < 0)
- syslog(LOG_ERR, "setsid failed (initial) %m");
- sigvec(SIGTERM, &rvec, (struct sigvec *)0);
- signal(SIGTSTP, idle);
- signal(SIGTTIN, SIG_IGN);
- signal(SIGTTOU, SIG_IGN);
- (void) setjmp(sjbuf);
- for (; ; ) {
- oldhowto = howto;
- howto = RB_SINGLE;
- if (started && setjmp(shutpass) == 0)
- shutdown();
- started = 1;
- if (oldhowto & RB_SINGLE)
- single();
- if (runcom(oldhowto) == 0)
- continue;
- merge();
- multiple();
+
+ if (optind != argc)
+ warning("ignoring excess arguments");
+
+ /*
+ * We catch or block signals rather than ignore them,
+ * so that they get reset on exec.
+ */
+ handle(disaster, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
+ SIGBUS, SIGSYS, SIGXCPU, SIGXFSZ, 0);
+ handle(transition_handler, SIGHUP, SIGTERM, SIGTSTP, 0);
+ handle(alrm_handler, SIGALRM, 0);
+ handle(chld_handler, SIGCHLD, 0);
+ sigfillset(&mask);
+ delset(&mask, SIGABRT, SIGFPE, SIGILL, SIGSEGV,
+ SIGBUS, SIGSYS, SIGXCPU, SIGXFSZ, 0);
+ sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);
+ multi_sig_mask = mask;
+ delset(&multi_sig_mask, SIGHUP, SIGTERM, SIGTSTP, SIGCHLD, 0);
+ death_mask = mask;
+ delset(&death_mask, SIGCHLD, SIGALRM);
+
+ /*
+ * Paranoia.
+ */
+ close(0);
+ close(1);
+ close(2);
+
+ /*
+ * Start the state machine.
+ */
+ transition(requested_transition);
+
+ /*
+ * Should never reach here.
+ */
+ return 1;
+}
+
+void
+#ifdef __STDC__
+handle(sig_t handler, ...)
+#else
+handle(va_alist)
+ va_dcl
+#endif
+{
+ int sig;
+ struct sigaction sa;
+ int mask_everything;
+ va_list ap;
+#ifndef __STDC__
+ sig_t handler;
+
+ va_start(ap);
+ handler = va_arg(ap, sig_t);
+#else
+ va_start(ap, handler);
+#endif
+
+ sa.sa_handler = handler;
+ sigfillset(&mask_everything);
+
+ while (sig = va_arg(ap, int)) {
+ sa.sa_mask = mask_everything;
+ /* XXX SA_RESTART? */
+ sa.sa_flags = sig == SIGCHLD ? SA_NOCLDSTOP : 0;
+ sigaction(sig, &sa, (struct sigaction *) 0);