X-Git-Url: http://git.archive.openwrt.org/?p=project%2Fprocd.git;a=blobdiff_plain;f=inittab.c;h=f8f0218f219b01023de4270483cf09eda134a3e8;hp=c8540b199e2a8906c970ccad13a6e6bb25799ea4;hb=8ce928994027019c858a523f2a2078736f8e2c5d;hpb=c1a558f7d0c1e6c1ffa5a47d557a7b45205eef1d diff --git a/inittab.c b/inittab.c index c8540b1..f8f0218 100644 --- a/inittab.c +++ b/inittab.c @@ -14,6 +14,7 @@ #include #include +#include #include #include @@ -25,6 +26,7 @@ #include #include +#include "utils/utils.h" #include "procd.h" #include "rcS.h" @@ -36,7 +38,7 @@ #define MAX_ARGS 8 struct init_action; -const char *console; +char *console = NULL; struct init_handler { const char *name; @@ -63,10 +65,54 @@ static char *ask = "/sbin/askfirst"; static LIST_HEAD(actions); +static int dev_open(const char *dev) +{ + int fd = -1; + + if (dev) { + if (chdir("/dev")) + ERROR("failed to change dir to /dev\n"); + fd = open(dev, O_RDWR); + if (chdir("/")) + ERROR("failed to change dir to /\n"); + } + + return fd; +} + +static int dev_exist(const char *dev) +{ + int res; + + res = dev_open(dev); + if (res != -1) + close(res); + + return (res != -1); +} + static void fork_worker(struct init_action *a) { + int fd; + pid_t p; + a->proc.pid = fork(); if (!a->proc.pid) { + p = setsid(); + + fd = dev_open(a->id); + if (fd != -1) + { + dup2(fd, STDIN_FILENO); + dup2(fd, STDOUT_FILENO); + dup2(fd, STDERR_FILENO); + if (fd > STDERR_FILENO) + close(fd); + } + + ioctl(STDIN_FILENO, TIOCSCTTY, 1); + tcsetpgrp(STDIN_FILENO, p); + execvp(a->argv[0], a->argv); ERROR("Failed to execute %s\n", a->argv[0]); exit(-1); @@ -105,27 +151,25 @@ static void runrc(struct init_action *a) ERROR("valid format is rcS \n"); return; } - rcS(a->argv[1], a->argv[2], rcdone); + + /* proceed even if no init or shutdown scripts run */ + if (rcS(a->argv[1], a->argv[2], rcdone)) + rcdone(NULL); } static void askfirst(struct init_action *a) { - struct stat s; int i; - chdir("/dev"); - i = stat(a->id, &s); - chdir("/"); - if (i || (console && !strcmp(console, a->id))) { + if (!dev_exist(a->id) || (console && !strcmp(console, a->id))) { DEBUG(4, "Skipping %s\n", a->id); return; } a->tout.cb = respawn; - for (i = MAX_ARGS - 2; i >= 2; i--) - a->argv[i] = a->argv[i - 2]; + for (i = MAX_ARGS - 1; i >= 1; i--) + a->argv[i] = a->argv[i - 1]; a->argv[0] = ask; - a->argv[1] = a->id; a->respawn = 500; a->proc.cb = child_exit; @@ -134,46 +178,36 @@ static void askfirst(struct init_action *a) static void askconsole(struct init_action *a) { - struct stat s; - char line[256], *tty; - int i, r, fd = open("/proc/cmdline", O_RDONLY); - regex_t pat_cmdline; - regmatch_t matches[2]; + char line[256], *tty, *split; + int i; - if (fd < 0) - return; + tty = get_cmdline_val("console", line, sizeof(line)); + if (tty != NULL) { + split = strchr(tty, ','); + if (split != NULL) + *split = '\0'; + + if (!dev_exist(tty)) { + DEBUG(4, "skipping %s\n", tty); + return; + } - r = read(fd, line, sizeof(line) - 1); - line[r] = '\0'; - close(fd); - - regcomp(&pat_cmdline, "console=([a-zA-Z0-9]*)", REG_EXTENDED); - if (regexec(&pat_cmdline, line, 2, matches, 0)) - goto err_out; - line[matches[1].rm_eo] = '\0'; - tty = &line[matches[1].rm_so]; - - chdir("/dev"); - i = stat(tty, &s); - chdir("/"); - if (i) { - DEBUG(4, "skipping %s\n", tty); - goto err_out; + console = strdup(tty); + a->id = strdup(tty); + } + else { + console = NULL; + a->id = NULL; } - console = strdup(tty); a->tout.cb = respawn; - for (i = MAX_ARGS - 2; i >= 2; i--) - a->argv[i] = a->argv[i - 2]; + for (i = MAX_ARGS - 1; i >= 1; i--) + a->argv[i] = a->argv[i - 1]; a->argv[0] = ask; - a->argv[1] = strdup(tty); a->respawn = 500; a->proc.cb = child_exit; fork_worker(a); - -err_out: - regfree(&pat_cmdline); } static void rcrespawn(struct init_action *a)