summaryrefslogtreecommitdiff
path: root/compat
diff options
context:
space:
mode:
authorPhillip Wood <phillip.wood@dunelm.org.uk>2022-03-16 18:54:04 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-03-16 19:24:44 (GMT)
commit6606d99bae4161289d498b51a21acd11aa09e6ef (patch)
treec22dcea648e0905ef7f38349408747be8732afe9 /compat
parente4938ce3cc5967c2366db289ca854b0b796a5afd (diff)
downloadgit-6606d99bae4161289d498b51a21acd11aa09e6ef.zip
git-6606d99bae4161289d498b51a21acd11aa09e6ef.tar.gz
git-6606d99bae4161289d498b51a21acd11aa09e6ef.tar.bz2
terminal: work around macos poll() bug
On macos the builtin "add -p" does not handle keys that generate escape sequences because poll() does not work with terminals there. Switch to using select() on non-windows platforms to work around this. Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'compat')
-rw-r--r--compat/terminal.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/compat/terminal.c b/compat/terminal.c
index 4893294..2ae8a6f 100644
--- a/compat/terminal.c
+++ b/compat/terminal.c
@@ -92,6 +92,31 @@ static int enable_non_canonical(enum save_term_flags flags)
return disable_bits(flags, ICANON | ECHO);
}
+/*
+ * On macos it is not possible to use poll() with a terminal so use select
+ * instead.
+ */
+static int getchar_with_timeout(int timeout)
+{
+ struct timeval tv, *tvp = NULL;
+ fd_set readfds;
+ int res;
+
+ if (timeout >= 0) {
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+ tvp = &tv;
+ }
+
+ FD_ZERO(&readfds);
+ FD_SET(0, &readfds);
+ res = select(1, &readfds, NULL, NULL, tvp);
+ if (res <= 0)
+ return EOF;
+
+ return getchar();
+}
+
#elif defined(GIT_WINDOWS_NATIVE)
#define INPUT_PATH "CONIN$"
@@ -257,6 +282,16 @@ static int mingw_getchar(void)
}
#define getchar mingw_getchar
+static int getchar_with_timeout(int timeout)
+{
+ struct pollfd pfd = { .fd = 0, .events = POLLIN };
+
+ if (poll(&pfd, 1, timeout) < 1)
+ return EOF;
+
+ return getchar();
+}
+
#endif
#ifndef FORCE_TEXT
@@ -407,12 +442,7 @@ int read_key_without_echo(struct strbuf *buf)
* half a second when we know that the sequence is complete.
*/
while (!is_known_escape_sequence(buf->buf)) {
- struct pollfd pfd = { .fd = 0, .events = POLLIN };
-
- if (poll(&pfd, 1, 500) < 1)
- break;
-
- ch = getchar();
+ ch = getchar_with_timeout(500);
if (ch == EOF)
break;
strbuf_addch(buf, ch);