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();
|