summaryrefslogtreecommitdiff
path: root/src/init/s6-linux-init-telinit.c
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2019-04-16 20:37:01 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2019-04-16 20:37:01 +0000
commit73cff35173dd75b0254ae7cf9098c32822859de0 (patch)
treefd1bb09611b2b7064967ca8d8b2aef98514e616b /src/init/s6-linux-init-telinit.c
parent5199738f4e32773f4f752a94998593e18e3af36f (diff)
downloads6-linux-init-73cff35173dd75b0254ae7cf9098c32822859de0.tar.xz
It builds! Tomorrow: skeletons for stage2, stage3 and runlevel scripts.
Diffstat (limited to 'src/init/s6-linux-init-telinit.c')
-rw-r--r--src/init/s6-linux-init-telinit.c72
1 files changed, 72 insertions, 0 deletions
diff --git a/src/init/s6-linux-init-telinit.c b/src/init/s6-linux-init-telinit.c
new file mode 100644
index 0000000..8678709
--- /dev/null
+++ b/src/init/s6-linux-init-telinit.c
@@ -0,0 +1,72 @@
+/* ISC license. */
+
+#include <string.h>
+#include <sys/wait.h>
+
+#include <skalibs/types.h>
+#include <skalibs/sgetopt.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/config.h>
+
+#include <s6-linux-init/config.h>
+#include "initctl.h"
+
+#define USAGE "s6-linux-init-telinit runlevel"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+int main (int argc, char const *const *argv, char const *const *envp)
+{
+ char const *newargv[8] = { S6_EXTBINPREFIX "s6-sudo", "-e", "-T", "3600000", "--", RUNLEVELD_PATH, 0, 0 } ;
+ PROG = "s6-linux-init-telinit" ;
+ {
+ subgetopt_t l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "c:p:s:m:d:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'c' : /* s6-linux-init may be called with these options, don't choke on them */
+ case 'p' :
+ case 's' :
+ case 'm' :
+ case 'd' : break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ }
+
+ if (!argc) dieusage() ;
+ newargv[6] = argv[0] ;
+
+
+ /* specialcase 0 and 6: fork runlevel call then exec shutdown, instead of execing runlevel call */
+
+ if (!strcmp(argv[0], "0") || !strcmp(argv[0], "6"))
+ {
+ int wstat ;
+ pid_t pid = child_spawn0(newargv[0], newargv, envp) ;
+ if (!pid) strerr_diefu2sys(111, "spawn ", newargv[0]) ;
+ if (wait_pid(pid, &wstat) < 0) strerr_diefu1sys(111, "wait_pid") ;
+ if (WIFSIGNALED(wstat))
+ {
+ char fmt[UINT_FMT] ;
+ fmt[uint_fmt(fmt, WTERMSIG(wstat))] = 0 ;
+ strerr_dief3x(wait_estatus(wstat), newargv[0], " crashed with signal ", fmt) ;
+ }
+ else if (WEXITSTATUS(wstat))
+ {
+ char fmt[UINT_FMT] ;
+ fmt[uint_fmt(fmt, WEXITSTATUS(wstat))] = 0 ;
+ strerr_dief3x(wait_estatus(wstat), newargv[0], " died with exitcode ", fmt) ;
+ }
+
+ newargv[0] = argv[0][0] == '6' ? S6_LINUX_INIT_BINPREFIX "reboot" : S6_LINUX_INIT_BINPREFIX "poweroff" ;
+ newargv[1] = 0 ;
+ }
+
+ xpathexec_run(newargv[0], newargv, envp) ;
+}