From: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> We allow timeout units to be specified in microseconds but for poll() we need to round them up to milliseconds. Switch to ppoll() to avoid losing precision. Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@xxxxxxxxxx> Reviewed-by: Kent Gibson <warthog618@xxxxxxxxx> --- tools/gpiomon.c | 12 ++++++++++-- tools/gpionotify.c | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tools/gpiomon.c b/tools/gpiomon.c index 40e6ac2..7135843 100644 --- a/tools/gpiomon.c +++ b/tools/gpiomon.c @@ -176,7 +176,7 @@ static int parse_config(int argc, char **argv, struct config *cfg) cfg->fmt = optarg; break; case 'i': - cfg->idle_timeout = parse_period_or_die(optarg) / 1000; + cfg->idle_timeout = parse_period_or_die(optarg); break; case 'l': cfg->active_low = true; @@ -362,6 +362,7 @@ int main(int argc, char **argv) int num_lines, events_done = 0; struct gpiod_edge_event *event; struct line_resolver *resolver; + struct timespec idle_timeout; struct gpiod_chip *chip; struct pollfd *pollfds; unsigned int *offsets; @@ -450,10 +451,17 @@ int main(int argc, char **argv) if (cfg.banner) print_banner(argc, argv); + if (cfg.idle_timeout > 0) { + idle_timeout.tv_sec = cfg.idle_timeout / 1000000; + idle_timeout.tv_nsec = + (cfg.idle_timeout % 1000000) * 1000; + } + for (;;) { fflush(stdout); - ret = poll(pollfds, resolver->num_chips, cfg.idle_timeout); + ret = ppoll(pollfds, resolver->num_chips, + cfg.idle_timeout > 0 ? &idle_timeout : NULL, NULL); if (ret < 0) die_perror("error polling for events"); diff --git a/tools/gpionotify.c b/tools/gpionotify.c index d2aee15..08f5da9 100644 --- a/tools/gpionotify.c +++ b/tools/gpionotify.c @@ -132,7 +132,7 @@ static int parse_config(int argc, char **argv, struct config *cfg) cfg->fmt = optarg; break; case 'i': - cfg->idle_timeout = parse_period_or_die(optarg) / 1000; + cfg->idle_timeout = parse_period_or_die(optarg); break; case 'n': cfg->events_wanted = parse_uint_or_die(optarg); @@ -374,6 +374,7 @@ int main(int argc, char **argv) int i, j, ret, events_done = 0, evtype; struct line_resolver *resolver; struct gpiod_info_event *event; + struct timespec idle_timeout; struct gpiod_chip **chips; struct gpiod_chip *chip; struct pollfd *pollfds; @@ -419,10 +420,17 @@ int main(int argc, char **argv) if (cfg.banner) print_banner(argc, argv); + if (cfg.idle_timeout > 0) { + idle_timeout.tv_sec = cfg.idle_timeout / 1000000; + idle_timeout.tv_nsec = + (cfg.idle_timeout % 1000000) * 1000; + } + for (;;) { fflush(stdout); - ret = poll(pollfds, resolver->num_chips, cfg.idle_timeout); + ret = ppoll(pollfds, resolver->num_chips, + cfg.idle_timeout > 0 ? &idle_timeout : NULL, NULL); if (ret < 0) die_perror("error polling for events"); -- 2.40.1