]> git.ipfire.org Git - thirdparty/git.git/commitdiff
terminal: work around macos poll() bug
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Wed, 16 Mar 2022 18:54:04 +0000 (18:54 +0000)
committerJunio C Hamano <gitster@pobox.com>
Wed, 16 Mar 2022 19:24:44 +0000 (12:24 -0700)
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>
compat/terminal.c

index 4893294eb67a304393ca21f606a1643044c52f90..2ae8a6f13e72b4874945553523e9f80dc3d7c25b 100644 (file)
@@ -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);