From: Bartosz Golaszewski <brgl@bgdev.pl>
To: Kent Gibson <warthog618@gmail.com>,
Linus Walleij <linus.walleij@linaro.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: linux-gpio@vger.kernel.org, Bartosz Golaszewski <brgl@bgdev.pl>
Subject: [libgpiod v2][PATCH] misc: make gpiod_is_gpiochip_device() not set errno
Date: Fri, 1 Jul 2022 13:00:56 +0200 [thread overview]
Message-ID: <20220701110056.58502-1-brgl@bgdev.pl> (raw)
This function should just report whether the file indicated by path is
a GPIO chip or not. Let's rework it to not set errno. Failure to open a
chip should still report errro numbers like before.
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
---
lib/chip.c | 2 +-
lib/internal.c | 65 +++++++++++++++++++++++++++++++++++++++++++++-
lib/internal.h | 2 ++
lib/misc.c | 62 ++-----------------------------------------
tests/tests-misc.c | 2 ++
5 files changed, 71 insertions(+), 62 deletions(-)
diff --git a/lib/chip.c b/lib/chip.c
index fc3dda2..666a1ac 100644
--- a/lib/chip.c
+++ b/lib/chip.c
@@ -21,7 +21,7 @@ GPIOD_API struct gpiod_chip *gpiod_chip_open(const char *path)
struct gpiod_chip *chip;
int fd;
- if (!gpiod_is_gpiochip_device(path))
+ if (!gpiod_check_gpiochip_device(path, true))
return NULL;
fd = open(path, O_RDWR | O_CLOEXEC | O_NONBLOCK);
diff --git a/lib/internal.c b/lib/internal.c
index b7da67e..ba7b90f 100644
--- a/lib/internal.c
+++ b/lib/internal.c
@@ -1,12 +1,75 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
-// SPDX-FileCopyrightText: 2021 Bartosz Golaszewski <brgl@bgdev.pl>
+// SPDX-FileCopyrightText: 2021-2022 Bartosz Golaszewski <brgl@bgdev.pl>
#include <errno.h>
#include <poll.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "internal.h"
+bool gpiod_check_gpiochip_device(const char *path, bool set_errno)
+{
+ char *realname, *sysfsp, devpath[64];
+ struct stat statbuf;
+ bool ret = false;
+ int rv;
+
+ rv = lstat(path, &statbuf);
+ if (rv)
+ goto out;
+
+ /*
+ * Is it a symbolic link? We have to resolve it before checking
+ * the rest.
+ */
+ realname = S_ISLNK(statbuf.st_mode) ? realpath(path, NULL)
+ : strdup(path);
+ if (realname == NULL)
+ goto out;
+
+ rv = stat(realname, &statbuf);
+ if (rv)
+ goto out_free_realname;
+
+ /* Is it a character device? */
+ if (!S_ISCHR(statbuf.st_mode)) {
+ errno = ENOTTY;
+ goto out_free_realname;
+ }
+
+ /* Is the device associated with the GPIO subsystem? */
+ snprintf(devpath, sizeof(devpath), "/sys/dev/char/%u:%u/subsystem",
+ major(statbuf.st_rdev), minor(statbuf.st_rdev));
+
+ sysfsp = realpath(devpath, NULL);
+ if (!sysfsp)
+ goto out_free_realname;
+
+ if (strcmp(sysfsp, "/sys/bus/gpio") != 0) {
+ /* This is a character device but not the one we're after. */
+ errno = ENODEV;
+ goto out_free_sysfsp;
+ }
+
+ ret = true;
+
+out_free_sysfsp:
+ free(sysfsp);
+out_free_realname:
+ free(realname);
+out:
+ if (!set_errno)
+ errno = 0;
+ return ret;
+}
+
int gpiod_poll_fd(int fd, uint64_t timeout_ns)
{
struct timespec ts;
diff --git a/lib/internal.h b/lib/internal.h
index c87df91..12f184e 100644
--- a/lib/internal.h
+++ b/lib/internal.h
@@ -18,6 +18,8 @@
#define GPIOD_BIT(nr) (1UL << (nr))
+bool gpiod_check_gpiochip_device(const char *path, bool set_errno);
+
struct gpiod_chip_info *
gpiod_chip_info_from_uapi(struct gpiochip_info *uapi_info);
struct gpiod_line_info *
diff --git a/lib/misc.c b/lib/misc.c
index 5c326eb..b0899b3 100644
--- a/lib/misc.c
+++ b/lib/misc.c
@@ -1,71 +1,13 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
-// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
+// SPDX-FileCopyrightText: 2017-2022 Bartosz Golaszewski <bartekgola@gmail.com>
-#include <errno.h>
#include <gpiod.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/sysmacros.h>
-#include <sys/types.h>
-#include <unistd.h>
#include "internal.h"
GPIOD_API bool gpiod_is_gpiochip_device(const char *path)
{
- char *realname, *sysfsp, devpath[64];
- struct stat statbuf;
- bool ret = false;
- int rv;
-
- rv = lstat(path, &statbuf);
- if (rv)
- goto out;
-
- /*
- * Is it a symbolic link? We have to resolve it before checking
- * the rest.
- */
- realname = S_ISLNK(statbuf.st_mode) ? realpath(path, NULL)
- : strdup(path);
- if (realname == NULL)
- goto out;
-
- rv = stat(realname, &statbuf);
- if (rv)
- goto out_free_realname;
-
- /* Is it a character device? */
- if (!S_ISCHR(statbuf.st_mode)) {
- errno = ENOTTY;
- goto out_free_realname;
- }
-
- /* Is the device associated with the GPIO subsystem? */
- snprintf(devpath, sizeof(devpath), "/sys/dev/char/%u:%u/subsystem",
- major(statbuf.st_rdev), minor(statbuf.st_rdev));
-
- sysfsp = realpath(devpath, NULL);
- if (!sysfsp)
- goto out_free_realname;
-
- if (strcmp(sysfsp, "/sys/bus/gpio") != 0) {
- /* This is a character device but not the one we're after. */
- errno = ENODEV;
- goto out_free_sysfsp;
- }
-
- ret = true;
-
-out_free_sysfsp:
- free(sysfsp);
-out_free_realname:
- free(realname);
-out:
- return ret;
+ return gpiod_check_gpiochip_device(path, false);
}
GPIOD_API const char *gpiod_version_string(void)
diff --git a/tests/tests-misc.c b/tests/tests-misc.c
index c473aff..d3c9a82 100644
--- a/tests/tests-misc.c
+++ b/tests/tests-misc.c
@@ -15,7 +15,9 @@
GPIOD_TEST_CASE(is_gpiochip_bad)
{
g_assert_false(gpiod_is_gpiochip_device("/dev/null"));
+ g_assert_cmpint(errno, ==, 0);
g_assert_false(gpiod_is_gpiochip_device("/dev/nonexistent"));
+ g_assert_cmpint(errno, ==, 0);
}
GPIOD_TEST_CASE(is_gpiochip_good)
--
2.34.1
next reply other threads:[~2022-07-01 11:01 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-01 11:00 Bartosz Golaszewski [this message]
2022-07-01 11:11 ` [libgpiod v2][PATCH] misc: make gpiod_is_gpiochip_device() not set errno Andy Shevchenko
2022-07-01 11:43 ` Kent Gibson
2022-07-01 11:50 ` Bartosz Golaszewski
2022-07-01 11:55 ` Kent Gibson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220701110056.58502-1-brgl@bgdev.pl \
--to=brgl@bgdev.pl \
--cc=andriy.shevchenko@linux.intel.com \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=warthog618@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.