summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compat/terminal.c42
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);