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 */