Browse Source

init

nohooks-patch 0.1
M. Herdiansyah 4 years ago
commit
f081d9304b
  1. 21
      Makefile
  2. 1
      README
  3. 47
      halt.8
  4. 155
      halt.c

21
Makefile

@ -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

1
README

@ -0,0 +1 @@
This is a wrapper program for OpenRC and runit's shutdown scheme.

47
halt.8

@ -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)

155
halt.c

@ -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;
}