core: add non-closing gpiochip iterator function and foreach macro
authorClemens Gruber <clemens.gruber@pqgruber.com>
Tue, 31 Jan 2017 21:08:02 +0000 (22:08 +0100)
committerBartosz Golaszewski <bartekgola@gmail.com>
Wed, 1 Feb 2017 10:51:58 +0000 (11:51 +0100)
Allows users to iterate over the gpiochips without closing them
automatically. The lines can then be used during the runtime of the
program. The user is responsible for closing the chips after they are
no longer needed.

Signed-off-by: Clemens Gruber <clemens.gruber@pqgruber.com>
Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
include/gpiod.h
src/lib/core.c

index f863dcfdadfa57c34edba911b49ca83f951b59e0..b62932291cf793ccdd7537f8684fad5c7a642811 100644 (file)
@@ -965,6 +965,21 @@ void gpiod_chip_iter_free_noclose(struct gpiod_chip_iter *iter) GPIOD_API;
 struct gpiod_chip *
 gpiod_chip_iter_next(struct gpiod_chip_iter *iter) GPIOD_API;
 
+/**
+ * @brief Get the next gpiochip handle without closing the previous one.
+ * @param iter The gpiochip iterator object.
+ * @return Pointer to an open gpiochip handle or NULL if the next chip can't
+ *         be accessed.
+ *
+ * Internally this routine scans the /dev/ directory, storing current state
+ * in the chip iterator structure, and tries to open the next /dev/gpiochipX
+ * device file. If an error occurs or no more chips are present, the function
+ * returns NULL.
+ * Note: The user is responsible for closing the chips after use.
+ */
+struct gpiod_chip *
+gpiod_chip_iter_next_noclose(struct gpiod_chip_iter *iter) GPIOD_API;
+
 /**
  * @brief Iterate over all gpiochip present in the system.
  * @param iter An initialized GPIO chip iterator.
@@ -980,6 +995,21 @@ gpiod_chip_iter_next(struct gpiod_chip_iter *iter) GPIOD_API;
             !gpiod_chip_iter_done(iter);                               \
             (chip) = gpiod_chip_iter_next(iter))
 
+/**
+ * @brief Iterate over all gpiochip present in the system without closing them.
+ * @param iter An initialized GPIO chip iterator.
+ * @param chip Pointer to a GPIO chip handle. On each iteration the newly
+ *             opened chip handle is assigned to this argument.
+ *
+ * The user must close the GPIO chip manually after use, until then, the chip
+ * remains open. Free the iterator by calling gpiod_chip_iter_free_noclose to
+ * avoid closing the last chip automatically.
+ */
+#define gpiod_foreach_chip_noclose(iter, chip)                         \
+       for ((chip) = gpiod_chip_iter_next_noclose(iter);               \
+            !gpiod_chip_iter_done(iter);                               \
+            (chip) = gpiod_chip_iter_next_noclose(iter))
+
 /**
  * @brief Check if we're done iterating over gpiochips on this iterator.
  * @param iter The gpiochip iterator object.
index 55f144baa9458834b72e398d3ce94d5f7a0f4157..71ac7d23bcb3cecd39395f6e52f49a30bbc938a5 100644 (file)
@@ -1074,15 +1074,20 @@ void gpiod_chip_iter_free_noclose(struct gpiod_chip_iter *iter)
 
 struct gpiod_chip * gpiod_chip_iter_next(struct gpiod_chip_iter *iter)
 {
-       struct gpiod_chip *chip;
-       struct dirent *dentry;
-       int status;
-
        if (iter->current) {
                gpiod_chip_close(iter->current);
                iter->current = NULL;
        }
 
+       return gpiod_chip_iter_next_noclose(iter);
+}
+
+struct gpiod_chip * gpiod_chip_iter_next_noclose(struct gpiod_chip_iter *iter)
+{
+       struct gpiod_chip *chip;
+       struct dirent *dentry;
+       int status;
+
        for (dentry = readdir(iter->dir);
             dentry;
             dentry = readdir(iter->dir)) {