99#include <errno.h>
1010#include <limits.h>
1111#include <locale.h>
12- #include <poll.h>
1312#include <signal.h>
1413#include <stdio.h>
1514#include <stdlib.h>
@@ -70,13 +69,15 @@ struct choice {
7069 double score ;
7170};
7271
72+ int tty_getc_peek = -1 ;
73+
7374static int choice_cmp (const void * , const void * );
7475static const char * choice_description (const struct choice * );
7576static const char * choice_string (const struct choice * );
7677static void delete_between (char * , size_t , size_t , size_t );
7778static char * eager_strpbrk (const char * , const char * );
7879static int filter_choices (size_t );
79- static size_t get_choices (int , size_t );
80+ static size_t get_choices (int , ssize_t );
8081static enum key get_key (const char * * );
8182static void handle_sigwinch (int );
8283static int isu8cont (unsigned char );
@@ -224,7 +225,7 @@ usage(int status)
224225}
225226
226227size_t
227- get_choices (int fd , size_t insert )
228+ get_choices (int fd , ssize_t insert )
228229{
229230 static const char * ifs ;
230231 static char * buf ;
@@ -291,7 +292,7 @@ get_choices(int fd, size_t insert)
291292 }
292293 offset = start - buf ;
293294 dchoices = choices .length - nchoices ;
294- if (dchoices == 0 || nchoices == 0 )
295+ if (dchoices == 0 || nchoices == 0 || insert == -1 )
295296 return n ;
296297
297298 /* Move new choices after the given insert index. */
@@ -323,66 +324,53 @@ eager_strpbrk(const char *string, const char *separators)
323324const struct choice *
324325selected_choice (void )
325326{
326- struct pollfd fds [2 ];
327327 const char * buf ;
328- size_t cursor_position , i , j , length , nfds , xscroll ;
328+ ssize_t insert ;
329+ size_t cursor_position , i , j , length , xscroll ;
329330 size_t choices_count = 0 ;
330331 size_t selection = 0 ;
331332 size_t yscroll = 0 ;
332- int dokey , doread , timo ;
333+ int fd , ready , timo ;
333334 int choices_reset = 1 ;
334335 int dochoices = 0 ;
335336 int dofilter = 1 ;
336337
337338 cursor_position = query_length ;
338339
339- fds [0 ].fd = fileno (tty_in );
340- fds [0 ].events = POLLIN ;
341- fds [1 ].fd = STDIN_FILENO ;
342- fds [1 ].events = POLLIN ;
343- nfds = 2 ;
344- /* No timeout on first call to poll in order to render the UI fast. */
340+ /* No timeout on first call to fdwait in order to render the UI fast. */
345341 timo = 0 ;
342+ fd = STDIN_FILENO ;
346343 for (;;) {
347- dokey = doread = 0 ;
348344 toggle_sigwinch (1 );
349- if (poll (fds , nfds , timo ) == -1 && errno != EINTR )
350- err (1 , "poll" );
345+ ready = fdwait (fileno (tty_in ), fd , timo );
346+ if (ready == -1 ) {
347+ if (errno == EINTR )
348+ ready = 0 ;
349+ else
350+ err (1 , "fdwait" );
351+ }
351352 toggle_sigwinch (0 );
352353 if (gotsigwinch ) {
353354 gotsigwinch = 0 ;
354355 goto resize ;
355356 }
356357 timo = -1 ;
357- for (i = 0 ; i < nfds ; i ++ ) {
358- if (fds [i ].revents & (POLLERR | POLLNVAL ))
359- errx (1 , "%d: bad file descriptor" , fds [i ].fd );
360- if ((fds [i ].revents & (POLLIN | POLLHUP )) == 0 )
361- continue ;
362-
363- if (fds [i ].fd == fds [0 ].fd )
364- dokey = 1 ;
365- else if (fds [i ].fd == fds [1 ].fd )
366- doread = 1 ;
367- }
368358
369359 length = choices .length ;
370- if (doread ) {
371- if ( get_choices ( STDIN_FILENO , query_length > 0 ?
372- choices_count : 0 )) {
360+ if (ready & FD_STDIN_READY ) {
361+ insert = query_length > 0 ? choices_count : -1 ;
362+ if ( get_choices ( STDIN_FILENO , insert )) {
373363 if (query_length > 0 ) {
374364 dofilter = 1 ;
375365 choices_reset = 0 ;
376366 choices_count += choices .length -
377367 length ;
378368 }
379369 } else {
380- nfds = 1 ; /* EOF */
370+ fd = - 1 ; /* EOF */
381371 }
382372 }
383- if (!dokey && query_length == 0 && length >= choices_lines )
384- continue ; /* prevent redundant rendering */
385- if (!dokey )
373+ if ((ready & FD_TTY_READY ) == 0 )
386374 goto render ;
387375
388376 switch (get_key (& buf )) {
590578filter_choices (size_t nchoices )
591579{
592580 struct choice * c ;
593- struct pollfd pfd ;
594581 size_t i , match_length ;
595- int nready ;
582+ int ready ;
596583
597584 for (i = 0 ; i < nchoices ; i ++ ) {
598585 c = & choices .v [i ];
@@ -608,11 +595,8 @@ filter_choices(size_t nchoices)
608595 }
609596
610597 if (i > 0 && i % 50 == 0 ) {
611- pfd .fd = fileno (tty_in );
612- pfd .events = POLLIN ;
613- if ((nready = poll (& pfd , 1 , 0 )) == -1 )
614- err (1 , "poll" );
615- if (nready == 1 && pfd .revents & (POLLIN | POLLHUP ))
598+ ready = fdwait (fileno (tty_in ), -1 , 0 );
599+ if (ready != -1 && (ready & FD_TTY_READY ) != 0 )
616600 return 0 ;
617601 }
618602 }
@@ -1116,6 +1100,12 @@ tty_getc(void)
11161100 ssize_t n ;
11171101 unsigned char c ;
11181102
1103+ if (tty_getc_peek != -1 ) {
1104+ c = tty_getc_peek ;
1105+ tty_getc_peek = -1 ;
1106+ return c ;
1107+ }
1108+
11191109 n = read (fileno (tty_in ), & c , sizeof (c ));
11201110 if (n == -1 )
11211111 err (1 , "read" );
0 commit comments