From 61bb69795d3d343196eb8c5b3e27c0b8ec205a3c Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Sat, 21 Oct 2017 19:55:17 +0200 Subject: [PATCH] Use FIONREAD to detect if stdin has data, safer than just select() When handling the stdin redirect workaround we should use FIONREAD to figure out if there is any data to read. When there is no more data to read from stdin we remove the watcher from internal bookkeeping but allow the callback to run one last time so it can detect a short read. Signed-off-by: Joachim Nilsson --- src/uev.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/uev.c b/src/uev.c index 1c71804..89d5e5a 100644 --- a/src/uev.c +++ b/src/uev.c @@ -26,6 +26,7 @@ #include /* O_CLOEXEC */ #include /* memset() */ #include +#include #include /* for select() workaround */ #include /* struct signalfd_siginfo */ #include /* close(), read() */ @@ -62,11 +63,15 @@ static int has_data(int fd) { struct timeval timeout = { 0, 0 }; fd_set fds; + int n = 0; FD_ZERO(&fds); FD_SET(fd, &fds); - return select(1, &fds, NULL, NULL, &timeout) > 0; + if (select(1, &fds, NULL, NULL, &timeout) > 0) + return ioctl(0, FIONREAD, &n) == 0 && n > 0; + + return 0; } /* Private to libuEv, do not use directly! */ @@ -292,7 +297,6 @@ int uev_run(uev_ctx_t *ctx, int flags) if (!has_data(w->fd)) { w->active = 0; LIST_REMOVE(w, link); - continue; } rerun++;