diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-05-09 16:52:07 +1000 |
---|---|---|
committer | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2009-05-09 16:52:07 +1000 |
commit | d5aaacda5a4b6cbea654c0d0cca3c901b8dda3d3 (patch) | |
tree | 431e1eb0054adf6ae76a9121b766476f7fc6c508 | |
parent | 4f8a4a01cdb91a0e4b0f7ee7235b69d93cd11843 (diff) | |
download | busybox-w32-d5aaacda5a4b6cbea654c0d0cca3c901b8dda3d3.tar.gz busybox-w32-d5aaacda5a4b6cbea654c0d0cca3c901b8dda3d3.tar.bz2 busybox-w32-d5aaacda5a4b6cbea654c0d0cca3c901b8dda3d3.zip |
introduce libbb/termios.c for terminal-related functions
-rw-r--r-- | include/cygwin_termios.h | 109 | ||||
-rw-r--r-- | libbb/Kbuild | 1 | ||||
-rw-r--r-- | libbb/lineedit.c | 68 | ||||
-rw-r--r-- | libbb/termios.c | 73 | ||||
-rw-r--r-- | libbb/xfuncs.c | 21 |
5 files changed, 189 insertions, 83 deletions
diff --git a/include/cygwin_termios.h b/include/cygwin_termios.h new file mode 100644 index 000000000..b7ec2957f --- /dev/null +++ b/include/cygwin_termios.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* iflag bits */ | ||
2 | #define IGNBRK 0x00001 | ||
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 | |||
17 | /* oflag bits */ | ||
18 | |||
19 | #define OPOST 0x00001 | ||
20 | #define OLCUC 0x00002 | ||
21 | #define OCRNL 0x00004 | ||
22 | #define ONLCR 0x00008 | ||
23 | #define ONOCR 0x00010 | ||
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 TCSAFLUSH 1 | ||
84 | #define TCSANOW 2 | ||
85 | #define TCSADRAIN 3 | ||
86 | #define TCSADFLUSH 4 | ||
87 | |||
88 | typedef unsigned char cc_t; | ||
89 | typedef unsigned int tcflag_t; | ||
90 | typedef unsigned int speed_t; | ||
91 | typedef unsigned short otcflag_t; | ||
92 | typedef unsigned char ospeed_t; | ||
93 | |||
94 | #define NCCS 18 | ||
95 | struct termios { | ||
96 | tcflag_t c_iflag; | ||
97 | tcflag_t c_oflag; | ||
98 | tcflag_t c_cflag; | ||
99 | tcflag_t c_lflag; | ||
100 | char c_line; | ||
101 | cc_t c_cc[NCCS]; | ||
102 | speed_t c_ispeed; | ||
103 | speed_t c_ospeed; | ||
104 | }; | ||
105 | |||
106 | int tcgetattr(int fd, struct termios *t); | ||
107 | int tcsetattr(int fd, int mode, const struct termios *t); | ||
108 | int is_cygwin_tty(int fd); | ||
109 | int wincon_read(int fd, char *buf, int size); | ||
diff --git a/libbb/Kbuild b/libbb/Kbuild index e335a95dc..b3560bd0b 100644 --- a/libbb/Kbuild +++ b/libbb/Kbuild | |||
@@ -138,6 +138,7 @@ lib-$(CONFIG_MINGW32) += setenv.o | |||
138 | lib-$(CONFIG_MINGW32) += strbuf.o | 138 | lib-$(CONFIG_MINGW32) += strbuf.o |
139 | lib-$(CONFIG_MINGW32) += strbuf_file.o | 139 | lib-$(CONFIG_MINGW32) += strbuf_file.o |
140 | lib-$(CONFIG_MINGW32) += strlcpy.o | 140 | lib-$(CONFIG_MINGW32) += strlcpy.o |
141 | lib-$(CONFIG_MINGW32) += termios.o | ||
141 | lib-$(CONFIG_MINGW32) += trace.o | 142 | lib-$(CONFIG_MINGW32) += trace.o |
142 | lib-$(CONFIG_MINGW32) += usage.o | 143 | lib-$(CONFIG_MINGW32) += usage.o |
143 | lib-$(CONFIG_MINGW32) += winansi.o | 144 | lib-$(CONFIG_MINGW32) += winansi.o |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b349bc6f2..e56dd20b0 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -59,28 +59,13 @@ | |||
59 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ | 59 | #define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ |
60 | (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) | 60 | (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) |
61 | 61 | ||
62 | |||
63 | static line_input_t *state; | ||
64 | |||
65 | #ifdef __MINGW32__ | 62 | #ifdef __MINGW32__ |
66 | struct termios { | 63 | #include "cygwin_termios.h" |
67 | int c_lflag; | 64 | #define safe_read(fd,buf,size) wincon_read(fd,buf,size) |
68 | int c_cc[3]; | ||
69 | }; | ||
70 | #define safe_read(fd,buf,n) wincon_read(fd,buf,n) | ||
71 | /* True value does not matter because it's emulated */ | ||
72 | #define ICANON 1 | ||
73 | #define ECHO 2 | ||
74 | #define ECHONL 4 | ||
75 | #define ISIG 8 | ||
76 | |||
77 | #define VMIN 0 | ||
78 | #define VTIME 1 | ||
79 | #define VINTR 2 | ||
80 | |||
81 | static int wincon_read(int fd, char *buf, int size); | ||
82 | #endif | 65 | #endif |
83 | 66 | ||
67 | static line_input_t *state; | ||
68 | |||
84 | static struct termios initial_settings, new_settings; | 69 | static struct termios initial_settings, new_settings; |
85 | 70 | ||
86 | static volatile unsigned cmdedit_termw = 80; /* actual terminal width */ | 71 | static volatile unsigned cmdedit_termw = 80; /* actual terminal width */ |
@@ -1227,13 +1212,10 @@ static void parse_prompt(const char *prmt_ptr) | |||
1227 | } | 1212 | } |
1228 | #endif | 1213 | #endif |
1229 | 1214 | ||
1230 | #ifdef __MINGW32__ | ||
1231 | #define setTermSettings(fd, argp) | ||
1232 | #define getTermSettings(fd, argp) ((struct termios *)argp)->c_lflag = ECHO; | ||
1233 | #else | ||
1234 | #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) | 1215 | #define setTermSettings(fd, argp) tcsetattr(fd, TCSANOW, argp) |
1235 | #define getTermSettings(fd, argp) tcgetattr(fd, argp); | 1216 | #define getTermSettings(fd, argp) tcgetattr(fd, argp); |
1236 | 1217 | ||
1218 | #ifndef __MINGW32__ | ||
1237 | static sighandler_t previous_SIGWINCH_handler; | 1219 | static sighandler_t previous_SIGWINCH_handler; |
1238 | #endif | 1220 | #endif |
1239 | 1221 | ||
@@ -1770,46 +1752,6 @@ line_input_t *new_line_input_t(int flags) | |||
1770 | return n; | 1752 | return n; |
1771 | } | 1753 | } |
1772 | 1754 | ||
1773 | #ifdef __MINGW32__ | ||
1774 | #include <windef.h> | ||
1775 | #include <wincon.h> | ||
1776 | #include "strbuf.h" | ||
1777 | |||
1778 | #undef safe_read | ||
1779 | static int wincon_read(int fd, char *buf, int size) | ||
1780 | { | ||
1781 | static struct strbuf input = STRBUF_INIT; | ||
1782 | HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); | ||
1783 | static int initialized = 0; | ||
1784 | |||
1785 | if (fd != 0) | ||
1786 | die("wincon_read is for stdin only"); | ||
1787 | if (cin == INVALID_HANDLE_VALUE) | ||
1788 | return safe_read(fd, buf, size); | ||
1789 | if (!initialized) { | ||
1790 | SetConsoleMode(cin, ENABLE_ECHO_INPUT); | ||
1791 | initialized = 1; | ||
1792 | } | ||
1793 | while (input.len < size) { | ||
1794 | INPUT_RECORD record; | ||
1795 | DWORD nevent = 0, nevent_out; | ||
1796 | int ch; | ||
1797 | |||
1798 | if (!ReadConsoleInput(cin, &record, 1, &nevent_out)) | ||
1799 | return -1; | ||
1800 | if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) | ||
1801 | continue; | ||
1802 | ch = record.Event.KeyEvent.uChar.AsciiChar; | ||
1803 | /* Ctrl-X is handled by ReadConsoleInput, Alt-X is not needed anyway */ | ||
1804 | strbuf_addch(&input, ch); | ||
1805 | } | ||
1806 | memcpy(buf, input.buf, size); | ||
1807 | memcpy(input.buf, input.buf+size, input.len-size+1); | ||
1808 | strbuf_setlen(&input, input.len-size); | ||
1809 | return size; | ||
1810 | } | ||
1811 | #endif | ||
1812 | |||
1813 | #else | 1755 | #else |
1814 | 1756 | ||
1815 | #undef read_line_input | 1757 | #undef read_line_input |
diff --git a/libbb/termios.c b/libbb/termios.c new file mode 100644 index 000000000..f47593a49 --- /dev/null +++ b/libbb/termios.c | |||
@@ -0,0 +1,73 @@ | |||
1 | #include "libbb.h" | ||
2 | #include <windef.h> | ||
3 | #include <wincon.h> | ||
4 | #include "strbuf.h" | ||
5 | #include "cygwin_termios.h" | ||
6 | |||
7 | int tcgetattr(int fd, struct termios *t) | ||
8 | { | ||
9 | t->c_lflag = ECHO; | ||
10 | return 0; | ||
11 | } | ||
12 | |||
13 | |||
14 | int tcsetattr(int fd, int mode, const struct termios *t) | ||
15 | { | ||
16 | return 0; | ||
17 | } | ||
18 | |||
19 | static int get_wincon_width_height(const int fd, int *width, int *height) | ||
20 | { | ||
21 | HANDLE console; | ||
22 | CONSOLE_SCREEN_BUFFER_INFO sbi; | ||
23 | |||
24 | console = GetStdHandle(STD_OUTPUT_HANDLE); | ||
25 | if (console == INVALID_HANDLE_VALUE || !console) | ||
26 | return -1; | ||
27 | |||
28 | GetConsoleScreenBufferInfo(console, &sbi); | ||
29 | |||
30 | if (width) | ||
31 | *width = sbi.srWindow.Right - sbi.srWindow.Left; | ||
32 | if (height) | ||
33 | *height = sbi.srWindow.Bottom - sbi.srWindow.Top; | ||
34 | return 0; | ||
35 | } | ||
36 | |||
37 | int get_terminal_width_height(const int fd, int *width, int *height) | ||
38 | { | ||
39 | return get_wincon_width_height(fd, width, height); | ||
40 | } | ||
41 | |||
42 | int wincon_read(int fd, char *buf, int size) | ||
43 | { | ||
44 | static struct strbuf input = STRBUF_INIT; | ||
45 | HANDLE cin = GetStdHandle(STD_INPUT_HANDLE); | ||
46 | static int initialized = 0; | ||
47 | |||
48 | if (fd != 0) | ||
49 | die("wincon_read is for stdin only"); | ||
50 | if (cin == INVALID_HANDLE_VALUE || is_cygwin_tty(fd)) | ||
51 | return safe_read(fd, buf, size); | ||
52 | if (!initialized) { | ||
53 | SetConsoleMode(cin, ENABLE_ECHO_INPUT); | ||
54 | initialized = 1; | ||
55 | } | ||
56 | while (input.len < size) { | ||
57 | INPUT_RECORD record; | ||
58 | DWORD nevent_out; | ||
59 | int ch; | ||
60 | |||
61 | if (!ReadConsoleInput(cin, &record, 1, &nevent_out)) | ||
62 | return -1; | ||
63 | if (record.EventType != KEY_EVENT || !record.Event.KeyEvent.bKeyDown) | ||
64 | continue; | ||
65 | ch = record.Event.KeyEvent.uChar.AsciiChar; | ||
66 | /* Ctrl-X is handled by ReadConsoleInput, Alt-X is not needed anyway */ | ||
67 | strbuf_addch(&input, ch); | ||
68 | } | ||
69 | memcpy(buf, input.buf, size); | ||
70 | memcpy(input.buf, input.buf+size, input.len-size+1); | ||
71 | strbuf_setlen(&input, input.len-size); | ||
72 | return size; | ||
73 | } | ||
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 06bba0fe3..3d0bec7ac 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c | |||
@@ -625,26 +625,7 @@ void selinux_or_die(void) | |||
625 | 625 | ||
626 | /* It is perfectly ok to pass in a NULL for either width or for | 626 | /* It is perfectly ok to pass in a NULL for either width or for |
627 | * height, in which case that value will not be set. */ | 627 | * height, in which case that value will not be set. */ |
628 | #ifdef __MINGW32__ | 628 | #ifndef __MINGW32__ |
629 | #include <windows.h> | ||
630 | int get_terminal_width_height(const int fd, int *width, int *height) | ||
631 | { | ||
632 | HANDLE console; | ||
633 | CONSOLE_SCREEN_BUFFER_INFO sbi; | ||
634 | |||
635 | console = GetStdHandle(STD_OUTPUT_HANDLE); | ||
636 | if (console == INVALID_HANDLE_VALUE || !console) | ||
637 | return -1; | ||
638 | |||
639 | GetConsoleScreenBufferInfo(console, &sbi); | ||
640 | |||
641 | if (width) | ||
642 | *width = sbi.srWindow.Right - sbi.srWindow.Left; | ||
643 | if (height) | ||
644 | *height = sbi.srWindow.Bottom - sbi.srWindow.Top; | ||
645 | return 0; | ||
646 | } | ||
647 | #else | ||
648 | int get_terminal_width_height(const int fd, int *width, int *height) | 629 | int get_terminal_width_height(const int fd, int *width, int *height) |
649 | { | 630 | { |
650 | struct winsize win = { 0, 0, 0, 0 }; | 631 | struct winsize win = { 0, 0, 0, 0 }; |