iterators: improve error checking
authorBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Jan 2017 09:52:13 +0000 (10:52 +0100)
committerBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Jan 2017 09:52:13 +0000 (10:52 +0100)
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 <bartekgola@gmail.com>
core.c
gpiod.h
gpiodetect.c

diff --git a/core.c b/core.c
index ea24288e1a21e2be6e009748caf8c59dfd86a5ff..e7696d7ebdd1ea877f205f36f797a2523dbbefc2 100644 (file)
--- 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 ecba21a2db1a27cf9e0b2bac12ba0fb67b431a26..5cf3254bac91b91c6361cb93e895d4c6ed652f46 100644 (file)
--- 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.
  *
index afb5479f973fbf84be6949f8c83fcd0d2d3ae0fa..aab022d20d782122d0fd603b89570cffbb8eb5aa 100644 (file)
@@ -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),