mirror of
https://github.com/troglobit/finit.git
synced 2026-10-14 10:19:36 +00:00
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:
1 parent
6f99c1db05
commit
2743a49d91
1 file changed
+168
-4
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user