mirror of
https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git
synced 2026-10-24 00:48:53 +03:00
Platforms like Bionic libc don't have program_invocation_[short_]name, which is a GNU extension. It does have getprogname(), a BSD extension, but rather than supporting multiple extensions let's just introduce our own local helpers. We derive the short name ourselves rather than calling basename(), as the POSIX version takes char *, not const char *, and is thus not guaranteed to avoid modifying its input. (The GNU version does take const char * but we are avoiding extensions here.) Signed-off-by: Benjamin Li <benl@squareup.com> Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
125 lines
2.6 KiB
C
125 lines
2.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
// SPDX-FileCopyrightText: 2017-2021 Bartosz Golaszewski <bartekgola@gmail.com>
|
|
// SPDX-FileCopyrightText: 2022 Kent Gibson <warthog618@gmail.com>
|
|
|
|
#include <getopt.h>
|
|
#include <gpiod.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "tools-common.h"
|
|
|
|
static void print_help(void)
|
|
{
|
|
printf("Usage: %s [OPTIONS] [chip]...\n", get_prog_name());
|
|
printf("\n");
|
|
printf("List GPIO chips, print their labels and number of GPIO lines.\n");
|
|
printf("\n");
|
|
printf("Chips may be identified by number, name, or path.\n");
|
|
printf("e.g. '0', 'gpiochip0', and '/dev/gpiochip0' all refer to the same chip.\n");
|
|
printf("\n");
|
|
printf("If no chips are specified then all chips are listed.\n");
|
|
printf("\n");
|
|
printf("Options:\n");
|
|
printf(" -h, --help\t\tdisplay this help and exit\n");
|
|
printf(" -v, --version\t\toutput version information and exit\n");
|
|
}
|
|
|
|
static int parse_config(int argc, char **argv)
|
|
{
|
|
static const struct option longopts[] = {
|
|
{ "help", no_argument, NULL, 'h' },
|
|
{ "version", no_argument, NULL, 'v' },
|
|
{ GETOPT_NULL_LONGOPT },
|
|
};
|
|
|
|
static const char *const shortopts = "+hv";
|
|
|
|
int optc, opti;
|
|
|
|
for (;;) {
|
|
optc = getopt_long(argc, argv, shortopts, longopts, &opti);
|
|
if (optc < 0)
|
|
break;
|
|
|
|
switch (optc) {
|
|
case 'h':
|
|
print_help();
|
|
exit(EXIT_SUCCESS);
|
|
case 'v':
|
|
print_version();
|
|
exit(EXIT_SUCCESS);
|
|
case '?':
|
|
die("try %s --help", get_prog_name());
|
|
default:
|
|
abort();
|
|
}
|
|
}
|
|
return optind;
|
|
}
|
|
|
|
static int print_chip_info(const char *path)
|
|
{
|
|
struct gpiod_chip_info *info;
|
|
struct gpiod_chip *chip;
|
|
|
|
chip = gpiod_chip_open(path);
|
|
if (!chip) {
|
|
print_perror("unable to open chip '%s'", path);
|
|
return 1;
|
|
}
|
|
|
|
info = gpiod_chip_get_info(chip);
|
|
if (!info)
|
|
die_perror("unable to read info for '%s'", path);
|
|
|
|
printf("%s [%s] (%zu lines)\n", gpiod_chip_info_get_name(info),
|
|
gpiod_chip_info_get_label(info),
|
|
gpiod_chip_info_get_num_lines(info));
|
|
|
|
gpiod_chip_info_free(info);
|
|
gpiod_chip_close(chip);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int num_chips, i, ret = EXIT_SUCCESS;
|
|
char **paths, *path;
|
|
|
|
set_prog_name(argv[0]);
|
|
i = parse_config(argc, argv);
|
|
argc -= i;
|
|
argv += i;
|
|
|
|
if (argc == 0) {
|
|
num_chips = all_chip_paths(&paths);
|
|
for (i = 0; i < num_chips; i++) {
|
|
if (print_chip_info(paths[i]))
|
|
ret = EXIT_FAILURE;
|
|
|
|
free(paths[i]);
|
|
}
|
|
|
|
free(paths);
|
|
}
|
|
|
|
for (i = 0; i < argc; i++) {
|
|
if (chip_path_lookup(argv[i], &path)) {
|
|
if (print_chip_info(path))
|
|
ret = EXIT_FAILURE;
|
|
|
|
free(path);
|
|
} else {
|
|
print_error(
|
|
"cannot find GPIO chip character device '%s'",
|
|
argv[i]);
|
|
ret = EXIT_FAILURE;
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|