1 #include "git-compat-util.h"
2 #include "compat/terminal.h"
6 #if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)
8 static void restore_term(void);
10 static void restore_term_on_signal(int sig
)
19 #define INPUT_PATH "/dev/tty"
20 #define OUTPUT_PATH "/dev/tty"
22 static int term_fd
= -1;
23 static struct termios old_term
;
25 static void restore_term(void)
30 tcsetattr(term_fd
, TCSAFLUSH
, &old_term
);
35 static int disable_echo(void)
39 term_fd
= open("/dev/tty", O_RDWR
);
40 if (tcgetattr(term_fd
, &t
) < 0)
44 sigchain_push_common(restore_term_on_signal
);
47 if (!tcsetattr(term_fd
, TCSAFLUSH
, &t
))
56 #elif defined(GIT_WINDOWS_NATIVE)
58 #define INPUT_PATH "CONIN$"
59 #define OUTPUT_PATH "CONOUT$"
60 #define FORCE_TEXT "t"
62 static HANDLE hconin
= INVALID_HANDLE_VALUE
;
65 static void restore_term(void)
67 if (hconin
== INVALID_HANDLE_VALUE
)
70 SetConsoleMode(hconin
, cmode
);
72 hconin
= INVALID_HANDLE_VALUE
;
75 static int disable_echo(void)
77 hconin
= CreateFile("CONIN$", GENERIC_READ
| GENERIC_WRITE
,
78 FILE_SHARE_READ
, NULL
, OPEN_EXISTING
,
79 FILE_ATTRIBUTE_NORMAL
, NULL
);
80 if (hconin
== INVALID_HANDLE_VALUE
)
83 GetConsoleMode(hconin
, &cmode
);
84 sigchain_push_common(restore_term_on_signal
);
85 if (!SetConsoleMode(hconin
, cmode
& (~ENABLE_ECHO_INPUT
))) {
87 hconin
= INVALID_HANDLE_VALUE
;
100 char *git_terminal_prompt(const char *prompt
, int echo
)
102 static struct strbuf buf
= STRBUF_INIT
;
104 FILE *input_fh
, *output_fh
;
106 input_fh
= fopen(INPUT_PATH
, "r" FORCE_TEXT
);
110 output_fh
= fopen(OUTPUT_PATH
, "w" FORCE_TEXT
);
116 if (!echo
&& disable_echo()) {
122 fputs(prompt
, output_fh
);
125 r
= strbuf_getline_lf(&buf
, input_fh
);
127 putc('\n', output_fh
);
142 char *git_terminal_prompt(const char *prompt
, int echo
)
144 return getpass(prompt
);