From b8190c8a2ab6e2fa74919dcc4d4333a13d54f533 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sun, 29 Oct 2017 16:53:26 +0100 Subject: [PATCH] Refactor, move speed parser from getty() to prepare_tty() This patch relocates the speed parser so that exec.c can set the TTY speed properly as soon as possible. For external getty we make sure to not touch the TTY speed. Signed-off-by: Joachim Nilsson --- src/exec.c | 24 ++++++++++++++------ src/getty.c | 63 +-------------------------------------------------- src/helpers.h | 9 ++++++-- src/stty.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 84 insertions(+), 74 deletions(-) diff --git a/src/exec.c b/src/exec.c index 46e3e5b5..af4d6758 100644 --- a/src/exec.c +++ b/src/exec.c @@ -30,6 +30,7 @@ #include #include #include +#include /* Not included by default in musl libc */ #include #include @@ -40,8 +41,6 @@ #define NUM_ARGS 16 -int getty(char *tty, char *baud, char *term, char *user); - /* Wait for process completion, returns status of waitpid(2) syscall */ int complete(char *cmd, int pid) @@ -235,14 +234,14 @@ int exec_runtask(char *cmd, char *args[]) return execvp(_PATH_BSHELL, argv); } -static void prepare_tty(char *tty, char *procname) +static void prepare_tty(char *tty, speed_t speed, char *procname) { struct termios term; /* * Reset to sane defaults in case of messup from prev. session */ - stty(STDIN_FILENO, B38400); + stty(STDIN_FILENO, speed); /* * Disable ISIG (INTR, QUIT, SUSP) before handing over to getty. @@ -336,13 +335,23 @@ static int activate_console(int noclear, int nowait) * since /bin/login usually only disables ECHO until a password line has * been entered. Upon starting the user's $SHELL the ISIG flag is reset */ -pid_t run_getty(char *tty, char *speed, char *term, int noclear, int nowait) +pid_t run_getty(char *tty, char *baud, char *term, int noclear, int nowait) { pid_t pid; pid = fork(); if (!pid) { - prepare_tty(tty, "finit-getty"); + speed_t speed = B38400; + + if (baud) { + speed = stty_parse_speed(baud); + if (B0 == speed) { + logit(LOG_CRIT, "TTY %s: Invalid speed %s", tty, baud); + speed = B38400; + } + } + + prepare_tty(tty, speed, "finit-getty"); if (activate_console(noclear, nowait)) _exit(getty(tty, speed, term, NULL)); } @@ -379,7 +388,8 @@ pid_t run_getty2(char *tty, char *cmd, char *args[], int noclear, int nowait) dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); - prepare_tty(tty, "getty"); + /* Dunno speed, tell stty() to not mess with it */ + prepare_tty(tty, B0, "getty"); if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) _pe("Failed TIOCSCTTY"); diff --git a/src/getty.c b/src/getty.c index 90875cc3..e83a42c1 100644 --- a/src/getty.c +++ b/src/getty.c @@ -208,73 +208,12 @@ static int do_login(char *name) return 1; /* We shouldn't get here ... */ } -static speed_t do_parse_speed(char *baud) -{ - char *ptr; - size_t i; - unsigned long val; - struct { unsigned long val; speed_t speed; } v2s[] = { - { 0, B0 }, - { 50, B50 }, - { 75, B75 }, - { 110, B110 }, - { 134, B134 }, - { 150, B150 }, - { 200, B200 }, - { 300, B300 }, - { 600, B600 }, - { 1200, B1200 }, - { 1800, B1800 }, - { 2400, B2400 }, - { 4800, B4800 }, - { 9600, B9600 }, - { 19200, B19200 }, - { 38400, B38400 }, - { 57600, B57600 }, - { 115200, B115200 }, - { 230400, B230400 }, - { 460800, B460800 }, - { 500000, B500000 }, - { 576000, B576000 }, - { 921600, B921600 }, - { 1000000, B1000000 }, - { 1152000, B1152000 }, - { 1500000, B1500000 }, - { 2000000, B2000000 }, - { 2500000, B2500000 }, - { 3000000, B3000000 }, - { 3500000, B3500000 }, - { 4000000, B4000000 }, - }; - - errno = 0; - val = strtoul(baud, &ptr, 10); - if (errno || ptr == baud) - return B0; - - for (i = 0; i < sizeof(v2s) / sizeof(v2s[0]); i++) { - if (v2s[i].val == val) - return v2s[i].speed; - } - - return B0; -} - -int getty(char *tty, char *baud, char *term, char *user) +int getty(char *tty, speed_t speed, char *term, char *user) { int fd; char name[30]; - speed_t speed = B38400; struct sigaction sa; - if (baud) { - speed = do_parse_speed(baud); - if (speed == B0) { - logit(LOG_CRIT, "TTY %s: Invalid speed %s", tty, baud); - return 1; - } - } - /* Detach from initial controlling TTY */ vhangup(); diff --git a/src/helpers.h b/src/helpers.h index 7a70af28..b677faba 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -27,6 +27,8 @@ #include #include +#include /* Not included by default in musl libc */ +#include #include #include "log.h" @@ -48,7 +50,10 @@ struct fstab *getfsent (void); char *strip_line (char *line); -int stty (int fd, unsigned int speed); +int getty (char *tty, speed_t speed, char *term, char *user); + +int stty (int fd, speed_t speed); +speed_t stty_parse_speed(char *baud); int pid_alive (pid_t pid); char *pid_get_name (pid_t pid, char *name, size_t len); @@ -66,7 +71,7 @@ int complete (char *cmd, int pid); int run (char *cmd); int run_interactive (char *cmd, char *fmt, ...); int exec_runtask (char *cmd, char *args[]); -pid_t run_getty (char *tty, char *speed, char *term, int noclear, int nowait); +pid_t run_getty (char *tty, char *baud, char *term, int noclear, int nowait); pid_t run_getty2 (char *tty, char *cmd, char *args[], int noclear, int nowait); int run_parts (char *dir, char *cmd); diff --git a/src/stty.c b/src/stty.c index 00ec911f..fd8429d7 100644 --- a/src/stty.c +++ b/src/stty.c @@ -21,10 +21,64 @@ * THE SOFTWARE. */ +#include +#include #include /* _POSIX_VDISABLE */ #include /* Not included by default in musl libc */ #include +speed_t stty_parse_speed(char *baud) +{ + char *ptr; + size_t i; + unsigned long val; + struct { unsigned long val; speed_t speed; } v2s[] = { + { 0, B0 }, + { 50, B50 }, + { 75, B75 }, + { 110, B110 }, + { 134, B134 }, + { 150, B150 }, + { 200, B200 }, + { 300, B300 }, + { 600, B600 }, + { 1200, B1200 }, + { 1800, B1800 }, + { 2400, B2400 }, + { 4800, B4800 }, + { 9600, B9600 }, + { 19200, B19200 }, + { 38400, B38400 }, + { 57600, B57600 }, + { 115200, B115200 }, + { 230400, B230400 }, + { 460800, B460800 }, + { 500000, B500000 }, + { 576000, B576000 }, + { 921600, B921600 }, + { 1000000, B1000000 }, + { 1152000, B1152000 }, + { 1500000, B1500000 }, + { 2000000, B2000000 }, + { 2500000, B2500000 }, + { 3000000, B3000000 }, + { 3500000, B3500000 }, + { 4000000, B4000000 }, + }; + + errno = 0; + val = strtoul(baud, &ptr, 10); + if (errno || ptr == baud) + return B0; + + for (i = 0; i < sizeof(v2s) / sizeof(v2s[0]); i++) { + if (v2s[i].val == val) + return v2s[i].speed; + } + + return B0; +} + void stty(int fd, speed_t speed) { struct termios term; @@ -33,9 +87,11 @@ void stty(int fd, speed_t speed) if (tcgetattr(fd, &term)) return; - cfsetispeed(&term, speed); - cfsetospeed(&term, speed); - tcsetattr(fd, TCSAFLUSH, &term); + if (speed != B0) { + cfsetispeed(&term, speed); + cfsetospeed(&term, speed); + tcsetattr(fd, TCSAFLUSH, &term); + } tcflush(fd, TCIOFLUSH); /* Disable modem specific flags */