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) {
62putc('\n', fh);
63fflush(fh);
64}
6566
restore_term();
67fclose(fh);
6869
if (r == EOF)
70return NULL;
71return buf.buf;
72}
7374
#else
7576
char *git_terminal_prompt(const char *prompt, int echo)
77{
78return getpass(prompt);
79}
8081
#endif