mirror of
https://github.com/troglobit/finit.git
synced 2026-10-20 11:19:35 +00:00
Fix #147: refactor reboot as multi-call to initctl
This patch drops the stand-alone reboot binary and folds it into the initctl tool, which now becomes a multi-call binary. With this change the reboot/shutdown/poweroff/halt/suspend commands also no longer default to sending signals to PID 1, instead it now uses the initctl <--> finit UNIX domain socket API. Signals are only used as a fallback in case of non-working domain socket. The -f,--force mode of operation still works, where `reboot(2)` is called directly. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
1 parent
649a269526
commit
7e42203627
4 files changed
+117
-66
No files matched your search
+34
-12
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
@@ -40,6 +41,13 @@ typedef enum {
|
||||
static cmd_t cmd = CMD_UNKNOWN;
|
||||
static char *msg = NULL;
|
||||
|
||||
/* initctl API */
|
||||
extern int do_reboot (char *arg);
|
||||
extern int do_halt (char *arg);
|
||||
extern int do_poweroff(char *arg);
|
||||
extern int do_suspend (char *arg);
|
||||
|
||||
|
||||
static void transform(char *nm)
|
||||
{
|
||||
if (!nm)
|
||||
@@ -80,6 +88,16 @@ static void transform(char *nm)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* fallback in case of initctl API failure
|
||||
*/
|
||||
static void do_kill(int signo, char *msg)
|
||||
{
|
||||
if (kill(1, signo))
|
||||
err(1, "Failed signalling init to %s", msg);
|
||||
do_sleep(5);
|
||||
}
|
||||
|
||||
static void sig(int signo)
|
||||
{
|
||||
(void)signo; /* NOP */
|
||||
@@ -100,7 +118,7 @@ static int usage(int rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
int reboot_main(int argc, char *argv[])
|
||||
{
|
||||
int c, force = 0;
|
||||
struct option long_options[] = {
|
||||
@@ -113,7 +131,7 @@ int main(int argc, char *argv[])
|
||||
};
|
||||
|
||||
/* Initial command taken from program name */
|
||||
transform(progname(argv[0]));
|
||||
transform(prognm);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h?fHPpr", long_options, NULL)) != EOF) {
|
||||
switch(c) {
|
||||
@@ -165,6 +183,8 @@ int main(int argc, char *argv[])
|
||||
|
||||
case CMD_SUSPEND:
|
||||
c = reboot(RB_SW_SUSPEND);
|
||||
if (c && errno == EINVAL)
|
||||
errx(1, "Kernel does not support suspend.");
|
||||
break;
|
||||
|
||||
case CMD_UNKNOWN:
|
||||
@@ -173,22 +193,25 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (c)
|
||||
warn("Failed forced %s", msg);
|
||||
else
|
||||
return 0;
|
||||
err(1, "Failed forced %s", msg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (cmd) {
|
||||
case CMD_REBOOT:
|
||||
c = kill(1, SIGTERM);
|
||||
if (do_reboot(NULL))
|
||||
do_kill(SIGTERM, msg);
|
||||
break;
|
||||
|
||||
case CMD_HALT:
|
||||
c = kill(1, SIGUSR1);
|
||||
if (do_halt(NULL))
|
||||
do_kill(SIGUSR1, msg);
|
||||
break;
|
||||
|
||||
case CMD_POWEROFF:
|
||||
c = kill(1, SIGUSR2);
|
||||
if (do_poweroff(NULL))
|
||||
do_kill(SIGUSR2, msg);
|
||||
break;
|
||||
|
||||
case CMD_SUSPEND:
|
||||
@@ -196,16 +219,15 @@ int main(int argc, char *argv[])
|
||||
* Only initctl supports suspend, we avoid adding
|
||||
* another signal to finit for compat reasons.
|
||||
*/
|
||||
do_suspend(NULL);
|
||||
break;
|
||||
|
||||
|
||||
case CMD_UNKNOWN:
|
||||
errx(1, "Invalid command");
|
||||
break;
|
||||
}
|
||||
|
||||
if (c)
|
||||
err(1, "Failed signalling init to %s", msg);
|
||||
do_sleep(5);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user