File: find_line_by_name.c

package info (click to toggle)
libgpiod 2.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,172 kB
  • sloc: ansic: 26,661; sh: 8,090; cpp: 4,944; python: 2,426; makefile: 811; xml: 49
file content (105 lines) | stat: -rw-r--r-- 2,106 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: 2023 Kent Gibson <warthog618@gmail.com>

/* Minimal example of finding a line with the given name. */

#include <dirent.h>
#include <errno.h>
#include <gpiod.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>

static int chip_dir_filter(const struct dirent *entry)
{
	struct stat sb;
	int ret = 0;
	char *path;

	if (asprintf(&path, "/dev/%s", entry->d_name) < 0)
		return 0;

	if ((lstat(path, &sb) == 0) && (!S_ISLNK(sb.st_mode)) &&
	    gpiod_is_gpiochip_device(path))
		ret = 1;

	free(path);

	return ret;
}

static int all_chip_paths(char ***paths_ptr)
{
	int i, j, num_chips, ret = 0;
	struct dirent **entries;
	char **paths;

	num_chips = scandir("/dev/", &entries, chip_dir_filter, versionsort);
	if (num_chips < 0)
		return 0;

	paths = calloc(num_chips, sizeof(*paths));
	if (!paths)
		return 0;

	for (i = 0; i < num_chips; i++) {
		if (asprintf(&paths[i], "/dev/%s", entries[i]->d_name) < 0) {
			for (j = 0; j < i; j++)
				free(paths[j]);

			free(paths);
			return 0;
		}
	}

	*paths_ptr = paths;
	ret = num_chips;

	for (i = 0; i < num_chips; i++)
		free(entries[i]);

	free(entries);
	return ret;
}

int main(void)
{
	/* Example configuration - customize to suit your situation. */
	static const char *const line_name = "GPIO19";

	struct gpiod_chip_info *cinfo;
	int i, num_chips, offset;
	struct gpiod_chip *chip;
	char **chip_paths;

	/*
	 * Names are not guaranteed unique, so this finds the first line with
	 * the given name.
	 */
	num_chips = all_chip_paths(&chip_paths);
	for (i = 0; i < num_chips; i++) {
		chip = gpiod_chip_open(chip_paths[i]);
		if (!chip)
			continue;

		offset = gpiod_chip_get_line_offset_from_name(chip, line_name);
		if (offset == -1)
			goto close_chip;

		cinfo = gpiod_chip_get_info(chip);
		if (!cinfo)
			goto close_chip;

		printf("%s: %s %d\n", line_name,
		       gpiod_chip_info_get_name(cinfo), offset);

		return EXIT_SUCCESS;

close_chip:
		gpiod_chip_close(chip);
	}

	printf("line '%s' not found\n", line_name);
	return EXIT_FAILURE;
}