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) {62fseek(fh, SEEK_CUR, 0);63putc('\n', fh);64fflush(fh);65}6667restore_term();68fclose(fh);6970if (r == EOF)71return NULL;72return buf.buf;73}7475#else7677char *git_terminal_prompt(const char *prompt, int echo)78{79return getpass(prompt);80}8182#endif