Submit #3241 ยป shutdown.patch
| sbin/reboot/reboot.8 | ||
|---|---|---|
|
.It Fl n
|
||
|
The file system cache is not flushed.
|
||
|
This option should probably not be used.
|
||
|
.It Fl p
|
||
|
The system will turn off the power if it can.
|
||
|
If the power down action fails, the system
|
||
|
will halt or reboot normally, depending on whether
|
||
|
.Nm halt
|
||
|
or
|
||
|
.Nm
|
||
|
was called.
|
||
|
.It Fl q
|
||
|
The system is halted or restarted quickly and ungracefully, and only
|
||
|
the flushing of the file system cache is performed (if the
|
||
|
.Fl n
|
||
|
is not specified).
|
||
|
This option should probably not be used.
|
||
|
.It Fl p
|
||
|
The system will turn off the power
|
||
|
if it can.
|
||
|
This is of course likely to make
|
||
|
.Nm
|
||
|
rather similar to
|
||
|
.Nm halt .
|
||
|
.El
|
||
|
.Pp
|
||
|
The
|
||
| sbin/reboot/reboot.c | ||
|---|---|---|
|
#include <unistd.h>
|
||
|
#include <utmpx.h>
|
||
|
static void usage(void) __dead2;
|
||
|
static void usage(void);
|
||
|
static u_int get_pageins(void);
|
||
|
static int dohalt;
|
||
| ... | ... | |
|
}
|
||
|
argc -= optind;
|
||
|
argv += optind;
|
||
|
if (argc != 0)
|
||
|
usage();
|
||
|
if ((howto & (RB_DUMP | RB_HALT)) == (RB_DUMP | RB_HALT))
|
||
|
errx(1, "cannot dump (-d) when halting; must reboot instead");
|
||
| ... | ... | |
|
signal(SIGHUP, SIG_IGN);
|
||
|
/* parent shell might also send a SIGTERM? Best to ignore as well */
|
||
|
signal(SIGTERM, SIG_IGN);
|
||
|
/* Group leaders may try killing us with other signals, ignore */
|
||
|
signal(SIGINT, SIG_IGN);
|
||
|
signal(SIGQUIT, SIG_IGN);
|
||
|
signal(SIGTSTP, SIG_IGN);
|
||
|
/*
|
||
|
* If we're running in a pipeline, we don't want to die
|
||
|
* after killing whatever we're writing to.
|
||
|
*/
|
||
|
signal(SIGPIPE, SIG_IGN);
|
||
|
/* Send a SIGTERM first, a chance to save the buffers. */
|
||
|
if (kill(-1, SIGTERM) == -1)
|
||
| sbin/shutdown/shutdown.8 | ||
|---|---|---|
|
.Ar time .
|
||
|
.It Fl p
|
||
|
The system is halted and the power is turned off
|
||
|
(hardware support required)
|
||
|
(hardware support required, otherwise the system is halted)
|
||
|
at the specified
|
||
|
.Ar time .
|
||
|
.It Fl r
|
||
| ... | ... | |
|
.Xr halt 8
|
||
|
or
|
||
|
.Xr reboot 8
|
||
|
instead of sending signal to
|
||
|
instead of sending a signal to
|
||
|
.Xr init 8 .
|
||
|
.It Fl n
|
||
|
If the
|
||
| ... | ... | |
|
is the time at which
|
||
|
.Nm
|
||
|
will bring the system down and
|
||
|
may be the word
|
||
|
may be the case-insensitive word
|
||
|
.Ar now
|
||
|
(indicating an immediate shutdown) or
|
||
|
specify a future time in one of two formats:
|
||
| ... | ... | |
|
or
|
||
|
.Ar yymmddhhmm ,
|
||
|
where the year, month, and day may be defaulted
|
||
|
to the current system values. The first form brings the system down in
|
||
|
to the current system values.
|
||
|
The first form brings the system down in
|
||
|
.Ar number
|
||
|
minutes and the second at the absolute time specified.
|
||
|
.Ar +number
|
||
|
may be specified in units other than minutes by appending the corresponding
|
||
|
suffix:
|
||
|
.Dq Li s ,
|
||
|
.Dq Li sec ,
|
||
|
.Dq Li m ,
|
||
|
.Dq Li min .
|
||
|
.Dq Li h ,
|
||
|
.Dq Li hour .
|
||
|
.Pp
|
||
|
If an absolute time is specified, but not a date,
|
||
|
and that time today has already passed,
|
||
|
.Nm
|
||
|
will assume that the same time tomorrow was meant.
|
||
|
(If a complete date is specified which has already passed,
|
||
|
.Nm
|
||
|
will print an error and exit without shutting the system down.)
|
||
|
.It Ar warning-message
|
||
|
Any other arguments comprise the warning message that is broadcast
|
||
|
to users currently logged into the system.
|
||
| ... | ... | |
|
.Pp
|
||
|
At intervals, becoming more frequent as apocalypse approaches
|
||
|
and starting at ten hours before shutdown, warning messages are displayed
|
||
|
on the terminals of all users logged in. Five minutes before
|
||
|
on the terminals of all users logged in.
|
||
|
Five minutes before
|
||
|
shutdown, or immediately if shutdown is in less than 5 minutes,
|
||
|
logins are disabled by creating
|
||
|
.Pa /var/run/nologin
|
||
|
and copying the
|
||
|
warning message there. If this file exists when a user attempts to
|
||
|
warning message there.
|
||
|
If this file exists when a user attempts to
|
||
|
log in,
|
||
|
.Xr login 1
|
||
|
prints its contents and exits. The file is
|
||
|
prints its contents and exits.
|
||
|
The file is
|
||
|
removed just before
|
||
|
.Nm
|
||
|
exits.
|
||
| ... | ... | |
|
.Nm
|
||
|
created will be removed automatically.
|
||
|
.Pp
|
||
|
When run without options, the
|
||
|
.Nm
|
||
|
utility will place the system into single user mode at the
|
||
|
.Ar time
|
||
|
specified.
|
||
|
.Pp
|
||
|
Calling
|
||
|
.Dq Nm poweroff
|
||
|
is equivalent to running:
|
||
| ... | ... | |
|
.Sh FILES
|
||
|
.Bl -tag -width /var/run/nologin -compact
|
||
|
.It Pa /var/run/nologin
|
||
|
tells login not to let anyone log in
|
||
|
tells
|
||
|
.Xr login 1
|
||
|
not to let anyone log in
|
||
|
.El
|
||
|
.Sh EXAMPLES
|
||
|
Reboot the system in 30 minutes and display a warning message on the terminals
|
||
|
of all users currently logged in:
|
||
|
.Pp
|
||
|
.Dl # shutdown -r +30 \&"System will reboot\&"
|
||
|
.Sh BACKWARD COMPATIBILITY
|
||
|
The hours and minutes in the second time format may be separated by
|
||
|
a colon (``:'') for backward compatibility.
|
||
| sbin/shutdown/shutdown.c | ||
|---|---|---|
|
fprintf(pf, "System going down in %d minute%s\n\n",
|
||
|
timeleft / 60, (timeleft > 60) ? "s" : "");
|
||
|
else if (timeleft)
|
||
|
fprintf(pf, "System going down in 30 seconds\n\n");
|
||
|
fprintf(pf, "System going down in %s30 seconds\n\n",
|
||
|
(offset > 0 && offset < 30 ? "less than " : ""));
|
||
|
else
|
||
|
fprintf(pf, "System going down IMMEDIATELY\n\n");
|
||
| ... | ... | |
|
static void
|
||
|
die_you_gravy_sucking_pig_dog(void)
|
||
|
{
|
||
|
#ifndef DEBUG
|
||
|
char *empty_environ[] = { NULL };
|
||
|
#endif
|
||
|
syslog(LOG_NOTICE, "%s by %s: %s",
|
||
|
doreboot ? "reboot" : dohalt ? "halt" : dopower ? "power-down" :
|
||
| ... | ... | |
|
struct tm *lt;
|
||
|
char *p;
|
||
|
time_t now;
|
||
|
int this_year;
|
||
|
int maybe_today, this_year;
|
||
|
int errno;
|
||
|
char *timeunit;
|
||
|
time(&now);
|
||
| ... | ... | |
|
if (*timearg == '+') { /* +minutes */
|
||
|
if (!isdigit(*++timearg))
|
||
|
badtime();
|
||
|
if ((offset = atoi(timearg) * 60) < 0)
|
||
|
errno = 0;
|
||
|
offset = strtol(timearg, &timeunit, 10);
|
||
|
if (offset < 0 || offset == LONG_MAX || errno != 0)
|
||
|
badtime();
|
||
|
if (timeunit[0] == '\0' || strcasecmp(timeunit, "m") == 0 ||
|
||
|
strcasecmp(timeunit, "min") == 0 ||
|
||
|
strcasecmp(timeunit, "mins") == 0) {
|
||
|
offset *= 60;
|
||
|
} else if (strcasecmp(timeunit, "h") == 0 ||
|
||
|
strcasecmp(timeunit, "hour") == 0 ||
|
||
|
strcasecmp(timeunit, "hours") == 0) {
|
||
|
offset *= 60 * 60;
|
||
|
} else if (strcasecmp(timeunit, "s") == 0 ||
|
||
|
strcasecmp(timeunit, "sec") == 0 ||
|
||
|
strcasecmp(timeunit, "secs") == 0) {
|
||
|
offset *= 1;
|
||
|
} else {
|
||
|
badtime();
|
||
|
}
|
||
|
/* if ((offset = atoi(timearg) * 60) < 0) */
|
||
|
/* badtime(); */
|
||
|
shuttime = now + offset;
|
||
|
return;
|
||
|
}
|
||
| ... | ... | |
|
unsetenv("TZ"); /* OUR timezone */
|
||
|
lt = localtime(&now); /* current time val */
|
||
|
maybe_today = 1;
|
||
|
switch(strlen(timearg)) {
|
||
|
case 10:
|
||
| ... | ... | |
|
badtime();
|
||
|
/* FALLTHROUGH */
|
||
|
case 6:
|
||
|
maybe_today = 0;
|
||
|
lt->tm_mday = ATOI2(timearg);
|
||
|
if (lt->tm_mday < 1 || lt->tm_mday > 31)
|
||
|
badtime();
|
||
| ... | ... | |
|
lt->tm_sec = 0;
|
||
|
if ((shuttime = mktime(lt)) == -1)
|
||
|
badtime();
|
||
|
if ((offset = shuttime - now) < 0)
|
||
|
errx(1, "that time is already past.");
|
||
|
if ((offset = shuttime - now) < 0) {
|
||
|
if (!maybe_today)
|
||
|
errx(1, "that time is already past.");
|
||
|
/*
|
||
|
* If the user only gave a time, assume that
|
||
|
* any time earlier than the current time
|
||
|
* was intended to be that time tomorrow.
|
||
|
*/
|
||
|
lt->tm_mday++;
|
||
|
if ((shuttime = mktime(lt)) == -1)
|
||
|
badtime();
|
||
|
if ((offset = shuttime - now) < 0) {
|
||
|
errx(1, "tomorrow is before today?");
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
default:
|
||
|
badtime();
|
||