The problem was caused by procd not opening /dev/tty* (which ever was specified in /etc/inittab), causing /proc/PID/fd to point to /console instead. /dev/console is a non-controlling tty (CTTY), and cannot be used as one, which is exactly what curses applications want. Since this is very likely to cause problems with other programs, procd now opens /dev/tty? when the ID field of the inittab assigns one, and forces this to be a CTTY.
Signed-off-by: Michel Stam <m.s...@fugro.nl> --- inittab.c | 64 +++++++++++++++++++++++++++++++++++++++++--------------- utils/askfirst.c | 28 ++----------------------- 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/inittab.c b/inittab.c index c8540b1..344c55d 100644 --- a/inittab.c +++ b/inittab.c @@ -25,6 +25,7 @@ #include <libubox/utils.h> #include <libubox/list.h> +#include <sys/ioctl.h> #include "procd.h" #include "rcS.h" @@ -63,10 +64,49 @@ static char *ask = "/sbin/askfirst"; static LIST_HEAD(actions); +static int dev_open(const char *dev) +{ + int fd = -1; + + if (dev) { + chdir("/dev"); + fd = open( dev, O_RDWR); + chdir("/"); + } + + 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); + tcsetpgrp(fd, p); + close(fd); + ioctl(STDIN_FILENO, TIOCSCTTY, 1); + } execvp(a->argv[0], a->argv); ERROR("Failed to execute %s\n", a->argv[0]); exit(-1); @@ -110,22 +150,17 @@ static void runrc(struct init_action *a) 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,7 +169,6 @@ 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; @@ -153,20 +187,16 @@ static void askconsole(struct init_action *a) line[matches[1].rm_eo] = '\0'; tty = &line[matches[1].rm_so]; - chdir("/dev"); - i = stat(tty, &s); - chdir("/"); - if (i) { + if (!dev_exist(tty)) { DEBUG(4, "skipping %s\n", tty); goto err_out; } - 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->id = strdup(tty); a->argv[0] = ask; - a->argv[1] = strdup(tty); a->respawn = 500; a->proc.cb = child_exit; diff --git a/utils/askfirst.c b/utils/askfirst.c index 6ad77aa..e1f757a 100644 --- a/utils/askfirst.c +++ b/utils/askfirst.c @@ -19,34 +19,10 @@ #include <unistd.h> #include <fcntl.h> -static int redirect_output(const char *dev) -{ - pid_t p = setsid(); - int fd; - - chdir("/dev"); - fd = open(dev, O_RDWR); - chdir("/"); - - if (fd < 0) - return -1; - - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - tcsetpgrp(fd, p); - close(fd); - - return 0; -} - int main(int argc, char **argv) { int c; - if (redirect_output(argv[1])) - fprintf(stderr, "%s: Failed to open %s\n", argv[0], argv[1]); - printf("Please press Enter to activate this console.\n"); do { c = getchar(); @@ -55,8 +31,8 @@ int main(int argc, char **argv) } while (c != 0xA); - execvp(argv[2], &argv[2]); - printf("%s: Failed to execute %s\n", argv[0], argv[2]); + execvp(argv[1], &argv[1]); + printf("%s: Failed to execute %s\n", argv[0], argv[1]); return -1; } -- 1.7.12.1 _______________________________________________ openwrt-devel mailing list openwrt-devel@lists.openwrt.org https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel