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(&buf, input_fh, '\n');
127 putc('\n', output_fh);
142 char *git_terminal_prompt(const char *prompt, int echo)
144 return getpass(prompt);