@@ -25,25 +25,38 @@ static void restore_term_on_signal(int sig)
25
25
static int term_fd = -1 ;
26
26
static struct termios old_term ;
27
27
28
- static void restore_term (void )
28
+ void pop_term (void )
29
29
{
30
30
if (term_fd < 0 )
31
31
return ;
32
32
33
33
tcsetattr (term_fd , TCSAFLUSH , & old_term );
34
+ }
35
+
36
+ static void restore_term (void )
37
+ {
38
+ pop_term ();
39
+
34
40
close (term_fd );
35
41
term_fd = -1 ;
36
42
}
37
43
44
+ int push_term (int full_duplex )
45
+ {
46
+ if (term_fd < 0 )
47
+ term_fd = open ("/dev/tty" , O_RDWR );
48
+
49
+ return (term_fd < 0 ) ? -1 : tcgetattr (term_fd , & old_term );
50
+ }
51
+
38
52
static int disable_bits (tcflag_t bits )
39
53
{
40
54
struct termios t ;
41
55
42
- term_fd = open ("/dev/tty" , O_RDWR );
43
- if (tcgetattr (term_fd , & t ) < 0 )
56
+ if (push_term (0 ) < 0 )
44
57
goto error ;
45
58
46
- old_term = t ;
59
+ t = old_term ;
47
60
sigchain_push_common (restore_term_on_signal );
48
61
49
62
t .c_lflag &= ~bits ;
@@ -75,7 +88,22 @@ static int enable_non_canonical(void)
75
88
static int use_stty = 1 ;
76
89
static struct string_list stty_restore = STRING_LIST_INIT_DUP ;
77
90
static HANDLE hconin = INVALID_HANDLE_VALUE ;
78
- static DWORD cmode ;
91
+ static HANDLE hconout = INVALID_HANDLE_VALUE ;
92
+ static DWORD cmode_in , cmode_out ;
93
+
94
+ void pop_term (void )
95
+ {
96
+ if (hconin == INVALID_HANDLE_VALUE )
97
+ return ;
98
+
99
+ SetConsoleMode (hconin , cmode_in );
100
+ CloseHandle (hconin );
101
+ if (cmode_out ) {
102
+ assert (hconout != INVALID_HANDLE_VALUE );
103
+ SetConsoleMode (hconout , cmode_out );
104
+ CloseHandle (hconout );
105
+ }
106
+ }
79
107
80
108
static void restore_term (void )
81
109
{
@@ -94,12 +122,34 @@ static void restore_term(void)
94
122
return ;
95
123
}
96
124
125
+ pop_term ();
126
+ hconin = hconout = INVALID_HANDLE_VALUE ;
127
+ }
128
+
129
+ int push_term (int full_duplex )
130
+ {
131
+ hconin = CreateFileA ("CONIN$" , GENERIC_READ | GENERIC_WRITE ,
132
+ FILE_SHARE_READ , NULL , OPEN_EXISTING ,
133
+ FILE_ATTRIBUTE_NORMAL , NULL );
97
134
if (hconin == INVALID_HANDLE_VALUE )
98
- return ;
135
+ return -1 ;
136
+
137
+ if (full_duplex ) {
138
+ hconout = CreateFileA ("CONOUT$" , GENERIC_READ | GENERIC_WRITE ,
139
+ FILE_SHARE_WRITE , NULL , OPEN_EXISTING ,
140
+ FILE_ATTRIBUTE_NORMAL , NULL );
141
+ if (hconout == INVALID_HANDLE_VALUE )
142
+ goto error ;
99
143
100
- SetConsoleMode (hconin , cmode );
144
+ GetConsoleMode (hconout , & cmode_out );
145
+ }
146
+
147
+ GetConsoleMode (hconin , & cmode_in );
148
+ return 0 ;
149
+ error :
101
150
CloseHandle (hconin );
102
151
hconin = INVALID_HANDLE_VALUE ;
152
+ return -1 ;
103
153
}
104
154
105
155
static int disable_bits (DWORD bits )
@@ -135,15 +185,11 @@ static int disable_bits(DWORD bits)
135
185
use_stty = 0 ;
136
186
}
137
187
138
- hconin = CreateFile ("CONIN$" , GENERIC_READ | GENERIC_WRITE ,
139
- FILE_SHARE_READ , NULL , OPEN_EXISTING ,
140
- FILE_ATTRIBUTE_NORMAL , NULL );
141
- if (hconin == INVALID_HANDLE_VALUE )
188
+ if (push_term (0 ) < 0 )
142
189
return -1 ;
143
190
144
- GetConsoleMode (hconin , & cmode );
145
191
sigchain_push_common (restore_term_on_signal );
146
- if (!SetConsoleMode (hconin , cmode & ~bits )) {
192
+ if (!SetConsoleMode (hconin , cmode_in & ~bits )) {
147
193
CloseHandle (hconin );
148
194
hconin = INVALID_HANDLE_VALUE ;
149
195
return -1 ;
0 commit comments