summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
Diffstat (limited to 'compat')
-rw-r--r--compat/terminal.c55
-rw-r--r--compat/terminal.h3
2 files changed, 58 insertions, 0 deletions
diff --git a/compat/terminal.c b/compat/terminal.c
index 16e9949da1..1b2564042a 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -60,6 +60,11 @@ static int disable_echo(void)
return disable_bits(ECHO);
}
+static int enable_non_canonical(void)
+{
+ return disable_bits(ICANON | ECHO);
+}
+
#elif defined(GIT_WINDOWS_NATIVE)
#define INPUT_PATH "CONIN$"
@@ -151,6 +156,10 @@ static int disable_echo(void)
return disable_bits(ENABLE_ECHO_INPUT);
}
+static int enable_non_canonical(void)
+{
+ return disable_bits(ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT);
+}
#endif
@@ -198,6 +207,33 @@ char *git_terminal_prompt(const char *prompt, int echo)
return buf.buf;
}
+int read_key_without_echo(struct strbuf *buf)
+{
+ static int warning_displayed;
+ int ch;
+
+ if (warning_displayed || enable_non_canonical() < 0) {
+ if (!warning_displayed) {
+ warning("reading single keystrokes not supported on "
+ "this platform; reading line instead");
+ warning_displayed = 1;
+ }
+
+ return strbuf_getline(buf, stdin);
+ }
+
+ strbuf_reset(buf);
+ ch = getchar();
+ if (ch == EOF) {
+ restore_term();
+ return EOF;
+ }
+
+ strbuf_addch(buf, ch);
+ restore_term();
+ return 0;
+}
+
#else
char *git_terminal_prompt(const char *prompt, int echo)
@@ -205,4 +241,23 @@ char *git_terminal_prompt(const char *prompt, int echo)
return getpass(prompt);
}
+int read_key_without_echo(struct strbuf *buf)
+{
+ static int warning_displayed;
+ const char *res;
+
+ if (!warning_displayed) {
+ warning("reading single keystrokes not supported on this "
+ "platform; reading line instead");
+ warning_displayed = 1;
+ }
+
+ res = getpass("");
+ strbuf_reset(buf);
+ if (!res)
+ return EOF;
+ strbuf_addstr(buf, res);
+ return 0;
+}
+
#endif
diff --git a/compat/terminal.h b/compat/terminal.h
index 97db7cd69d..a9d52b8464 100644
--- a/compat/terminal.h
+++ b/compat/terminal.h
@@ -3,4 +3,7 @@
char *git_terminal_prompt(const char *prompt, int echo);
+/* Read a single keystroke, without echoing it to the terminal */
+int read_key_without_echo(struct strbuf *buf);
+
#endif /* COMPAT_TERMINAL_H */