Project

General

Profile

Submit #3241 ยป shutdown.patch

piecuch, 06/08/2020 12:30 PM

View differences:

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