reboot: Add halt/poweroff/suspend and force cmd

This patch is a complete rewrite of the Finit reboot command.  Not only
does it bring it up to speed with the new signal model, but it also adds
new features like poweroff, halt, and suspend -- including a forced mode
that goes for reboot(2) immediately.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2016-08-14 12:27:52 +02:00
1 parent 6f99c1db05
commit 2743a49d91
1 file changed
+168 -4
+168 -4
View File
@@ -1,6 +1,6 @@
/* reboot for finit
/* reboot, halt, poweroff, shutdown, suspend for finit
*
* Copyright (c) 2009-2012 Joachim Nilsson <troglobit@gmail.com>
* Copyright (c) 2009-2016 Joachim Nilsson <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,11 +21,175 @@
* THE SOFTWARE.
*/
#include <err.h>
#include <getopt.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/reboot.h>
int main (void)
typedef enum {
CMD_UNKNOWN = -1,
CMD_REBOOT = 0,
CMD_HALT,
CMD_POWEROFF,
CMD_SUSPEND,
} cmd_t;
static cmd_t cmd = CMD_UNKNOWN;
static char *msg = NULL;
extern char *__progname;
static void translate(void)
{
return !!kill(1, SIGINT);
if (cmd == CMD_UNKNOWN) {
if (!strcmp(__progname, "halt") || !strcmp(__progname, "shutdown"))
cmd = CMD_HALT;
else if (!strcmp(__progname, "poweroff"))
cmd = CMD_POWEROFF;
else if (!strcmp(__progname, "suspend"))
cmd = CMD_SUSPEND;
else
cmd = CMD_REBOOT;
}
switch (cmd) {
case CMD_REBOOT:
msg = "reboot";
break;
case CMD_HALT:
msg = "halt";
break;
case CMD_POWEROFF:
msg = "power-off";
break;
case CMD_SUSPEND:
msg = "suspend";
break;
case CMD_UNKNOWN:
cmd = CMD_REBOOT;
msg = "reboot";
break;
}
}
static int usage(int rc)
{
fprintf(stderr, "Usage: %s [OPTIONS]\n\n"
"Options:\n"
" -h, --help This help text\n"
" -f, --force Force unsafe %s now\n"
" --halt Halt system, regardless of how the command is called.\n"
" -p, --poweroff Power-off system, regardless of how the command is called.\n"
" --reboot Reboot system, regardless of how the command is called.\n"
"\n", __progname, msg);
return rc;
}
int main(int argc, char *argv[])
{
int c, force = 0;
struct option long_options[] = {
{"help", 0, NULL, 'h'},
{"force", 0, NULL, 'f'},
{"halt", 0, NULL, 'H'},
{"poweroff", 0, NULL, 'p'},
{"reboot", 0, NULL, 'r'},
{NULL, 0, NULL, 0}
};
/* Initial command taken from program name */
translate();
while ((c = getopt_long(argc, argv, "h?fHpr", long_options, NULL)) != EOF) {
switch(c) {
case 'h':
case '?':
return usage(0);
case 'f':
force = 1;
break;
case 'H':
cmd = CMD_HALT;
break;
case 'p':
cmd = CMD_POWEROFF;
break;
case 'r':
cmd = CMD_REBOOT;
break;
default:
return usage(1);
}
}
/* Check for any overrides */
translate();
if (force) {
sync();
switch (cmd) {
case CMD_REBOOT:
c = reboot(RB_AUTOBOOT);
break;
case CMD_HALT:
c = reboot(RB_HALT_SYSTEM);
break;
case CMD_POWEROFF:
c = reboot(RB_POWER_OFF);
break;
case CMD_SUSPEND:
c = reboot(RB_SW_SUSPEND);
break;
case CMD_UNKNOWN:
errx(1, "Invalid command");
break;
}
if (c)
warn("Failed forced %s", msg);
else
return 0;
}
switch (cmd) {
case CMD_REBOOT:
c = kill(1, SIGTERM);
break;
case CMD_HALT:
c = kill(1, SIGUSR1);
break;
case CMD_POWEROFF:
c = kill(1, SIGUSR2);
break;
case CMD_UNKNOWN:
errx(1, "Invalid command");
break;
}
if (c)
err(1, "Failed signalling init to %s", msg);
return 0;
}
/**