X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=inittab.c;h=b2ffc9a25e5fc69aa6a581002331c3ab93c1cc3f;hb=2562e2b38d14fb1f337202feb6376fd447f30222;hp=528396e57534553309cdf482b87ba837772984a1;hpb=f2c77756933f22981c1202c039e7f7e24d7247f3;p=project%2Fprocd.git diff --git a/inittab.c b/inittab.c index 528396e..b2ffc9a 100644 --- a/inittab.c +++ b/inittab.c @@ -12,6 +12,7 @@ * GNU General Public License for more details. */ +#define _GNU_SOURCE #include #include #include @@ -30,6 +31,10 @@ #include "procd.h" #include "rcS.h" +#ifndef O_PATH +#define O_PATH 010000000 +#endif + #define TAG_ID 0 #define TAG_RUNLVL 1 #define TAG_ACTION 2 @@ -99,7 +104,7 @@ static void fork_worker(struct init_action *a) tcsetpgrp(STDIN_FILENO, p); execvp(a->argv[0], a->argv); - ERROR("Failed to execute %s\n", a->argv[0]); + ERROR("Failed to execute %s: %m\n", a->argv[0]); exit(-1); } @@ -115,14 +120,22 @@ static void child_exit(struct uloop_process *proc, int ret) { struct init_action *a = container_of(proc, struct init_action, proc); - DEBUG(4, "pid:%d\n", proc->pid); - uloop_timeout_set(&a->tout, a->respawn); + DEBUG(4, "pid:%d, exitcode:%d\n", proc->pid, ret); + proc->pid = 0; + + if (!dev_exist(a->id)) { + DEBUG(4, "Skipping respawn: device '%s' does not exist anymore\n", a->id); + return; + } + + uloop_timeout_set(&a->tout, a->respawn); } static void respawn(struct uloop_timeout *tout) { struct init_action *a = container_of(tout, struct init_action, tout); - fork_worker(a); + if (!a->proc.pid) + fork_worker(a); } static void rcdone(struct runqueue *q) @@ -152,13 +165,17 @@ 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; - fork_worker(a); + if (!a->proc.pid) + fork_worker(a); } static void askconsole(struct init_action *a) @@ -166,7 +183,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) @@ -186,13 +214,17 @@ 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; - fork_worker(a); + if (!a->proc.pid) + fork_worker(a); } static void rcrespawn(struct init_action *a) @@ -201,7 +233,8 @@ static void rcrespawn(struct init_action *a) a->respawn = 500; a->proc.cb = child_exit; - fork_worker(a); + if (!a->proc.pid) + fork_worker(a); } static struct init_handler handlers[] = { @@ -223,6 +256,14 @@ static struct init_handler handlers[] = { .name = "respawn", .cb = rcrespawn, .multi = 1, + }, { + .name = "askconsolelate", + .cb = askconsole, + .multi = 1, + }, { + .name = "respawnlate", + .cb = rcrespawn, + .multi = 1, } }; @@ -246,12 +287,9 @@ 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; } } @@ -265,14 +303,13 @@ void procd_inittab(void) char *line; if (!fp) { - ERROR("Failed to open %s\n", tab); + ERROR("Failed to open %s: %m\n", tab); return; } regcomp(&pat_inittab, "([a-zA-Z0-9]*):([a-zA-Z0-9]*):([a-zA-Z0-9]*):(.*)", REG_EXTENDED); line = malloc(LINE_LEN); - a = malloc(sizeof(struct init_action)); - memset(a, 0, sizeof(struct init_action)); + a = calloc(1, sizeof(struct init_action)); while (fgets(line, LINE_LEN, fp)) { char *tags[TAG_PROCESS + 1]; @@ -290,7 +327,7 @@ void procd_inittab(void) if (regexec(&pat_inittab, line, 5, matches, 0)) continue; - DEBUG(4, "Parsing inittab - %s", line); + DEBUG(4, "Parsing inittab - %s\n", line); for (i = TAG_ID; i <= TAG_PROCESS; i++) { line[matches[i].rm_eo] = '\0'; @@ -309,8 +346,7 @@ void procd_inittab(void) if (add_action(a, tags[TAG_ACTION])) continue; line = malloc(LINE_LEN); - a = malloc(sizeof(struct init_action)); - memset(a, 0, sizeof(struct init_action)); + a = calloc(1, sizeof(struct init_action)); } fclose(fp);