merge(third_party/git): Merge squashed git subtree at v2.23.0
Merge commit '1b593e1ea4' as 'third_party/git'
This commit is contained in:
commit
7ef0d62730
3629 changed files with 1139935 additions and 0 deletions
147
third_party/git/compat/terminal.c
vendored
Normal file
147
third_party/git/compat/terminal.c
vendored
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#include "git-compat-util.h"
|
||||
#include "compat/terminal.h"
|
||||
#include "sigchain.h"
|
||||
#include "strbuf.h"
|
||||
|
||||
#if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)
|
||||
|
||||
static void restore_term(void);
|
||||
|
||||
static void restore_term_on_signal(int sig)
|
||||
{
|
||||
restore_term();
|
||||
sigchain_pop(sig);
|
||||
raise(sig);
|
||||
}
|
||||
|
||||
#ifdef HAVE_DEV_TTY
|
||||
|
||||
#define INPUT_PATH "/dev/tty"
|
||||
#define OUTPUT_PATH "/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);
|
||||
close(term_fd);
|
||||
term_fd = -1;
|
||||
}
|
||||
|
||||
static int disable_echo(void)
|
||||
{
|
||||
struct termios t;
|
||||
|
||||
term_fd = open("/dev/tty", O_RDWR);
|
||||
if (tcgetattr(term_fd, &t) < 0)
|
||||
goto error;
|
||||
|
||||
old_term = t;
|
||||
sigchain_push_common(restore_term_on_signal);
|
||||
|
||||
t.c_lflag &= ~ECHO;
|
||||
if (!tcsetattr(term_fd, TCSAFLUSH, &t))
|
||||
return 0;
|
||||
|
||||
error:
|
||||
close(term_fd);
|
||||
term_fd = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#elif defined(GIT_WINDOWS_NATIVE)
|
||||
|
||||
#define INPUT_PATH "CONIN$"
|
||||
#define OUTPUT_PATH "CONOUT$"
|
||||
#define FORCE_TEXT "t"
|
||||
|
||||
static HANDLE hconin = INVALID_HANDLE_VALUE;
|
||||
static DWORD cmode;
|
||||
|
||||
static void restore_term(void)
|
||||
{
|
||||
if (hconin == INVALID_HANDLE_VALUE)
|
||||
return;
|
||||
|
||||
SetConsoleMode(hconin, cmode);
|
||||
CloseHandle(hconin);
|
||||
hconin = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static int disable_echo(void)
|
||||
{
|
||||
hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (hconin == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
GetConsoleMode(hconin, &cmode);
|
||||
sigchain_push_common(restore_term_on_signal);
|
||||
if (!SetConsoleMode(hconin, cmode & (~ENABLE_ECHO_INPUT))) {
|
||||
CloseHandle(hconin);
|
||||
hconin = INVALID_HANDLE_VALUE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef FORCE_TEXT
|
||||
#define FORCE_TEXT
|
||||
#endif
|
||||
|
||||
char *git_terminal_prompt(const char *prompt, int echo)
|
||||
{
|
||||
static struct strbuf buf = STRBUF_INIT;
|
||||
int r;
|
||||
FILE *input_fh, *output_fh;
|
||||
|
||||
input_fh = fopen(INPUT_PATH, "r" FORCE_TEXT);
|
||||
if (!input_fh)
|
||||
return NULL;
|
||||
|
||||
output_fh = fopen(OUTPUT_PATH, "w" FORCE_TEXT);
|
||||
if (!output_fh) {
|
||||
fclose(input_fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!echo && disable_echo()) {
|
||||
fclose(input_fh);
|
||||
fclose(output_fh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fputs(prompt, output_fh);
|
||||
fflush(output_fh);
|
||||
|
||||
r = strbuf_getline_lf(&buf, input_fh);
|
||||
if (!echo) {
|
||||
putc('\n', output_fh);
|
||||
fflush(output_fh);
|
||||
}
|
||||
|
||||
restore_term();
|
||||
fclose(input_fh);
|
||||
fclose(output_fh);
|
||||
|
||||
if (r == EOF)
|
||||
return NULL;
|
||||
return buf.buf;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
char *git_terminal_prompt(const char *prompt, int echo)
|
||||
{
|
||||
return getpass(prompt);
|
||||
}
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue