#include "git-compat-util.h" | |
#include "compat/terminal.h" | |
#include "sigchain.h" | |
#include "strbuf.h" | |
#ifdef HAVE_DEV_TTY | |
static int term_fd = -1; | |
static struct termios old_term; | |
static void restore_term(void) | |
{ | |
if (term_fd < 0) | |
return; | |
tcsetattr(term_fd, TCSAFLUSH, &old_term); | |
term_fd = -1; | |
} | |
static void restore_term_on_signal(int sig) | |
{ | |
restore_term(); | |
sigchain_pop(sig); | |
raise(sig); | |
} | |
char *git_terminal_prompt(const char *prompt, int echo) | |
{ | |
static struct strbuf buf = STRBUF_INIT; | |
int r; | |
FILE *fh; | |
fh = fopen("/dev/tty", "w+"); | |
if (!fh) | |
return NULL; | |
if (!echo) { | |
struct termios t; | |
if (tcgetattr(fileno(fh), &t) < 0) { | |
fclose(fh); | |
return NULL; | |
} | |
old_term = t; | |
term_fd = fileno(fh); | |
sigchain_push_common(restore_term_on_signal); | |
t.c_lflag &= ~ECHO; | |
if (tcsetattr(fileno(fh), TCSAFLUSH, &t) < 0) { | |
term_fd = -1; | |
fclose(fh); | |
return NULL; | |
} | |
} | |
fputs(prompt, fh); | |
fflush(fh); | |
r = strbuf_getline(&buf, fh, '\n'); | |
if (!echo) { | |
putc('\n', fh); | |
fflush(fh); | |
} | |
restore_term(); | |
fclose(fh); | |
if (r == EOF) | |
return NULL; | |
return buf.buf; | |
} | |
#else | |
char *git_terminal_prompt(const char *prompt, int echo) | |
{ | |
return getpass(prompt); | |
} | |
#endif |