From 4020c7689c3f640e8a56edd1a1491403112857ec Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sun, 5 Mar 2023 12:32:15 +0000 Subject: win32: add virtual terminal support to termios(3) Modify `struct termios` to support Windows virtual terminals. Native console mode flags replace the Unix `c_?flag` structure members. Remove unsupported flags from termios.h. Add implementations of tcgetattr(3)/tcsetattr(3) to get/set console flags when virtual terminal input mode is enabled. Add support for emulating raw mode to get_termios_and_make_raw(). This (and related functions) are exposed but not yet used. --- libbb/xfuncs.c | 8 ++-- win32/termios.c | 28 +++++++++++++ win32/termios.h | 128 ++++++++------------------------------------------------ 3 files changed, 50 insertions(+), 114 deletions(-) diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 388b246ca..bf15f4c75 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -311,13 +311,12 @@ int FAST_FUNC is_TERM_dumb(void) return term && strcmp(term, "dumb") == 0; } -#if !ENABLE_PLATFORM_MINGW32 int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) { return tcsetattr(STDIN_FILENO, TCSANOW, tp); } -int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *oldterm, int flags) +int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *oldterm, int flags IF_PLATFORM_MINGW32(UNUSED_PARAM)) { //TODO: slattach, shell read might be adapted to use this too: grep for "tcsetattr", "[VTIME] = 0" int r; @@ -326,6 +325,9 @@ int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct t r = tcgetattr(fd, oldterm); *newterm = *oldterm; +#if ENABLE_PLATFORM_MINGW32 + newterm->imode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT); +#else /* Turn off buffered input (ICANON) * Turn off echoing (ECHO) * and separate echoing of newline (ECHONL, normally off anyway) @@ -382,6 +384,7 @@ int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct t */ newterm->c_iflag &= ~(IXOFF|IXON|IXANY|BRKINT|INLCR|ICRNL|IUCLC|IMAXBEL); } +#endif return r; } @@ -392,7 +395,6 @@ int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags) get_termios_and_make_raw(fd, &newterm, oldterm, flags); return tcsetattr(fd, TCSANOW, &newterm); } -#endif pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) { diff --git a/win32/termios.c b/win32/termios.c index 7d390ce09..4b3588826 100644 --- a/win32/termios.c +++ b/win32/termios.c @@ -1,5 +1,33 @@ #include "libbb.h" +int tcsetattr(int fd, int mode UNUSED_PARAM, const struct termios *t) +{ + if (terminal_mode(FALSE) & VT_INPUT) { + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (!SetConsoleMode(h, t->imode)) { + errno = err_win_to_posix(); + return -1; + } + } + + return 0; +} + +int tcgetattr(int fd, struct termios *t) +{ + if (terminal_mode(FALSE) & VT_INPUT) { + HANDLE h = (HANDLE)_get_osfhandle(fd); + if (!GetConsoleMode(h, &t->imode)) { + errno = err_win_to_posix(); + return -1; + } + } + t->c_cc[VINTR] = 3; // ctrl-c + t->c_cc[VEOF] = 4; // ctrl-d + + return 0; +} + int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout) { HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); diff --git a/win32/termios.h b/win32/termios.h index c98d414f3..8408aa3e3 100644 --- a/win32/termios.h +++ b/win32/termios.h @@ -1,125 +1,31 @@ -/* iflag bits */ -#define IGNBRK 0x00001 -#define BRKINT 0x00002 -#define IGNPAR 0x00004 -#define IMAXBEL 0x00008 -#define INPCK 0x00010 -#define ISTRIP 0x00020 -#define INLCR 0x00040 -#define IGNCR 0x00080 -#define ICRNL 0x00100 -#define IXON 0x00400 -#define IXOFF 0x01000 -#define IUCLC 0x04000 -#define IXANY 0x08000 -#define PARMRK 0x10000 +#ifndef TERMIOS_H +#define TERMIOS_H -/* oflag bits */ +#define VINTR 0 +#define VEOF 1 -#define OPOST 0x00001 -#define OLCUC 0x00002 -#define OCRNL 0x00004 -#define ONLCR 0x00008 -#define ONOCR 0x00010 -#define ONLRET 0x00020 -#define OFILL 0x00040 -#define CRDLY 0x00180 -#define CR0 0x00000 -#define CR1 0x00080 -#define CR2 0x00100 -#define CR3 0x00180 -#define NLDLY 0x00200 -#define NL0 0x00000 -#define NL1 0x00200 -#define BSDLY 0x00400 -#define BS0 0x00000 -#define BS1 0x00400 -#define TABDLY 0x01800 -#define TAB0 0x00000 -#define TAB1 0x00800 -#define TAB2 0x01000 -#define TAB3 0x01800 -#define XTABS 0x01800 -#define VTDLY 0x02000 -#define VT0 0x00000 -#define VT1 0x02000 -#define FFDLY 0x04000 -#define FF0 0x00000 -#define FF1 0x04000 -#define OFDEL 0x08000 - -/* lflag bits */ -#define ISIG 0x0001 -#define ICANON 0x0002 -#define ECHO 0x0004 -#define ECHOE 0x0008 -#define ECHOK 0x0010 -#define ECHONL 0x0020 -#define NOFLSH 0x0040 -#define TOSTOP 0x0080 -#define IEXTEN 0x0100 -#define FLUSHO 0x0200 -#define ECHOKE 0x0400 -#define ECHOCTL 0x0800 - -#define VDISCARD 1 -#define VEOL 2 -#define VEOL2 3 -#define VEOF 4 -#define VERASE 5 -#define VINTR 6 -#define VKILL 7 -#define VLNEXT 8 -#define VMIN 9 -#define VQUIT 10 -#define VREPRINT 11 -#define VSTART 12 -#define VSTOP 13 -#define VSUSP 14 -#define VSWTC 15 -#define VTIME 16 -#define VWERASE 17 - -#define TCIFLUSH 0 -#define TCSAFLUSH 1 -#define TCSANOW 2 -#define TCSADRAIN 3 -#define TCSADFLUSH 4 - -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 +#define TCIFLUSH 0 +#define TCSAFLUSH 1 +#define TCSANOW 2 +#define TCSADRAIN 3 +#define TCSADFLUSH 4 typedef unsigned char cc_t; -typedef unsigned int tcflag_t; typedef unsigned int speed_t; -typedef unsigned short otcflag_t; -typedef unsigned char ospeed_t; -#define NCCS 18 +#define NCCS 2 struct termios { - tcflag_t c_iflag; - tcflag_t c_oflag; - tcflag_t c_cflag; - tcflag_t c_lflag; - char c_line; cc_t c_cc[NCCS]; - speed_t c_ispeed; - speed_t c_ospeed; + unsigned long imode; + unsigned long omode; }; struct winsize { unsigned short ws_row, ws_col; unsigned short ws_xpixel, ws_ypixel; }; + +int tcgetattr(int fd, struct termios *t); +int tcsetattr(int fd, int mode, const struct termios *t); + +#endif /* TERMIOS_H */ -- cgit v1.2.3-55-g6feb