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