From f273ecc1352ab601c717938c6280c1a1078f531f Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Thu, 31 Aug 2017 00:51:11 +0200 Subject: [PATCH] Fix #79: Add 'nowait' option to tty setting, external getty This patch makes it possible to disable the "Please press Enter" prompt when using an external getty. Simply append `nowait` to the .conf entry and Finit will spawn the getty immediately. A future patch will add support for `noclear` as well to external getty, as well as a change in default (=> `wait`) for the built-in getty. Signed-off-by: Joachim Nilsson --- src/exec.c | 47 +++++++++++++++++++++++++++++------------------ src/helpers.h | 2 +- src/tty.c | 41 +++++++++++++++++++++++++---------------- src/tty.h | 1 + 4 files changed, 56 insertions(+), 35 deletions(-) diff --git a/src/exec.c b/src/exec.c index ec3b51c2..82b96705 100644 --- a/src/exec.c +++ b/src/exec.c @@ -240,7 +240,34 @@ pid_t run_getty(char *tty, char *speed, char *term, int noclear, int console) return pid; } -pid_t run_getty2(char *tty, char *cmd, char *args[], int console) +static int activate_console(int nowait) +{ + if (nowait) + return 1; + + while (!fexist(SYNC_SHUTDOWN)) { + char c; + static const char msg[] = "\nPlease press Enter to activate this console."; + + if (fexist(SYNC_STOPPED)) { + sleep(5); + continue; + } + + (void)write(STDERR_FILENO, msg, sizeof(msg)); + while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n') + continue; + + if (fexist(SYNC_STOPPED)) + continue; + + return 1; + } + + return 0; +} + +pid_t run_getty2(char *tty, char *cmd, char *args[], int nowait, int console) { pid_t pid; @@ -274,24 +301,8 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int console) if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) _pe("Failed TIOCSCTTY"); - while (!fexist(SYNC_SHUTDOWN)) { - char c; - static const char msg[] = "\nPlease press Enter to activate this console."; - - if (fexist(SYNC_STOPPED)) { - sleep(1); - continue; - } - - (void)write(STDERR_FILENO, msg, sizeof(msg)); - while (read(STDIN_FILENO, &c, 1) == 1 && c != '\n') - continue; - - if (fexist(SYNC_STOPPED)) - continue; - + if (activate_console(nowait)) _exit(execv(cmd, args)); - } close(fd); vhangup(); diff --git a/src/helpers.h b/src/helpers.h index cb06d81c..142a3d3d 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -64,7 +64,7 @@ int complete (char *cmd, int pid); int run (char *cmd); int run_interactive (char *cmd, char *fmt, ...); pid_t run_getty (char *tty, char *speed, char *term, int noclear, int console); -pid_t run_getty2 (char *tty, char *cmd, char *args[], int console); +pid_t run_getty2 (char *tty, char *cmd, char *args[], int nowait, int console); int run_parts (char *dir, char *cmd); static inline void create(char *path, mode_t mode, uid_t uid, gid_t gid) diff --git a/src/tty.c b/src/tty.c index 1f66a9f1..bbe1af48 100644 --- a/src/tty.c +++ b/src/tty.c @@ -115,12 +115,12 @@ void tty_sweep(void) * a leading '/dev' is encountered the remaining options must be in * the following sequence: * - * tty [!1-9,S] [BAUD[,BAUD,...]] [TERM] [noclear] + * tty [!1-9,S] [BAUD[,BAUD,...]] [TERM] [noclear] [nowait] * * Otherwise the leading prefix must be the full path to an existing * getty implementation, with it's arguments following: * - * tty [!1-9,S] [ARGS] + * tty [!1-9,S] [ARGS] [noclear] [nowait] * * Different getty implementations prefer the TTY device argument in * different order, so take care to investigate this first. @@ -128,7 +128,7 @@ void tty_sweep(void) int tty_register(char *line, struct timeval *mtime) { tty_node_t *entry; - int insert = 0, noclear = 0; + int insert = 0, noclear = 0, nowait = 0; size_t i, num = 0; char *tok, *cmd = NULL, *args[TTY_MAX_ARGS]; char *dev = NULL, *baud = NULL; @@ -146,12 +146,19 @@ int tty_register(char *line, struct timeval *mtime) */ tok = strtok(line, " \t"); while (tok && num < NELEMS(args)) { - args[num++] = tok; + if (!strcmp(tok, "noclear")) + noclear = 1; + else if (!strcmp(tok, "nowait")) + nowait = 1; + else + args[num++] = tok; + tok = strtok(NULL, " \t"); } - /* Iterate over all args, figure out if built-in or external */ + /* Iterate over all args */ for (i = 0; i < num; i++) { + /* First, figure out if built-in or external */ if (!dev && !cmd) { if (args[i][0] == '[') runlevels = line; @@ -168,25 +175,26 @@ int tty_register(char *line, struct timeval *mtime) /* Built-in getty args */ if (dev) { - if (isdigit(args[i][0])) + if (isdigit(args[i][0])) { baud = tok; - else if (!strcmp(args[i], "noclear")) - noclear = 1; - else + continue; + } + + /* + * Last arg, if not anything else, is the value + * to be used for the TERM environment variable. + */ + if (i + 1 == num) term = tok; } /* External getty, figure out the device */ if (cmd) { - if (!strncmp(args[i], "/dev", 4)) { + if (!strncmp(args[i], "/dev", 4)) dev = args[i]; - break; - } - if (!strncmp(args[i], "tty", 3)) { + if (!strncmp(args[i], "tty", 3)) dev = args[i]; - break; - } } } @@ -219,6 +227,7 @@ int tty_register(char *line, struct timeval *mtime) entry->data.baud = baud ? strdup(baud) : NULL; entry->data.term = term ? strdup(term) : NULL; entry->data.noclear = noclear; + entry->data.nowait = nowait; entry->data.runlevels = conf_parse_runlevels(runlevels); /* External getty */ @@ -374,7 +383,7 @@ void tty_start(finit_tty_t *tty) if (!tty->cmd) tty->pid = run_getty(dev, tty->baud, tty->term, tty->noclear, is_console); else - tty->pid = run_getty2(dev, tty->cmd, tty->args, is_console); + tty->pid = run_getty2(dev, tty->cmd, tty->args, tty->nowait, is_console); } void tty_stop(finit_tty_t *tty) diff --git a/src/tty.h b/src/tty.h index a484aefa..c6610457 100644 --- a/src/tty.h +++ b/src/tty.h @@ -36,6 +36,7 @@ typedef struct { char *baud; char *term; int noclear; + int nowait; int runlevels; char *cmd; /* NULL when running built-in getty */