commit
f081d9304b
4 changed files with 224 additions and 0 deletions
@ -0,0 +1,21 @@
|
||||
PREFIX ?= /usr
|
||||
|
||||
all: |
||||
$(CC) $(CFLAGS) halt.c -o halt $(LDFLAGS)
|
||||
|
||||
install: |
||||
install -d $(DESTDIR)$(PREFIX)/bin
|
||||
install -m755 halt $(DESTDIR)$(PREFIX)/bin/halt
|
||||
ln -sf halt $(DESTDIR)$(PREFIX)/bin/shutdown
|
||||
ln -sf halt $(DESTDIR)$(PREFIX)/bin/poweroff
|
||||
ln -sf halt $(DESTDIR)$(PREFIX)/bin/reboot
|
||||
install -d $(DESTDIR)$(PREFIX)/share/man/man8
|
||||
install -m644 halt.8 $(DESTDIR)$(PREFIX)/share/man/man8/halt.8
|
||||
ln -sf halt.8 $(DESTDIR)$(PREFIX)/share/man/man8/shutdown.8
|
||||
ln -sf halt.8 $(DESTDIR)$(PREFIX)/share/man/man8/poweroff.8
|
||||
ln -sf halt.8 $(DESTDIR)$(PREFIX)/share/man/man8/reboot.8
|
||||
|
||||
clean: |
||||
-rm -f halt
|
||||
|
||||
.PHONY: all install clean |
@ -0,0 +1 @@
|
||||
This is a wrapper program for OpenRC and runit's shutdown scheme. |
@ -0,0 +1,47 @@
|
||||
.TH "HALT" "8" "April 2018" "Artix Linux" "System Manager's Manual" |
||||
. |
||||
.SH "NAME" |
||||
\fBhalt\fR \- stop the system |
||||
. |
||||
.SH "SYNOPSIS" |
||||
\fBhalt\fR [\-nfdw] |
||||
. |
||||
.br |
||||
\fBpoweroff\fR [\-nfdw] |
||||
. |
||||
.br |
||||
\fBreboot\fR [\-nfdw] |
||||
. |
||||
.SH "DESCRIPTION" |
||||
\fBhalt\fR/\fBreboot\fR/\fBpoweroff\fR/\fBshutdown\fR is a (mostly) sysvinit\-compatible binary\. It tells init(8)/openrc\-shutdown(8) to bring down, reboot, or power off the system\. Without \fB\-f\fR, it is a shortcut to \fBinit 0\fR/\fBinit 6\fR (runit) or \fBopenrc\-shutdown\fR (openrc)\. |
||||
. |
||||
.TP |
||||
\fB\-n\fR |
||||
Don\'t sync before reboot or halt\. Note that the kernel and storage drivers may still sync\. |
||||
. |
||||
.TP |
||||
\fB\-f\fR |
||||
Force halt or reboot, don\'t call init(8)\. This is \fBdangerous\fR! |
||||
. |
||||
.TP |
||||
\fB\-d\fR |
||||
Do not write to the wtmp record\. |
||||
. |
||||
.TP |
||||
\fB\-w\fR |
||||
Do not stop the system but write to the wtmp record\. |
||||
. |
||||
.SH "NOTES" |
||||
This program tries to be as sysvinit\-compatible as possible, but due to limitations by the init system, some functions may not be available yet\. |
||||
. |
||||
.P |
||||
The \fBshutdown\fR program behaves like the \fBpoweroff\fR program\. |
||||
. |
||||
.P |
||||
Options \fB\-h\fR and \fB\-i\fR are fully ignored\. |
||||
. |
||||
.P |
||||
When you are using runit(8), the options \fB\-n\fR, \fB\-d\fR, and \fB\-w\fR are ignored\. |
||||
. |
||||
.SH "SEE ALSO" |
||||
init(8) |
@ -0,0 +1,155 @@
|
||||
/*
|
||||
* halt.c: A halt/poweroff/reboot wrapper for Artix Linux |
||||
* Based on halt.c from void-runit |
||||
* |
||||
* Copyright (C) 2018 Muhammad Herdiansyah |
||||
* (C) 2018 Artix Linux Developers |
||||
* |
||||
* Permission to use, copy, modify, and/or distribute this software |
||||
* for any purpose with or without fee is hereby granted, provided |
||||
* that the above copyright notice and this permission notice appear |
||||
* in all copies. |
||||
* |
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL |
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED |
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE |
||||
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL |
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA |
||||
* OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER |
||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
||||
* PERFORMANCE OF THIS SOFTWARE. |
||||
*/ |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <unistd.h> |
||||
#include <string.h> |
||||
#include <err.h> |
||||
#include <sys/reboot.h> |
||||
|
||||
extern char *__progname; |
||||
|
||||
typedef enum {NOOP, HALT, REBOOT, POWEROFF} action_type; |
||||
typedef enum {OPENRC, RUNIT} initsys; |
||||
|
||||
const char* get_init() |
||||
{ |
||||
char *name = (char *)calloc(1024,sizeof(char)); |
||||
if(name) { |
||||
sprintf(name, "/proc/1/cmdline"); |
||||
FILE *f = fopen(name, "r"); |
||||
if (f) { |
||||
size_t size; |
||||
size = fread(name, sizeof(char), 1024, f); |
||||
if (size > 0) { |
||||
if ('\n' == name[size-1]) |
||||
name[size-1]='\0'; |
||||
} |
||||
fclose(f); |
||||
} |
||||
} |
||||
return name; |
||||
} |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
if (getuid() != 0) |
||||
errx(1, "You must be root to do that!"); |
||||
|
||||
int do_sync = 1; |
||||
int do_force = 0; |
||||
int opt; |
||||
action_type action = NOOP; |
||||
initsys init; |
||||
const char *initfile = get_init(); |
||||
char openrc_options[50]; |
||||
|
||||
if (strcmp(initfile, "runit") == 0) |
||||
init = RUNIT; |
||||
else init = OPENRC; |
||||
|
||||
if (strcmp(__progname, "halt") == 0) |
||||
action = HALT; |
||||
else if (strcmp(__progname, "reboot") == 0) |
||||
action = REBOOT; |
||||
else if (strcmp(__progname, "poweroff") == 0 || strcmp(__progname, "shutdown") == 0) |
||||
action = POWEROFF; |
||||
else |
||||
warnx("No default behavior, needs to be called as halt/reboot/poweroff/shutdown."); |
||||
|
||||
while ((opt = getopt(argc, argv, "dfhinw")) != -1) |
||||
switch (opt) { |
||||
case 'n': |
||||
do_sync = 0; |
||||
strcat(openrc_options, "--no-write"); |
||||
break; |
||||
case 'w': |
||||
action = NOOP; |
||||
do_sync = 0; |
||||
strcat(openrc_options, "--write-only"); |
||||
break; |
||||
case 'd': |
||||
strcat(openrc_options, "--no-write"); |
||||
break; |
||||
case 'h': |
||||
case 'i': |
||||
break; |
||||
case 'f': |
||||
do_force = 1; |
||||
break; |
||||
default: |
||||
errx(1, "Usage: %s [-n] [-f]", __progname); |
||||
} |
||||
|
||||
if (do_sync) |
||||
sync(); |
||||
|
||||
switch (action) { |
||||
case HALT: |
||||
if (do_force) |
||||
reboot(RB_HALT_SYSTEM); |
||||
else |
||||
switch (init) { |
||||
case RUNIT: |
||||
execl("/usr/bin/runit-init", "init", "0", (char*)0); |
||||
break; |
||||
case OPENRC: |
||||
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--halt", openrc_options, (char*)0); |
||||
break; |
||||
} |
||||
err(1, "halt failed"); |
||||
break; |
||||
case POWEROFF: |
||||
if (do_force) |
||||
reboot(RB_POWER_OFF); |
||||
else |
||||
switch (init) { |
||||
case RUNIT: |
||||
execl("/usr/bin/runit-init", "init", "0", (char*)0); |
||||
break; |
||||
case OPENRC: |
||||
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--poweroff", openrc_options, (char*)0); |
||||
break; |
||||
} |
||||
err(1, "poweroff failed"); |
||||
break; |
||||
case REBOOT: |
||||
if (do_force) |
||||
reboot(RB_AUTOBOOT); |
||||
else |
||||
switch(init) { |
||||
case RUNIT: |
||||
execl("/usr/bin/runit-init", "init", "6", (char*)0); |
||||
break; |
||||
case OPENRC: |
||||
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--reboot", openrc_options, (char*)0); |
||||
break; |
||||
} |
||||
err(1, "reboot failed"); |
||||
break; |
||||
case NOOP: |
||||
break; |
||||
} |
||||
|
||||
return 0; |
||||
} |
Reference in new issue