X-Git-Url: http://git.openwrt.org/?a=blobdiff_plain;f=inittab.c;h=b2ffc9a25e5fc69aa6a581002331c3ab93c1cc3f;hb=93fc0893742092c7cbca5026da717a6ef2ae60b5;hp=6dde11af1a7ec9a1744b6fbd73e627f7061a840a;hpb=9a6f83d3c168523ac7b898ae481c2fd8c501d6a6;p=project%2Fprocd.git diff --git a/inittab.c b/inittab.c index 6dde11a..b2ffc9a 100644 --- a/inittab.c +++ b/inittab.c @@ -31,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 @@ -100,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); } @@ -116,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) @@ -153,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) @@ -167,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) @@ -187,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) @@ -202,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[] = { @@ -224,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, } }; @@ -247,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; } } @@ -266,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]; @@ -291,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'; @@ -310,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);