static const char cdev_prefix[] = "gpiochip";
static const char libgpiod_consumer[] = "libgpiod";
+static __thread int last_error;
+
static void * zalloc(size_t size)
{
void *ptr;
return *str == '\0';
}
+int gpiod_errno(void)
+{
+ return last_error;
+}
+
+const char * gpiod_strerror(int errnum)
+{
+ return strerror(errnum);
+}
+
int gpiod_simple_get_value(const char *device, unsigned int offset)
{
struct gpiod_chip *chip;
int status, value;
chip = gpiod_chip_open_lookup(device);
- if (GPIOD_IS_ERR(chip))
- return GPIOD_PTR_ERR(chip);
+ if (!chip)
+ return -1;
line = gpiod_chip_get_line(chip, offset);
- if (GPIOD_IS_ERR(line)) {
+ if (!line) {
gpiod_chip_close(chip);
- return GPIOD_PTR_ERR(line);
+ return -1;
}
status = gpiod_line_request(line, libgpiod_consumer,
GPIOD_DIRECTION_IN, 0, 0);
if (status < 0) {
gpiod_chip_close(chip);
- return status;
+ return -1;
}
value = gpiod_line_get_value(line);
int status;
chip = gpiod_chip_open_lookup(device);
- if (GPIOD_IS_ERR(chip))
- return GPIOD_PTR_ERR(chip);
+ if (!chip)
+ return -1;
line = gpiod_chip_get_line(chip, offset);
- if (GPIOD_IS_ERR(line)) {
+ if (!line) {
gpiod_chip_close(chip);
- return GPIOD_PTR_ERR(line);
+ return -1;
}
status = gpiod_line_request(line, libgpiod_consumer,
GPIOD_DIRECTION_OUT, value, 0);
if (status < 0) {
gpiod_chip_close(chip);
- return status;
+ return -1;
}
gpiod_line_release(line);
fd = gpiod_chip_get_fd(chip);
status = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, req);
- if (status < 0)
- return -errno;
+ if (status < 0) {
+ last_error = errno;
+ return -1;
+ }
line->requested = true;
struct gpiohandle_data data;
int status;
- if (!gpiod_line_is_requested(line))
- return -EPERM;
+ if (!gpiod_line_is_requested(line)) {
+ last_error = -EPERM;
+ return -1;
+ }
memset(&data, 0, sizeof(data));
status = ioctl(line->lreq.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
- if (status < 0)
- return -errno;
+ if (status < 0) {
+ last_error = errno;
+ return -1;
+ }
return data.values[0];
}
struct gpiohandle_data data;
int status;
- if (!gpiod_line_is_requested(line))
- return -EPERM;
+ if (!gpiod_line_is_requested(line)) {
+ last_error = -EPERM;
+ return -1;
+ }
memset(&data, 0, sizeof(data));
data.values[0] = value ? 1 : 0;
status = ioctl(line->lreq.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data);
- if (status < 0)
- return -errno;
+ if (status < 0) {
+ last_error = errno;
+ return -1;
+ }
return 0;
}
int status, fd;
fd = open(path, O_RDWR);
- if (fd < 0)
- return GPIOD_ERR_PTR(-errno);
+ if (fd < 0) {
+ last_error = errno;
+ return NULL;
+ }
chip = zalloc(sizeof(*chip));
if (!chip) {
close(fd);
- return GPIOD_ERR_PTR(-ENOMEM);
+ last_error = ENOMEM;
+ return NULL;
}
chip->fd = fd;
if (status < 0) {
close(chip->fd);
free(chip);
- return GPIOD_ERR_PTR(-errno);
+ last_error = errno;
+ return NULL;
}
chip->lines = zalloc(chip->cinfo.lines * sizeof(*chip->lines));
if (!chip->lines) {
close(chip->fd);
free(chip);
- return GPIOD_ERR_PTR(-ENOMEM);
+ last_error = ENOMEM;
+ return NULL;
}
return chip;
int status;
status = asprintf(&path, "%s%s", dev_dir, name);
- if (status < 0)
- return GPIOD_ERR_PTR(-errno);
+ if (status < 0) {
+ last_error = errno;
+ return NULL;
+ }
chip = gpiod_chip_open(path);
free(path);
int status;
status = asprintf(&path, "%s%s%u", dev_dir, cdev_prefix, num);
- if (!status)
- return GPIOD_ERR_PTR(-ENOMEM);
+ if (!status) {
+ last_error = errno;
+ return NULL;
+ }
chip = gpiod_chip_open(path);
free(path);
struct gpiod_line *line;
int status;
- if (offset >= chip->cinfo.lines)
- return GPIOD_ERR_PTR(-EINVAL);
+ if (offset >= chip->cinfo.lines) {
+ last_error = EINVAL;
+ return NULL;
+ }
line = &chip->lines[offset];
line->linfo.line_offset = offset;
status = ioctl(chip->fd, GPIO_GET_LINEINFO_IOCTL, &line->linfo);
- if (status < 0)
- return GPIOD_ERR_PTR(-errno);
+ if (status < 0) {
+ last_error = errno;
+ return NULL;
+ }
line->chip = chip;
struct gpiod_chip_iter *new;
new = zalloc(sizeof(*new));
- if (!new)
- return GPIOD_ERR_PTR(-ENOMEM);
+ if (!new) {
+ last_error = ENOMEM;
+ return NULL;
+ }
new->dir = opendir(dev_dir);
- if (!new->dir)
- return GPIOD_ERR_PTR(-errno);
+ if (!new->dir) {
+ last_error = errno;
+ return NULL;
+ }
return new;
}
#define GPIOD_BIT(nr) (1UL << (nr))
-#define __GPIOD_MAX_ERRNO 4095
+int gpiod_errno(void) GPIOD_API;
-static inline void * GPIOD_ERR_PTR(long error)
-{
- return (void *)error;
-}
-
-static inline long GPIOD_PTR_ERR(const void *ptr)
-{
- return (long)ptr;
-}
-
-static inline bool GPIOD_IS_ERR(const void *ptr)
-{
- return (uintptr_t)ptr >= ((unsigned int) - __GPIOD_MAX_ERRNO);
-}
+const char * gpiod_strerror(int errnum) GPIOD_API;
int gpiod_simple_get_value(const char *device, unsigned int offset) GPIOD_API;
#define gpiod_foreach_chip(iter, chip) \
for ((chip) = gpiod_chip_iter_next(iter); \
- (chip) && !GPIOD_IS_ERR(chip); \
+ (chip); \
(chip) = gpiod_chip_iter_next(iter))
struct gpiod_line_iter {
#define gpiod_chip_foreach_line(iter, chip, line) \
for ((line) = gpiod_chip_line_next(chip, iter); \
- (line) && !(GPIOD_IS_ERR(line)); \
+ (line); \
(line) = gpiod_chip_line_next(chip, iter))
#ifdef __cplusplus
{
struct gpiod_chip_iter *iter;
struct gpiod_chip *chip;
- int status;
if (argc != 1) {
printf("Usage: %s\n", argv[0]);
}
iter = gpiod_chip_iter_new();
- if (GPIOD_IS_ERR(iter)) {
- status = GPIOD_PTR_ERR(iter);
- goto err;
+ if (!iter) {
+ fprintf(stderr, "%s: unable to access gpio chips: %s\n",
+ argv[0], gpiod_strerror(gpiod_errno()));
+
+ return EXIT_FAILURE;
}
gpiod_foreach_chip(iter, chip) {
gpiod_chip_iter_free(iter);
- if (GPIOD_IS_ERR(chip)) {
- status = GPIOD_PTR_ERR(chip);
- goto err;
- }
-
return EXIT_SUCCESS;
-
-err:
- fprintf(stderr, "%s: unable to access gpio chips: %s\n",
- argv[0], strerror(-status));
-
- return EXIT_FAILURE;
}
}
chip = gpiod_chip_open_lookup(device);
- if (GPIOD_IS_ERR(chip)) {
+ if (!chip) {
fprintf(stderr,
"%s: error accessing gpiochip %s: %s\n",
- argv[0], device, strerror(-GPIOD_PTR_ERR(chip)));
+ argv[0], device, gpiod_strerror(gpiod_errno()));
return EXIT_FAILURE;
}
line = gpiod_chip_get_line(chip, offset);
- if (GPIOD_IS_ERR(line)) {
+ if (!line) {
fprintf(stderr,
"%s: error accessing line %u: %s\n",
- argv[0], offset, strerror(-GPIOD_PTR_ERR(chip)));
+ argv[0], offset, gpiod_strerror(gpiod_errno()));
return EXIT_FAILURE;
}
if (status < 0) {
fprintf(stderr,
"%s: error requesting GPIO line: %s\n",
- argv[0], strerror(-status));
+ argv[0], gpiod_strerror(gpiod_errno()));
return EXIT_FAILURE;
}
if (status < 0) {
fprintf(stderr,
"%s: error setting GPIO value: %s\n",
- argv[0], strerror(-status));
+ argv[0], gpiod_strerror(gpiod_errno()));
return EXIT_FAILURE;
}