commit ba9fe481228c0ff7e15387d9ad84fbd96f6557bf
Author: Cem Keylan <cem@ckyln.com>
Date: Thu, 6 Feb 2020 14:19:14 +0300
initial commit
Diffstat:
A | .gitignore | | | 2 | ++ |
A | LICENSE | | | 21 | +++++++++++++++++++++ |
A | Makefile | | | 35 | +++++++++++++++++++++++++++++++++++ |
A | README.md | | | 54 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | config.def.h | | | 3 | +++ |
A | minit.c | | | 61 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
6 files changed, 176 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,2 @@
+minit
+config.h
diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2020 Cem Keylan
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/Makefile b/Makefile
@@ -0,0 +1,35 @@
+VERSION = 0.1.0
+
+PREFIX = /usr/local
+BINDIR = ${PREFIX}/bin
+
+CFLAGS = -Wextra -Wall -Os
+LDFLAGS = -s -static
+CC = cc
+
+all: minit
+
+minit: config.h
+ ${CC} ${LDFLAGS} ${CFLAGS} -o $@ minit.c
+
+config.h:
+ cp config.def.h config.h
+
+clean:
+ rm -f minit minit-${VERSION}.tar.gz
+
+dist:
+ mkdir minit-${VERSION}
+ cp minit.c Makefile LICENSE README.md config.def.h \
+ minit-${VERSION}
+ tar cf minit-${VERSION}.tar minit-${VERSION}
+ gzip minit-${VERSION}.tar
+ rm -rf minit-${VERSION}
+
+install: all
+ install -Dm755 minit ${DESTDIR}${BINDIR}/minit
+
+uninstall:
+ rm -f ${DESTDIR}${BINDIR}/minit
+
+.PHONY: all clean dist install uninstall
diff --git a/README.md b/README.md
@@ -0,0 +1,54 @@
+minit - mini init
+=================
+
+A small init daemon inspired by sinit[1]
+with basic halting capabilities.
+
+Building and installing
+-----------------------
+
+minit can be configured from config.h before
+compile time. After editing you can simply build
+and install with
+
+ make
+ make install
+
+Usage Note
+----------
+
+This halting capability adds 2 signals to
+the init daemon, SIGUSR2 and SIGQUIT. Keep
+in mind that you do not want to send these
+signals standalone, as they will power your
+computer off, they will not run through your
+init scripts or anything. You must send these
+signals from the init scripts so your computer
+shuts down (or reboots) after you deal with the
+delicate parts of your shutdown process.
+
+
+Controlling minit
+-----------------
+
+You can add some basic poweroff/reboot programs
+so you don't have to remember which signal to send
+with your kill command.
+
+A basic poweroff would be
+
+ #!/bin/sh
+ /bin/kill -s USR1 1
+
+A basic reboot would be
+
+ #!/bin/sh
+ /bin/kill -s INT 1
+
+
+On your init script, you can add something like
+
+ case "$1" in
+ reboot) /bin/kill -s QUIT 1 ;;
+ poweroff) /bin/kill -s USR2 1 ;;
+ esac
diff --git a/config.def.h b/config.def.h
@@ -0,0 +1,3 @@
+static char *const rcinitcmd[] = { "/usr/lib/init/rc.boot", NULL };
+static char *const rcrebootcmd[] = { "/usr/lib/init/rc.shutdown", "reboot", NULL };
+static char *const rcpoweroffcmd[] = { "/usr/lib/init/rc.shutdown", "poweroff", NULL };
diff --git a/minit.c b/minit.c
@@ -0,0 +1,61 @@
+#include <signal.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/reboot.h>
+
+#define LEN(x) (sizeof (x) / sizeof *(x))
+
+static void sigpoweroff(void);
+static void sigreboot(void);
+static void sighalt(void);
+static void sigrestart(void);
+static void spawn(char *const []);
+
+static struct {
+ int sig;
+ void (*handler)(void);} sigmap[] = {
+ { SIGUSR1, sigpoweroff },
+ { SIGINT, sigreboot },
+ { SIGUSR2, sighalt },
+ { SIGQUIT, sigrestart },
+};
+
+static sigset_t set;
+
+#include "config.h"
+
+int main(void) {
+ int sig;
+ size_t i;
+ if (getpid() != 1) return 1;
+
+ sigfillset(&set);
+ sigprocmask(SIG_BLOCK, &set, 0);
+ spawn(rcinitcmd);
+ while (1) {
+ sigwait(&set, &sig);
+ for (i = 0; i < LEN(sigmap); i++) {
+ if (sigmap[i].sig == sig) {
+ sigmap[i].handler();
+ break;
+ }
+ }
+ }
+}
+
+static void sigpoweroff(void){spawn(rcpoweroffcmd);}
+static void sigreboot(void){spawn(rcrebootcmd);}
+static void sighalt(void){reboot(RB_POWER_OFF);}
+static void sigrestart(void){reboot(RB_AUTOBOOT);}
+static void spawn(char *const argv[]){
+ switch (fork()) {
+ case 0:
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+ setsid();
+ execvp(argv[0], argv);
+ perror("execvp");
+ _exit(1);
+ case -1:
+ perror("fork");
+ }
+}