Skip to content

Commit 6606d99

Browse files
phillipwoodgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent e4938ce commit 6606d99

File tree

1 file changed

+36
-6
lines changed

1 file changed

+36
-6
lines changed

compat/terminal.c

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,31 @@ static int enable_non_canonical(enum save_term_flags flags)
9292
return disable_bits(flags, ICANON | ECHO);
9393
}
9494

95+
/*
96+
* On macos it is not possible to use poll() with a terminal so use select
97+
* instead.
98+
*/
99+
static int getchar_with_timeout(int timeout)
100+
{
101+
struct timeval tv, *tvp = NULL;
102+
fd_set readfds;
103+
int res;
104+
105+
if (timeout >= 0) {
106+
tv.tv_sec = timeout / 1000;
107+
tv.tv_usec = (timeout % 1000) * 1000;
108+
tvp = &tv;
109+
}
110+
111+
FD_ZERO(&readfds);
112+
FD_SET(0, &readfds);
113+
res = select(1, &readfds, NULL, NULL, tvp);
114+
if (res <= 0)
115+
return EOF;
116+
117+
return getchar();
118+
}
119+
95120
#elif defined(GIT_WINDOWS_NATIVE)
96121

97122
#define INPUT_PATH "CONIN$"
@@ -257,6 +282,16 @@ static int mingw_getchar(void)
257282
}
258283
#define getchar mingw_getchar
259284

285+
static int getchar_with_timeout(int timeout)
286+
{
287+
struct pollfd pfd = { .fd = 0, .events = POLLIN };
288+
289+
if (poll(&pfd, 1, timeout) < 1)
290+
return EOF;
291+
292+
return getchar();
293+
}
294+
260295
#endif
261296

262297
#ifndef FORCE_TEXT
@@ -407,12 +442,7 @@ int read_key_without_echo(struct strbuf *buf)
407442
* half a second when we know that the sequence is complete.
408443
*/
409444
while (!is_known_escape_sequence(buf->buf)) {
410-
struct pollfd pfd = { .fd = 0, .events = POLLIN };
411-
412-
if (poll(&pfd, 1, 500) < 1)
413-
break;
414-
415-
ch = getchar();
445+
ch = getchar_with_timeout(500);
416446
if (ch == EOF)
417447
break;
418448
strbuf_addch(buf, ch);

0 commit comments

Comments
 (0)