aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-03-05 12:32:15 +0000
committerRon Yorston <rmy@pobox.com>2023-03-05 12:32:15 +0000
commit4020c7689c3f640e8a56edd1a1491403112857ec (patch)
treee1f68655eb34994557b51af970afae5c14cb05c6
parentf52c2004b818ac739ec886d5ff0a87734b55d293 (diff)
downloadbusybox-w32-4020c7689c3f640e8a56edd1a1491403112857ec.tar.gz
busybox-w32-4020c7689c3f640e8a56edd1a1491403112857ec.tar.bz2
busybox-w32-4020c7689c3f640e8a56edd1a1491403112857ec.zip
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.
-rw-r--r--libbb/xfuncs.c8
-rw-r--r--win32/termios.c28
-rw-r--r--win32/termios.h128
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)
311 return term && strcmp(term, "dumb") == 0; 311 return term && strcmp(term, "dumb") == 0;
312} 312}
313 313
314#if !ENABLE_PLATFORM_MINGW32
315int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) 314int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
316{ 315{
317 return tcsetattr(STDIN_FILENO, TCSANOW, tp); 316 return tcsetattr(STDIN_FILENO, TCSANOW, tp);
318} 317}
319 318
320int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *oldterm, int flags) 319int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct termios *oldterm, int flags IF_PLATFORM_MINGW32(UNUSED_PARAM))
321{ 320{
322//TODO: slattach, shell read might be adapted to use this too: grep for "tcsetattr", "[VTIME] = 0" 321//TODO: slattach, shell read might be adapted to use this too: grep for "tcsetattr", "[VTIME] = 0"
323 int r; 322 int r;
@@ -326,6 +325,9 @@ int FAST_FUNC get_termios_and_make_raw(int fd, struct termios *newterm, struct t
326 r = tcgetattr(fd, oldterm); 325 r = tcgetattr(fd, oldterm);
327 *newterm = *oldterm; 326 *newterm = *oldterm;
328 327
328#if ENABLE_PLATFORM_MINGW32
329 newterm->imode &= ~(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
330#else
329 /* Turn off buffered input (ICANON) 331 /* Turn off buffered input (ICANON)
330 * Turn off echoing (ECHO) 332 * Turn off echoing (ECHO)
331 * and separate echoing of newline (ECHONL, normally off anyway) 333 * 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
382 */ 384 */
383 newterm->c_iflag &= ~(IXOFF|IXON|IXANY|BRKINT|INLCR|ICRNL|IUCLC|IMAXBEL); 385 newterm->c_iflag &= ~(IXOFF|IXON|IXANY|BRKINT|INLCR|ICRNL|IUCLC|IMAXBEL);
384 } 386 }
387#endif
385 return r; 388 return r;
386} 389}
387 390
@@ -392,7 +395,6 @@ int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags)
392 get_termios_and_make_raw(fd, &newterm, oldterm, flags); 395 get_termios_and_make_raw(fd, &newterm, oldterm, flags);
393 return tcsetattr(fd, TCSANOW, &newterm); 396 return tcsetattr(fd, TCSANOW, &newterm);
394} 397}
395#endif
396 398
397pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) 399pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
398{ 400{
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 @@
1#include "libbb.h" 1#include "libbb.h"
2 2
3int tcsetattr(int fd, int mode UNUSED_PARAM, const struct termios *t)
4{
5 if (terminal_mode(FALSE) & VT_INPUT) {
6 HANDLE h = (HANDLE)_get_osfhandle(fd);
7 if (!SetConsoleMode(h, t->imode)) {
8 errno = err_win_to_posix();
9 return -1;
10 }
11 }
12
13 return 0;
14}
15
16int tcgetattr(int fd, struct termios *t)
17{
18 if (terminal_mode(FALSE) & VT_INPUT) {
19 HANDLE h = (HANDLE)_get_osfhandle(fd);
20 if (!GetConsoleMode(h, &t->imode)) {
21 errno = err_win_to_posix();
22 return -1;
23 }
24 }
25 t->c_cc[VINTR] = 3; // ctrl-c
26 t->c_cc[VEOF] = 4; // ctrl-d
27
28 return 0;
29}
30
3int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout) 31int64_t FAST_FUNC read_key(int fd, char *buf UNUSED_PARAM, int timeout)
4{ 32{
5 HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); 33 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 @@
1/* iflag bits */ 1#ifndef TERMIOS_H
2#define IGNBRK 0x00001 2#define TERMIOS_H
3#define BRKINT 0x00002
4#define IGNPAR 0x00004
5#define IMAXBEL 0x00008
6#define INPCK 0x00010
7#define ISTRIP 0x00020
8#define INLCR 0x00040
9#define IGNCR 0x00080
10#define ICRNL 0x00100
11#define IXON 0x00400
12#define IXOFF 0x01000
13#define IUCLC 0x04000
14#define IXANY 0x08000
15#define PARMRK 0x10000
16 3
17/* oflag bits */ 4#define VINTR 0
5#define VEOF 1
18 6
19#define OPOST 0x00001 7#define TCIFLUSH 0
20#define OLCUC 0x00002 8#define TCSAFLUSH 1
21#define OCRNL 0x00004 9#define TCSANOW 2
22#define ONLCR 0x00008 10#define TCSADRAIN 3
23#define ONOCR 0x00010 11#define TCSADFLUSH 4
24#define ONLRET 0x00020
25#define OFILL 0x00040
26#define CRDLY 0x00180
27#define CR0 0x00000
28#define CR1 0x00080
29#define CR2 0x00100
30#define CR3 0x00180
31#define NLDLY 0x00200
32#define NL0 0x00000
33#define NL1 0x00200
34#define BSDLY 0x00400
35#define BS0 0x00000
36#define BS1 0x00400
37#define TABDLY 0x01800
38#define TAB0 0x00000
39#define TAB1 0x00800
40#define TAB2 0x01000
41#define TAB3 0x01800
42#define XTABS 0x01800
43#define VTDLY 0x02000
44#define VT0 0x00000
45#define VT1 0x02000
46#define FFDLY 0x04000
47#define FF0 0x00000
48#define FF1 0x04000
49#define OFDEL 0x08000
50
51/* lflag bits */
52#define ISIG 0x0001
53#define ICANON 0x0002
54#define ECHO 0x0004
55#define ECHOE 0x0008
56#define ECHOK 0x0010
57#define ECHONL 0x0020
58#define NOFLSH 0x0040
59#define TOSTOP 0x0080
60#define IEXTEN 0x0100
61#define FLUSHO 0x0200
62#define ECHOKE 0x0400
63#define ECHOCTL 0x0800
64
65#define VDISCARD 1
66#define VEOL 2
67#define VEOL2 3
68#define VEOF 4
69#define VERASE 5
70#define VINTR 6
71#define VKILL 7
72#define VLNEXT 8
73#define VMIN 9
74#define VQUIT 10
75#define VREPRINT 11
76#define VSTART 12
77#define VSTOP 13
78#define VSUSP 14
79#define VSWTC 15
80#define VTIME 16
81#define VWERASE 17
82
83#define TCIFLUSH 0
84#define TCSAFLUSH 1
85#define TCSANOW 2
86#define TCSADRAIN 3
87#define TCSADFLUSH 4
88
89#define B0 0000000 /* hang up */
90#define B50 0000001
91#define B75 0000002
92#define B110 0000003
93#define B134 0000004
94#define B150 0000005
95#define B200 0000006
96#define B300 0000007
97#define B600 0000010
98#define B1200 0000011
99#define B1800 0000012
100#define B2400 0000013
101#define B4800 0000014
102#define B9600 0000015
103 12
104typedef unsigned char cc_t; 13typedef unsigned char cc_t;
105typedef unsigned int tcflag_t;
106typedef unsigned int speed_t; 14typedef unsigned int speed_t;
107typedef unsigned short otcflag_t;
108typedef unsigned char ospeed_t;
109 15
110#define NCCS 18 16#define NCCS 2
111struct termios { 17struct termios {
112 tcflag_t c_iflag;
113 tcflag_t c_oflag;
114 tcflag_t c_cflag;
115 tcflag_t c_lflag;
116 char c_line;
117 cc_t c_cc[NCCS]; 18 cc_t c_cc[NCCS];
118 speed_t c_ispeed; 19 unsigned long imode;
119 speed_t c_ospeed; 20 unsigned long omode;
120}; 21};
121 22
122struct winsize { 23struct winsize {
123 unsigned short ws_row, ws_col; 24 unsigned short ws_row, ws_col;
124 unsigned short ws_xpixel, ws_ypixel; 25 unsigned short ws_xpixel, ws_ypixel;
125}; 26};
27
28int tcgetattr(int fd, struct termios *t);
29int tcsetattr(int fd, int mode, const struct termios *t);
30
31#endif /* TERMIOS_H */