1#include "git-compat-util.h"
2#include "compat/terminal.h"
3#include "sigchain.h"
4#include "strbuf.h"
56
#ifdef HAVE_DEV_TTY
78
static int term_fd = -1;
9static struct termios old_term;
1011
static void restore_term(void)
12{
13if (term_fd < 0)
14return;
1516
tcsetattr(term_fd, TCSAFLUSH, &old_term);
17term_fd = -1;
18}
1920
static void restore_term_on_signal(int sig)
21{
22restore_term();
23sigchain_pop(sig);
24raise(sig);
25}
2627
char *git_terminal_prompt(const char *prompt, int echo)
28{
29static struct strbuf buf = STRBUF_INIT;
30int r;
31FILE *fh;
3233
fh = fopen("/dev/tty", "w+");
34if (!fh)
35return NULL;
3637
if (!echo) {
38struct termios t;
3940
if (tcgetattr(fileno(fh), &t) < 0) {
41fclose(fh);
42return NULL;
43}
4445
old_term = t;
46term_fd = fileno(fh);
47sigchain_push_common(restore_term_on_signal);
4849
t.c_lflag &= ~ECHO;
50if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) {
51term_fd = -1;
52fclose(fh);
53return NULL;
54}
55}
5657
fputs(prompt, fh);
58fflush(fh);
5960
r = strbuf_getline(&buf, fh, '\n');
61if (!echo) {
62fseek(fh, SEEK_CUR, 0);
63putc('\n', fh);
64fflush(fh);
65}
6667
restore_term();
68fclose(fh);
6970
if (r == EOF)
71return NULL;
72return buf.buf;
73}
7475
#else
7677
char *git_terminal_prompt(const char *prompt, int echo)
78{
79return getpass(prompt);
80}
8182
#endif