linux-gpio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Ben Hutchings <ben.hutchings@mind.be>
To: linux-gpio@vger.kernel.org
Subject: [PATCH libgpiod-v2] tools: Restore support for opening chips by label
Date: Wed, 28 Jul 2021 23:19:17 +0200	[thread overview]
Message-ID: <20210728211916.GB14442@cephalopod> (raw)

Support for opening chips by label was removed because labels
are not necessarily unique and lookup by label requires opening
every GPIO device.

I don't think these concerns apply to the tools.  They will normally
be run by root, and if a label is specified it's because it's known to
be unique.

This adds a chip_open_by_label() function to tools-common.c, which:

1. Scans the /dev/ directory for GPIO devices, and opens each in turn
2. Checks whether the label matches, and that the label isn't used by
   two distinct devices
3. If all devices can be opened and exactly one matches the label,
   return that device

It changes chip_open_lookup() to call chip_open_by_label() as a final
fallback, rather than the previous behaviour.  This should avoid
producing spurious error messages if a tool is run by a user that can
only access a subset of GPIO devices.

Signed-off-by: Ben Hutchings <ben.hutchings@mind.be>
---
 tools/tools-common.c | 63 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 63 insertions(+)

diff --git a/tools/tools-common.c b/tools/tools-common.c
index 36724d5..d2665e8 100644
--- a/tools/tools-common.c
+++ b/tools/tools-common.c
@@ -4,6 +4,7 @@
 /* Common code for GPIO tools. */
 
 #include <ctype.h>
+#include <dirent.h>
 #include <errno.h>
 #include <gpiod.h>
 #include <libgen.h>
@@ -146,6 +147,66 @@ static struct gpiod_chip *chip_open_by_number(unsigned int num)
 	return chip;
 }
 
+struct gpiod_chip *chip_open_by_label(const char *label)
+{
+	struct gpiod_chip *chip = NULL, *next = NULL;
+	struct dirent **entries;
+	int num_chips, i, error = 0;
+
+	num_chips = scandir("/dev/", &entries, chip_dir_filter, alphasort);
+	if (num_chips < 0) {
+		error = errno;
+		fprintf(stderr, "unable to scan /dev: %s\n", strerror(error));
+		goto out;
+	}
+
+	for (i = 0; i < num_chips; i++) {
+		next = chip_open_by_name(entries[i]->d_name);
+		if (!next) {
+			error = errno;
+			fprintf(stderr, "unable to open %s: %s\n",
+				entries[i]->d_name, strerror(error));
+			break;
+		}
+
+		if (chip && !strcmp(gpiod_chip_get_name(chip),
+				    gpiod_chip_get_name(next))) {
+			/* chip and next are actually the same device */
+			gpiod_chip_close(next);
+		} else if (!strcmp(gpiod_chip_get_label(next), label)) {
+			/* label matches; check it's not a duplicate */
+			if (chip) {
+				fprintf(stderr,
+					"multiple chips have the label \"%s\"\n",
+					label);
+				error = EINVAL;
+				break;
+			}
+			chip = next;
+		} else {
+			gpiod_chip_close(next);
+		}
+	}
+
+	if (error) {
+		if (chip)
+			gpiod_chip_close(chip);
+		if (next)
+			gpiod_chip_close(next);
+		chip = NULL;
+	} else if (!chip) {
+		error = ENOENT;
+	}
+
+	for (i = 0; i < num_chips; i++)
+		free(entries[i]);
+	free(entries);
+
+out:
+	errno = error;
+	return chip;
+}
+
 static bool isuint(const char *str)
 {
 	for (; *str && isdigit(*str); str++)
@@ -166,6 +227,8 @@ struct gpiod_chip *chip_open_lookup(const char *device)
 		else
 			chip = gpiod_chip_open(device);
 	}
+	if (!chip)
+		chip = chip_open_by_label(device);
 
 	return chip;
 }
-- 
2.20.1

             reply	other threads:[~2021-07-28 21:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-28 21:19 Ben Hutchings [this message]
2021-09-20 14:32 ` [PATCH libgpiod-v2] tools: Restore support for opening chips by label Bartosz Golaszewski
2021-09-22 11:59   ` Ben Hutchings

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=20210728211916.GB14442@cephalopod \
    --to=ben.hutchings@mind.be \
    --cc=linux-gpio@vger.kernel.org \
    /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).