instance: exit in case asprintf() fails
[project/procd.git] / inittab.c
index b67730c4a5b0a1ae3bba7736f0be4f43c01c3c30..128268a03fdbd2163210007a555a8bfe2ef82dee 100644 (file)
--- a/inittab.c
+++ b/inittab.c
@@ -123,6 +123,9 @@ static void child_exit(struct uloop_process *proc, int ret)
        DEBUG(4, "pid:%d, exitcode:%d\n", proc->pid, ret);
        proc->pid = 0;
 
+       if (a->respawn < 0)
+               return;
+
        if (!dev_exist(a->id)) {
                DEBUG(4, "Skipping respawn: device '%s' does not exist anymore\n", a->id);
                return;
@@ -165,9 +168,12 @@ static void askfirst(struct init_action *a)
        }
 
        a->tout.cb = respawn;
-       for (i = MAX_ARGS - 1; i >= 1; i--)
-               a->argv[i] = a->argv[i - 1];
-       a->argv[0] = ask;
+       /* shift arguments only if not yet done */
+       if (a->argv[0] != ask) {
+               for (i = MAX_ARGS - 1; i >= 1; i--)
+                       a->argv[i] = a->argv[i - 1];
+               a->argv[0] = ask;
+       }
        a->respawn = 500;
 
        a->proc.cb = child_exit;
@@ -180,7 +186,18 @@ static void askconsole(struct init_action *a)
        char line[256], *tty, *split;
        int i;
 
+       /* First, try console= on the kernel command line,
+        * then fallback to /sys/class/tty/console/active,
+        * which should work when linux,stdout-path (or equivalent)
+        * is in the device tree
+        */
        tty = get_cmdline_val("console", line, sizeof(line));
+       if (tty == NULL) {
+               if (dev_exist("console"))
+                       tty = "console";
+               else
+                       tty = get_active_console(line, sizeof(line));
+       }
        if (tty != NULL) {
                split = strchr(tty, ',');
                if (split != NULL)
@@ -200,9 +217,12 @@ static void askconsole(struct init_action *a)
        }
 
        a->tout.cb = respawn;
-       for (i = MAX_ARGS - 1; i >= 1; i--)
-               a->argv[i] = a->argv[i - 1];
-       a->argv[0] = ask;
+       /* shift arguments only if not yet done */
+       if (a->argv[0] != ask) {
+               for (i = MAX_ARGS - 1; i >= 1; i--)
+                       a->argv[i] = a->argv[i - 1];
+               a->argv[0] = ask;
+       }
        a->respawn = 500;
 
        a->proc.cb = child_exit;
@@ -270,15 +290,23 @@ void procd_inittab_run(const char *handler)
 
        list_for_each_entry(a, &actions, list)
                if (!strcmp(a->handler->name, handler)) {
-                       if (a->handler->multi) {
-                               a->handler->cb(a);
-                               continue;
-                       }
                        a->handler->cb(a);
-                       break;
+                       if (!a->handler->multi)
+                               break;
                }
 }
 
+void procd_inittab_kill(void)
+{
+       struct init_action *a;
+
+       list_for_each_entry(a, &actions, list) {
+               a->respawn = -1;
+               if (a->proc.pid)
+                       kill(a->proc.pid, SIGKILL);
+       }
+}
+
 void procd_inittab(void)
 {
 #define LINE_LEN       128