diff options
author | Phillip Wood <phillip.wood@dunelm.org.uk> | 2022-03-16 21:54:04 +0300 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-03-16 22:24:44 +0300 |
commit | 6606d99bae4161289d498b51a21acd11aa09e6ef (patch) | |
tree | c22dcea648e0905ef7f38349408747be8732afe9 /compat | |
parent | e4938ce3cc5967c2366db289ca854b0b796a5afd (diff) |
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.c | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/compat/terminal.c b/compat/terminal.c index 4893294eb6..2ae8a6f13e 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); |