summaryrefslogtreecommitdiff
path: root/compat/terminal.c
diff options
context:
space:
mode:
authorJohannes Schindelin <johannes.schindelin@gmx.de>2020-01-14 18:43:48 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-01-15 20:06:17 (GMT)
commit9ea416cb511e87f830462b08ae74b8a78fcca223 (patch)
tree729c74b0d72b0c9bb72daa1c8922ed3584bd4a69 /compat/terminal.c
parent94ac3c31f730ab278e1373a942fb4503829f4279 (diff)
downloadgit-9ea416cb511e87f830462b08ae74b8a78fcca223.zip
git-9ea416cb511e87f830462b08ae74b8a78fcca223.tar.gz
git-9ea416cb511e87f830462b08ae74b8a78fcca223.tar.bz2
terminal: accommodate Git for Windows' default terminal
Git for Windows' Git Bash runs in MinTTY by default, which does not have a Win32 Console instance, but uses MSYS2 pseudo terminals instead. This is a problem, as Git for Windows does not want to use the MSYS2 emulation layer for Git itself, and therefore has no direct way to interact with that pseudo terminal. As a workaround, use the `stty` utility (which is included in Git for Windows, and which *is* an MSYS2 program, so it knows how to deal with the pseudo terminal). Note: If Git runs in a regular CMD or PowerShell window, there *is* a regular Win32 Console to work with. This is not a problem for the MSYS2 `stty`: it copes with this scenario just fine. Also note that we introduce support for more bits than would be necessary for a mere `disable_echo()` here, in preparation for the upcoming `enable_non_canonical()` function. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat/terminal.c')
-rw-r--r--compat/terminal.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/compat/terminal.c b/compat/terminal.c
index 1fb40b3..16e9949 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -2,6 +2,8 @@
#include "compat/terminal.h"
#include "sigchain.h"
#include "strbuf.h"
+#include "run-command.h"
+#include "string-list.h"
#if defined(HAVE_DEV_TTY) || defined(GIT_WINDOWS_NATIVE)
@@ -64,11 +66,28 @@ static int disable_echo(void)
#define OUTPUT_PATH "CONOUT$"
#define FORCE_TEXT "t"
+static int use_stty = 1;
+static struct string_list stty_restore = STRING_LIST_INIT_DUP;
static HANDLE hconin = INVALID_HANDLE_VALUE;
static DWORD cmode;
static void restore_term(void)
{
+ if (use_stty) {
+ int i;
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ if (stty_restore.nr == 0)
+ return;
+
+ argv_array_push(&cp.args, "stty");
+ for (i = 0; i < stty_restore.nr; i++)
+ argv_array_push(&cp.args, stty_restore.items[i].string);
+ run_command(&cp);
+ string_list_clear(&stty_restore, 0);
+ return;
+ }
+
if (hconin == INVALID_HANDLE_VALUE)
return;
@@ -79,6 +98,37 @@ static void restore_term(void)
static int disable_bits(DWORD bits)
{
+ if (use_stty) {
+ struct child_process cp = CHILD_PROCESS_INIT;
+
+ argv_array_push(&cp.args, "stty");
+
+ if (bits & ENABLE_LINE_INPUT) {
+ string_list_append(&stty_restore, "icanon");
+ argv_array_push(&cp.args, "-icanon");
+ }
+
+ if (bits & ENABLE_ECHO_INPUT) {
+ string_list_append(&stty_restore, "echo");
+ argv_array_push(&cp.args, "-echo");
+ }
+
+ if (bits & ENABLE_PROCESSED_INPUT) {
+ string_list_append(&stty_restore, "-ignbrk");
+ string_list_append(&stty_restore, "intr");
+ string_list_append(&stty_restore, "^c");
+ argv_array_push(&cp.args, "ignbrk");
+ argv_array_push(&cp.args, "intr");
+ argv_array_push(&cp.args, "");
+ }
+
+ if (run_command(&cp) == 0)
+ return 0;
+
+ /* `stty` could not be executed; access the Console directly */
+ use_stty = 0;
+ }
+
hconin = CreateFile("CONIN$", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);