--- sbin/reboot/reboot.c.orig 2009-09-29 22:29:39.172648998 -0700 +++ sbin/reboot/reboot.c 2009-09-29 22:41:28.438914656 -0700 @@ -65,7 +65,7 @@ main(int argc, char *argv[]) { const struct passwd *pw; - int ch, howto, i, fd, lflag, nflag, qflag, sverrno; + int ch, howto, i, fd, fflag, lflag, nflag, qflag, sverrno; u_int pageins; const char *p, *user, *kernel = NULL; @@ -74,12 +74,15 @@ howto = RB_HALT; } else howto = 0; - lflag = nflag = qflag = 0; - while ((ch = getopt(argc, argv, "dk:lnpq")) != -1) + fflag = lflag = nflag = qflag = 0; + while ((ch = getopt(argc, argv, "dfk:lnpq")) != -1) switch(ch) { case 'd': howto |= RB_DUMP; break; + case 'f': + fflag = 1; + break; case 'k': kernel = optarg; break; @@ -142,71 +145,78 @@ } logwtmp("~", "shutdown", ""); - /* - * Do a sync early on, so disks start transfers while we're off - * killing processes. Don't worry about writes done before the - * processes die, the reboot system call syncs the disks. - */ - if (!nflag) - sync(); - - /* - * Ignore signals that we can get as a result of killing - * parents, group leaders, etc. - */ - (void)signal(SIGHUP, SIG_IGN); - (void)signal(SIGINT, SIG_IGN); - (void)signal(SIGQUIT, SIG_IGN); - (void)signal(SIGTERM, SIG_IGN); - (void)signal(SIGTSTP, SIG_IGN); - - /* - * If we're running in a pipeline, we don't want to die - * after killing whatever we're writing to. - */ - (void)signal(SIGPIPE, SIG_IGN); - - /* Just stop init -- if we fail, we'll restart it. */ - if (kill(1, SIGTSTP) == -1) - err(1, "SIGTSTP init"); - - /* Send a SIGTERM first, a chance to save the buffers. */ - if (kill(-1, SIGTERM) == -1 && errno != ESRCH) - err(1, "SIGTERM processes"); - - /* - * After the processes receive the signal, start the rest of the - * buffers on their way. Wait 5 seconds between the SIGTERM and - * the SIGKILL to give everybody a chance. If there is a lot of - * paging activity then wait longer, up to a maximum of approx - * 60 seconds. - */ - sleep(2); - for (i = 0; i < 20; i++) { - pageins = get_pageins(); + if (!fflag) { + if (dohalt) + (void)kill(1, SIGUSR2); + else + (void)kill(1, SIGINT); + } else { + /* + * Do a sync early on, so disks start transfers while we're off + * killing processes. Don't worry about writes done before the + * processes die, the reboot system call syncs the disks. + */ if (!nflag) sync(); - sleep(3); - if (get_pageins() == pageins) - break; - } - for (i = 1;; ++i) { - if (kill(-1, SIGKILL) == -1) { - if (errno == ESRCH) + /* + * Ignore signals that we can get as a result of killing + * parents, group leaders, etc. + */ + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + (void)signal(SIGTERM, SIG_IGN); + (void)signal(SIGTSTP, SIG_IGN); + + /* + * If we're running in a pipeline, we don't want to die + * after killing whatever we're writing to. + */ + (void)signal(SIGPIPE, SIG_IGN); + + /* Just stop init -- if we fail, we'll restart it. */ + if (kill(1, SIGTSTP) == -1) + err(1, "SIGTSTP init"); + + /* Send a SIGTERM first, a chance to save the buffers. */ + if (kill(-1, SIGTERM) == -1 && errno != ESRCH) + err(1, "SIGTERM processes"); + + /* + * After the processes receive the signal, start the rest of the + * buffers on their way. Wait 5 seconds between the SIGTERM and + * the SIGKILL to give everybody a chance. If there is a lot of + * paging activity then wait longer, up to a maximum of approx + * 60 seconds. + */ + sleep(2); + for (i = 0; i < 20; i++) { + pageins = get_pageins(); + if (!nflag) + sync(); + sleep(3); + if (get_pageins() == pageins) break; - goto restart; } - if (i > 5) { - (void)fprintf(stderr, - "WARNING: some process(es) wouldn't die\n"); - break; + + for (i = 1;; ++i) { + if (kill(-1, SIGKILL) == -1) { + if (errno == ESRCH) + break; + goto restart; + } + if (i > 5) { + (void)fprintf(stderr, + "WARNING: some process(es) wouldn't die\n"); + break; + } + (void)sleep(2 * i); } - (void)sleep(2 * i); - } - reboot(howto); - /* FALLTHROUGH */ + reboot(howto); + /* FALLTHROUGH */ + } restart: sverrno = errno; @@ -218,7 +228,7 @@ static void usage() { - (void)fprintf(stderr, "usage: %s [-%slnpq] [-k kernel]\n", + (void)fprintf(stderr, "usage: %s [-%sflnpq] [-k kernel]\n", getprogname(), dohalt ? "" : "d"); exit(1); }