From: Gabriel Matni <gabriel.matni@xxxxxxxx> Add a timeout option which allows gpiomon to gracefully exit upon expiry. This is handy for scripting as it allows developers to implement an action when no trigger has been detected for a given period of time. Signed-off-by: Gabriel Matni <gabriel.matni@xxxxxxxx> --- diff --git a/tools/gpiomon.c b/tools/gpiomon.c index cc08f17dd2b4..7ef35fa69b1d 100644 --- a/tools/gpiomon.c +++ b/tools/gpiomon.c @@ -30,6 +30,7 @@ struct config { const char *fmt; enum gpiod_line_clock event_clock; int timestamp_fmt; + unsigned int timeout; }; static void print_help(void) @@ -68,9 +69,12 @@ static void print_help(void) printf(" -s, --strict\t\tabort if requested line names are not unique\n"); printf(" --unquoted\tdon't quote line or consumer names\n"); printf(" --utc\t\tformat event timestamps as UTC (default for 'realtime')\n"); + printf(" -t, --timeout <timeout>\n"); + printf("\t\t\tpoll timeout, format similar to debounce-period\n"); printf(" -v, --version\t\toutput version information and exit\n"); print_chip_help(); print_period_help(); + print_timeout_help(); printf("\n"); printf("Format specifiers:\n"); printf(" %%o GPIO line offset\n"); @@ -109,7 +113,7 @@ static int parse_event_clock_or_die(const char *option) static int parse_config(int argc, char **argv, struct config *cfg) { - static const char *const shortopts = "+b:c:C:e:E:hF:ln:p:qshv"; + static const char *const shortopts = "+b:c:C:e:E:hF:ln:p:qst:hv"; const struct option longopts[] = { { "active-low", no_argument, NULL, 'l' }, @@ -128,6 +132,7 @@ static int parse_config(int argc, char **argv, struct config *cfg) { "quiet", no_argument, NULL, 'q' }, { "silent", no_argument, NULL, 'q' }, { "strict", no_argument, NULL, 's' }, + { "timeout", required_argument, NULL, 't' }, { "unquoted", no_argument, NULL, 'Q' }, { "utc", no_argument, &cfg->timestamp_fmt, 1 }, { "version", no_argument, NULL, 'v' }, @@ -139,6 +144,7 @@ static int parse_config(int argc, char **argv, struct config *cfg) memset(cfg, 0, sizeof(*cfg)); cfg->edges = GPIOD_LINE_EDGE_BOTH; cfg->consumer = "gpiomon"; + cfg->timeout = -1; for (;;) { optc = getopt_long(argc, argv, shortopts, longopts, &opti); @@ -188,6 +194,9 @@ static int parse_config(int argc, char **argv, struct config *cfg) case 's': cfg->strict = true; break; + case 't': + cfg->timeout = parse_period_or_die(optarg) / 1000; + break; case 'h': print_help(); exit(EXIT_SUCCESS); @@ -442,11 +451,16 @@ int main(int argc, char **argv) print_banner(argc, argv); for (;;) { + int ret; fflush(stdout); - if (poll(pollfds, resolver->num_chips, -1) < 0) + ret = poll(pollfds, resolver->num_chips, cfg.timeout); + if (ret < 0) die_perror("error polling for events"); + if (ret == 0) + goto done; + for (i = 0; i < resolver->num_chips; i++) { if (pollfds[i].revents == 0) continue; diff --git a/tools/tools-common.c b/tools/tools-common.c index a0080fcdae1f..12c350aa8a48 100644 --- a/tools/tools-common.c +++ b/tools/tools-common.c @@ -188,6 +188,13 @@ void print_period_help(void) printf(" Supported units are 's', 'ms', and 'us'.\n"); } +void print_timeout_help(void) +{ + printf("\nTimeout:\n"); + printf(" Timeout is taken as milliseconds unless a unit is specified. e.g. 1s.\n"); + printf(" Supported units are 's', 'ms'.\n"); +} + #define TIME_BUFFER_SIZE 20 /* diff --git a/tools/tools-common.h b/tools/tools-common.h index 434e5ba5d271..2ee8f51b3c7c 100644 --- a/tools/tools-common.h +++ b/tools/tools-common.h @@ -92,6 +92,7 @@ unsigned int parse_uint_or_die(const char *option); void print_bias_help(void); void print_chip_help(void); void print_period_help(void); +void print_timeout_help(void); void print_event_time(uint64_t evtime, int format); void print_line_attributes(struct gpiod_line_info *info, bool unquoted_strings); void print_line_id(struct line_resolver *resolver, int chip_num,