linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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


             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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).