From 52ab139ca3a14c54c96e1a77b7b8003e64df7071 Mon Sep 17 00:00:00 2001 From: Raheman Vaiya Date: Wed, 31 Aug 2022 21:14:41 -0400 Subject: [PATCH] monitor: Drain stdin on exit --- src/evloop.c | 6 ++++-- src/keyd.h | 1 + src/monitor.c | 31 ++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/evloop.c b/src/evloop.c index 2b59b4e..be28970 100644 --- a/src/evloop.c +++ b/src/evloop.c @@ -115,8 +115,10 @@ int evloop(int (*event_handler) (struct event *ev)) } for (i = 0; i < nr_aux_fds; i++) { - if (pfds[i+ndevs+1].revents) { - ev.type = EV_FD_ACTIVITY; + short events = pfds[i+ndevs+1].revents; + + if (events) { + ev.type = events & POLLERR ? EV_FD_ERR : EV_FD_ACTIVITY; ev.fd = aux_fds[i]; timeout = event_handler(&ev); diff --git a/src/keyd.h b/src/keyd.h index cdad0f8..573d700 100644 --- a/src/keyd.h +++ b/src/keyd.h @@ -52,6 +52,7 @@ enum event_type { EV_DEV_REMOVE, EV_DEV_EVENT, EV_FD_ACTIVITY, + EV_FD_ERR, EV_TIMEOUT, }; diff --git a/src/monitor.c b/src/monitor.c index 32e0045..d27815a 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -1,25 +1,31 @@ #include "keyd.h" -static void set_echo(int set) +static void set_tflags(tcflag_t flags, int val) { - if (!isatty(1)) + if (!isatty(0)) return; struct termios tinfo; - tcgetattr(1, &tinfo); + tcgetattr(0, &tinfo); - if (set) - tinfo.c_lflag |= ECHO; + if (val) + tinfo.c_lflag |= flags; else - tinfo.c_lflag &= ~ECHO; + tinfo.c_lflag &= ~flags; - tcsetattr(1, TCSANOW, &tinfo); + tcsetattr(0, TCSANOW, &tinfo); } static void cleanup() { - set_echo(1); + /* Drain STDIN (useful for scripting). */ + set_tflags(ICANON, 0); + char buf[4096]; + fcntl(0, F_SETFL, O_NONBLOCK); + while(read(0, buf, sizeof buf) > 0) {} + + set_tflags(ICANON|ECHO, 1); } int event_handler(struct event *ev) @@ -47,7 +53,7 @@ int event_handler(struct event *ev) ev->dev->product_id, name, ev->devev->pressed ? "down" : "up"); } break; - case EV_FD_ACTIVITY: + case EV_FD_ERR: exit(0); break; default: @@ -62,9 +68,12 @@ int event_handler(struct event *ev) int monitor(int argc, char *argv[]) { - set_echo(0); + if (isatty(1)) + set_tflags(ECHO, 0); - evloop_add_fd(1); + /* Eagerly terminate on pipe closures. */ + if (!isatty(1)) + evloop_add_fd(1); setvbuf(stdout, NULL, _IOLBF, 0); setvbuf(stderr, NULL, _IOLBF, 0);