8
8
9
9
#if defined(HAVE_DEV_TTY ) || defined(GIT_WINDOWS_NATIVE )
10
10
11
- static void restore_term (void );
12
-
13
11
static void restore_term_on_signal (int sig )
14
12
{
15
13
restore_term ();
@@ -25,7 +23,7 @@ static void restore_term_on_signal(int sig)
25
23
static int term_fd = -1 ;
26
24
static struct termios old_term ;
27
25
28
- static void restore_term (void )
26
+ void restore_term (void )
29
27
{
30
28
if (term_fd < 0 )
31
29
return ;
@@ -35,15 +33,22 @@ static void restore_term(void)
35
33
term_fd = -1 ;
36
34
}
37
35
36
+ int save_term (int full_duplex )
37
+ {
38
+ if (term_fd < 0 )
39
+ term_fd = open ("/dev/tty" , O_RDWR );
40
+
41
+ return (term_fd < 0 ) ? -1 : tcgetattr (term_fd , & old_term );
42
+ }
43
+
38
44
static int disable_bits (tcflag_t bits )
39
45
{
40
46
struct termios t ;
41
47
42
- term_fd = open ("/dev/tty" , O_RDWR );
43
- if (tcgetattr (term_fd , & t ) < 0 )
48
+ if (save_term (0 ) < 0 )
44
49
goto error ;
45
50
46
- old_term = t ;
51
+ t = old_term ;
47
52
sigchain_push_common (restore_term_on_signal );
48
53
49
54
t .c_lflag &= ~bits ;
@@ -75,9 +80,10 @@ static int enable_non_canonical(void)
75
80
static int use_stty = 1 ;
76
81
static struct string_list stty_restore = STRING_LIST_INIT_DUP ;
77
82
static HANDLE hconin = INVALID_HANDLE_VALUE ;
78
- static DWORD cmode ;
83
+ static HANDLE hconout = INVALID_HANDLE_VALUE ;
84
+ static DWORD cmode_in , cmode_out ;
79
85
80
- static void restore_term (void )
86
+ void restore_term (void )
81
87
{
82
88
if (use_stty ) {
83
89
int i ;
@@ -97,9 +103,42 @@ static void restore_term(void)
97
103
if (hconin == INVALID_HANDLE_VALUE )
98
104
return ;
99
105
100
- SetConsoleMode (hconin , cmode );
106
+ SetConsoleMode (hconin , cmode_in );
107
+ CloseHandle (hconin );
108
+ if (cmode_out ) {
109
+ assert (hconout != INVALID_HANDLE_VALUE );
110
+ SetConsoleMode (hconout , cmode_out );
111
+ CloseHandle (hconout );
112
+ }
113
+
114
+ hconin = hconout = INVALID_HANDLE_VALUE ;
115
+ }
116
+
117
+ int save_term (int full_duplex )
118
+ {
119
+ hconin = CreateFileA ("CONIN$" , GENERIC_READ | GENERIC_WRITE ,
120
+ FILE_SHARE_READ , NULL , OPEN_EXISTING ,
121
+ FILE_ATTRIBUTE_NORMAL , NULL );
122
+ if (hconin == INVALID_HANDLE_VALUE )
123
+ return -1 ;
124
+
125
+ if (full_duplex ) {
126
+ hconout = CreateFileA ("CONOUT$" , GENERIC_READ | GENERIC_WRITE ,
127
+ FILE_SHARE_WRITE , NULL , OPEN_EXISTING ,
128
+ FILE_ATTRIBUTE_NORMAL , NULL );
129
+ if (hconout == INVALID_HANDLE_VALUE )
130
+ goto error ;
131
+
132
+ GetConsoleMode (hconout , & cmode_out );
133
+ }
134
+
135
+ GetConsoleMode (hconin , & cmode_in );
136
+ use_stty = 0 ;
137
+ return 0 ;
138
+ error :
101
139
CloseHandle (hconin );
102
140
hconin = INVALID_HANDLE_VALUE ;
141
+ return -1 ;
103
142
}
104
143
105
144
static int disable_bits (DWORD bits )
@@ -135,15 +174,11 @@ static int disable_bits(DWORD bits)
135
174
use_stty = 0 ;
136
175
}
137
176
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 )
177
+ if (save_term (0 ) < 0 )
142
178
return -1 ;
143
179
144
- GetConsoleMode (hconin , & cmode );
145
180
sigchain_push_common (restore_term_on_signal );
146
- if (!SetConsoleMode (hconin , cmode & ~bits )) {
181
+ if (!SetConsoleMode (hconin , cmode_in & ~bits )) {
147
182
CloseHandle (hconin );
148
183
hconin = INVALID_HANDLE_VALUE ;
149
184
return -1 ;
@@ -361,6 +396,16 @@ int read_key_without_echo(struct strbuf *buf)
361
396
362
397
#else
363
398
399
+ int save_term (int full_duplex )
400
+ {
401
+ /* full_duplex == 1, but no support available */
402
+ return - full_duplex ;
403
+ }
404
+
405
+ void restore_term (void )
406
+ {
407
+ }
408
+
364
409
char * git_terminal_prompt (const char * prompt , int echo )
365
410
{
366
411
return getpass (prompt );
0 commit comments