init: add telinit code
authorAlan Cox <alan@linux.intel.com>
Mon, 8 Jun 2015 19:33:23 +0000 (20:33 +0100)
committerAlan Cox <alan@linux.intel.com>
Mon, 8 Jun 2015 19:33:23 +0000 (20:33 +0100)
Applications/build.mk
Applications/util/Makefile
Applications/util/Makefile.6809
Applications/util/init.c
Applications/util/telinit.c [new file with mode: 0644]

index c865e86..be58666 100644 (file)
@@ -7,8 +7,8 @@ util_apps := \
        decomp16 df dirname dosread du echo ed factor false fdisk fgrep fsck \
        grep head id init kill ll ln logname ls man mkdir mkfs mkfifo mknod \
        mount more mv od pagesize passwd patchcpm printenv prtroot ps pwd rm rmdir \
-       sleep ssh sort stty sum su sync tee tail touch tr true umount uniq \
-       uud uue wc which who whoami write xargs yes
+       sleep ssh sort stty sum su sync tee tail telinit touch tr true umount \
+       uniq uud uue wc which who whoami write xargs yes
 
 # ...and in V7/cmd.
 
index 8c3f338..284e59e 100644 (file)
@@ -46,6 +46,7 @@ SRCSNS = \
        sum.c \
        sync.c \
        tee.c \
+       telinit.c \
        touch.c \
        tr.c \
        true.c \
index cfc12f6..dd5c9a1 100644 (file)
@@ -80,6 +80,7 @@ SRCS  = banner.c \
        sync.c \
        tee.c \
        tail.c \
+       telinit.c \
        touch.c \
        tr.c \
        true.c \
index 2f97fb8..b76fedf 100644 (file)
@@ -56,18 +56,26 @@ static int initcount;
 int default_rl;
 int runlevel;
 
+volatile static int dingdong;
+
 void sigalarm(int sig)
 {
        return;
 }
 
+void sigusr1(int sig)
+{
+       signal(SIGUSR1, sigusr1);
+       dingdong = 1;
+}
+
 int showfile(char *fname)
 {
        int fd, len;
        char buf[80];
 
        fd = open(fname, O_RDONLY);
-       if (fd > 0) {
+       if (fd >= 0) {
                do {
                        len = read(fd, buf, 80);
                        write(1, buf, len);
@@ -212,7 +220,7 @@ static uint8_t to_runlevel(uint8_t c)
                return 7;               /* 1 << 7 is used for boot/single */
        if (c >=  '0' && c <= '6')
                return c - '0';
-       return -1;
+       return 0xFF;
 }
 
 /*
@@ -253,7 +261,7 @@ static void parse_initline(void)
                        return;
                }
                bit = to_runlevel(*sdata++);
-               if (bit == -1) {
+               if (bit == 0xFF) {
                        bad_line();
                        return;
                }
@@ -461,7 +469,7 @@ int main(int argc, char *argv[])
        int fdtty1;
 
        signal(SIGINT, SIG_IGN);
-//     signal(SIGHUP, telinit);
+       signal(SIGUSR1, sigusr1);
 
        /* remove any stale /etc/mtab file */
 
@@ -494,7 +502,17 @@ int main(int argc, char *argv[])
 
        for (;;) {
                clear_zombies(0);
-               /* FIXME: telinit handling, HUP handling */
+               if (dingdong) {
+                       uint8_t newrl;
+                       int fd = open("/var/run/intctl", O_RDONLY);
+                       if (fd != -1 && read(fd, &newrl, 1) == 1) {
+                               exit_runlevel(1 << runlevel, 1 << newrl);
+                               runlevel = newrl;
+                               enter_runlevel(1 << runlevel);
+                       }
+                       close(fd);
+                       dingdong = 0;
+               }
        }
 }
 
diff --git a/Applications/util/telinit.c b/Applications/util/telinit.c
new file mode 100644 (file)
index 0000000..5fe2f4b
--- /dev/null
@@ -0,0 +1,38 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
+
+/*
+ *     Turn the character codes 0123456sS into run level numbers
+ */
+static uint8_t to_runlevel(uint8_t c)
+{
+       if (c == 's' || c == 'S')
+               return 7;               /* 1 << 7 is used for boot/single */
+       if (c >=  '0' && c <= '6')
+               return c - '0';
+       return 0xFF;
+}
+
+int main(int argc, char *argv[])
+{
+  int fd;
+  uint8_t v;
+  
+  if (argc != 2) {
+    write(2, "telinit: [runlevel]\n", 20);
+    exit(1);
+  }
+  if (argv[1][1] || (v = to_runlevel(argv[1][0])) == 0xFF) {
+    write(2, "telinit: invalid run level\n", 27);
+    exit(1);
+  }
+  fd = open("/var/run/initctl", O_WRONLY|O_TRUNC|O_CREAT, 0600);
+  if (fd < 0 || write(fd, &v, 1) != 1 || close(fd) == -1 || 
+      kill(1, SIGUSR1) < 0)
+  {
+    perror("telinit");
+    exit(1);
+  }
+  exit(0);
+}