iterators: extend chip iterator error handling
authorBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Jan 2017 10:06:50 +0000 (11:06 +0100)
committerBartosz Golaszewski <bartekgola@gmail.com>
Wed, 11 Jan 2017 10:06:50 +0000 (11:06 +0100)
Add a function that allows to retrieve the name of the gpiochip that
we failed to open from an iterator routine. Use it in gpiodetect.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
core.c
gpiod.h
gpiodetect.c

diff --git a/core.c b/core.c
index e7696d7ebdd1ea877f205f36f797a2523dbbefc2..2e1e3609d49620d039b4df3ccd01bea90ce2f5a7 100644 (file)
--- a/core.c
+++ b/core.c
@@ -63,6 +63,7 @@ struct gpiod_chip_iter
        DIR *dir;
        struct gpiod_chip *current;
        int state;
+       char *failed_chip;
 };
 
 static const char dev_dir[] = "/dev/";
@@ -955,6 +956,8 @@ void gpiod_chip_iter_free(struct gpiod_chip_iter *iter)
 void gpiod_chip_iter_free_noclose(struct gpiod_chip_iter *iter)
 {
        closedir(iter->dir);
+       if (iter->failed_chip)
+               free(iter->failed_chip);
        free(iter);
 }
 
@@ -976,10 +979,17 @@ struct gpiod_chip * gpiod_chip_iter_next(struct gpiod_chip_iter *iter)
                                 sizeof(cdev_prefix) - 1);
                if (status == 0) {
                        iter->state = CHIP_ITER_INIT;
+                       if (iter->failed_chip) {
+                               free(iter->failed_chip);
+                               iter->failed_chip = NULL;
+                       }
 
                        chip = gpiod_chip_open_by_name(dentry->d_name);
-                       if (!chip)
+                       if (!chip) {
                                iter->state = CHIP_ITER_ERR;
+                               iter->failed_chip = strdup(dentry->d_name);
+                               /* No point in an error check here. */
+                       }
 
                        iter->current = chip;
                        return iter->current;
@@ -999,3 +1009,9 @@ bool gpiod_chip_iter_iserr(struct gpiod_chip_iter *iter)
 {
        return iter->state == CHIP_ITER_ERR;
 }
+
+const char *
+gpiod_chip_iter_failed_chip(struct gpiod_chip_iter *iter)
+{
+       return iter->failed_chip;
+}
diff --git a/gpiod.h b/gpiod.h
index 5cf3254bac91b91c6361cb93e895d4c6ed652f46..4d2e7bc9953cc7face0a63ba70e4a388612a7c6b 100644 (file)
--- a/gpiod.h
+++ b/gpiod.h
@@ -723,6 +723,19 @@ bool gpiod_chip_iter_done(struct gpiod_chip_iter *iter) GPIOD_API;
  */
 bool gpiod_chip_iter_iserr(struct gpiod_chip_iter *iter) GPIOD_API;
 
+/**
+ * @brief Get the name of the gpiochip that we failed to access.
+ * @param iter The gpiochip iterator object.
+ * @return If gpiod_chip_iter_iserr() returned true, this function returns a
+ *         pointer to the name of the gpiochip that we failed to access.
+ *         If there was no error this function returns NULL.
+ *
+ * NOTE: this function will return NULL if the internal memory allocation
+ * fails.
+ */
+const char *
+gpiod_chip_iter_failed_chip(struct gpiod_chip_iter *iter) GPIOD_API;
+
 /**
  * @brief GPIO line iterator structure.
  *
index aab022d20d782122d0fd603b89570cffbb8eb5aa..c35b61835d25e4fd63fb6a3be5589a3c9ff9b499 100644 (file)
@@ -66,7 +66,8 @@ int main(int argc, char **argv)
 
        gpiod_foreach_chip(iter, chip) {
                if (gpiod_chip_iter_iserr(iter))
-                       die_perror("error accessing gpiochip");
+                       die_perror("error accessing gpiochip %s",
+                                  gpiod_chip_iter_failed_chip(iter));
 
                printf("%s [%s] (%u lines)\n",
                       gpiod_chip_name(chip),