From 669923dedb0a13c2c8b834947863dd4d663249f6 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 11 Jan 2017 10:52:13 +0100 Subject: [PATCH] iterators: improve error checking Add new functions that allow to check if opening a gpiochip device file from an iterator routine failed or if we're done iterating over all gpiochips present on the system. Use them in the relevant foreach macro and gpiodetect. Signed-off-by: Bartosz Golaszewski --- core.c | 25 +++++++++++++++++++++++++ gpiod.h | 18 +++++++++++++++++- gpiodetect.c | 3 +++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core.c b/core.c index ea24288..e7696d7 100644 --- a/core.c +++ b/core.c @@ -52,10 +52,17 @@ struct gpiod_line { }; }; +enum { + CHIP_ITER_INIT = 0, + CHIP_ITER_DONE, + CHIP_ITER_ERR, +}; + struct gpiod_chip_iter { DIR *dir; struct gpiod_chip *current; + int state; }; static const char dev_dir[] = "/dev/"; @@ -932,6 +939,8 @@ struct gpiod_chip_iter * gpiod_chip_iter_new(void) return NULL; } + new->state = CHIP_ITER_INIT; + return new; } @@ -966,11 +975,27 @@ struct gpiod_chip * gpiod_chip_iter_next(struct gpiod_chip_iter *iter) status = strncmp(dentry->d_name, cdev_prefix, sizeof(cdev_prefix) - 1); if (status == 0) { + iter->state = CHIP_ITER_INIT; + chip = gpiod_chip_open_by_name(dentry->d_name); + if (!chip) + iter->state = CHIP_ITER_ERR; + iter->current = chip; return iter->current; } } + iter->state = CHIP_ITER_DONE; return NULL; } + +bool gpiod_chip_iter_done(struct gpiod_chip_iter *iter) +{ + return iter->state == CHIP_ITER_DONE; +} + +bool gpiod_chip_iter_iserr(struct gpiod_chip_iter *iter) +{ + return iter->state == CHIP_ITER_ERR; +} diff --git a/gpiod.h b/gpiod.h index ecba21a..5cf3254 100644 --- a/gpiod.h +++ b/gpiod.h @@ -704,9 +704,25 @@ gpiod_chip_iter_next(struct gpiod_chip_iter *iter) GPIOD_API; */ #define gpiod_foreach_chip(iter, chip) \ for ((chip) = gpiod_chip_iter_next(iter); \ - (chip); \ + !gpiod_chip_iter_done(iter); \ (chip) = gpiod_chip_iter_next(iter)) +/** + * @brief Check if we're done iterating over gpiochips on this iterator. + * @param iter The gpiochip iterator object. + * @return True if we've iterated over all chips, false otherwise. + */ +bool gpiod_chip_iter_done(struct gpiod_chip_iter *iter) GPIOD_API; + +/** + * @brief Check if we've encountered an error condition while opening a + * gpiochip. + * @param iter The gpiochip iterator object. + * @return True if there was an error opening a gpiochip device file, + * false otherwise. + */ +bool gpiod_chip_iter_iserr(struct gpiod_chip_iter *iter) GPIOD_API; + /** * @brief GPIO line iterator structure. * diff --git a/gpiodetect.c b/gpiodetect.c index afb5479..aab022d 100644 --- a/gpiodetect.c +++ b/gpiodetect.c @@ -65,6 +65,9 @@ int main(int argc, char **argv) die_perror("unable to access GPIO chips"); gpiod_foreach_chip(iter, chip) { + if (gpiod_chip_iter_iserr(iter)) + die_perror("error accessing gpiochip"); + printf("%s [%s] (%u lines)\n", gpiod_chip_name(chip), gpiod_chip_label(chip), -- 2.30.2