core: kill custom error handling
authorBartosz Golaszewski <bartekgola@gmail.com>
Sat, 24 Jun 2017 10:21:57 +0000 (12:21 +0200)
committerBartosz Golaszewski <bartekgola@gmail.com>
Thu, 6 Jul 2017 09:11:36 +0000 (11:11 +0200)
The libgpiod-specific error codes are not really necessary and can be
easily replaced with regular libc error numbers defined in errno.h.

Remove all routines and definitions dealing with error numbers and
switch to using errnos in the library code.

Signed-off-by: Bartosz Golaszewski <bartekgola@gmail.com>
configure.ac
include/gpiod.h
src/lib/core.c
src/tools/tools-common.c
tests/tests-chip.c
tests/tests-line.c
tests/tests-misc.c
tests/tests-simple-api.c

index 7972c4b83ff7d38b1d048723fd4c9391a7cc3b06..383cdf14104532c8abb37c98ac88bb255c330de3 100644 (file)
@@ -44,7 +44,6 @@ AC_DEFUN([HEADER_NOT_FOUND_LIB],
 # This is always checked (library needs this)
 AC_HEADER_STDC
 AC_FUNC_MALLOC
-AC_FUNC_STRERROR_R
 AC_CHECK_FUNC([ioctl], [], [FUNC_NOT_FOUND_LIB([ioctl])])
 AC_CHECK_FUNC([asprintf], [], [FUNC_NOT_FOUND_LIB([asprintf])])
 AC_CHECK_FUNC([readdir], [], [FUNC_NOT_FOUND_LIB([readdir])])
index 2750f49738a8cbb9a91142aa0d895aea479c0630..e1bfa78be50b02465a174fed20f727f5ad58aa9d 100644 (file)
@@ -51,66 +51,6 @@ struct gpiod_chip_iter;
  */
 #define GPIOD_BIT(nr)          (1UL << (nr))
 
-/**
- * @}
- *
- * @defgroup __error__ Error handling
- * @{
- *
- * Error handling functions and macros. This library uses a combination of
- * system-wide errno numbers and internal GPIO-specific errors. The routines
- * in this section should be used to access the information about any error
- * conditions that may occur.
- *
- * With some noted exceptions, all libgpiod functions set the last error
- * variable if an error occurs. Internally, the last_error variable has a
- * separate instance per thread making the library thread-safe.
- */
-
-/**
- * @brief Private: offset for all libgpiod error numbers.
- */
-#define _GPIOD_ERRNO_OFFSET    10000
-
-/**
- * @brief libgpiod-specific error numbers.
- */
-enum {
-       GPIOD_ESUCCESS = _GPIOD_ERRNO_OFFSET,
-       /**< No error. */
-       GPIOD_EREQUEST,
-       /**< The caller has no ownership of this line. */
-       GPIOD_EEVREQUEST,
-       /**< The caller has not configured any events on this line. */
-       GPIOD_EBULKINCOH,
-       /**< Not all lines in bulk belong to the same GPIO chip. */
-       GPIOD_ELINEBUSY,
-       /**< This line is currently in use. */
-       GPIOD_ELINEMAX,
-       /**< Number of lines in the request exceeds limit. */
-       _GPIOD_MAX_ERR,
-       /**< Private: number of libgpiod-specific error numbers. */
-};
-
-/**
- * @brief Return last error.
- * @return Number of the last error inside libgpiod.
- */
-int gpiod_errno(void) GPIOD_API;
-
-/**
- * @brief Convert error number to a human-readable string.
- * @param errnum Error number to convert.
- * @return Pointer to a null-terminated error description.
- */
-const char * gpiod_strerror(int errnum) GPIOD_API;
-
-/**
- * @brief Convert the last libgpiod error number to a human-readable string.
- * @return Pointer to a null-terminated error description.
- */
-const char * gpiod_last_strerror(void) GPIOD_API;
-
 /**
  * @}
  *
index 680f5c1328018e47d237e02aeb2b52801324bad8..8d386941cd54b84e0fe166acd298debbb4270bfe 100644 (file)
@@ -69,45 +69,13 @@ struct gpiod_chip_iter {
 static const char dev_dir[] = "/dev/";
 static const char cdev_prefix[] = "gpiochip";
 
-/*
- * The longest error message in glibc is about 50 characters long so 64 should
- * be enough to store every error message in the future too.
- */
-#define ERRSTR_MAX 64
-
-static __thread int last_error;
-static __thread char errmsg[ERRSTR_MAX];
-
-static const char *const error_descr[] = {
-       "success",
-       "GPIO line not reserved",
-       "no events configured on GPIO line",
-       "GPIO lines in bulk don't belong to the same gpiochip",
-       "GPIO line currently in use",
-       "number of lines in the request exceeds limit",
-};
-
-static void set_last_error(int errnum)
-{
-       last_error = errnum;
-}
-
-static void last_error_from_errno(void)
-{
-       last_error = errno;
-}
-
 static MALLOC void * zalloc(size_t size)
 {
        void *ptr;
 
        ptr = malloc(size);
-       if (!ptr) {
-               set_last_error(ENOMEM);
-               return NULL;
-       }
-
-       memset(ptr, 0, size);
+       if (ptr)
+               memset(ptr, 0, size);
 
        return ptr;
 }
@@ -127,50 +95,7 @@ static void nsec_to_timespec(uint64_t nsec, struct timespec *ts)
 
 static int gpio_ioctl(int fd, unsigned long request, void *data)
 {
-       int status;
-
-       status = ioctl(fd, request, data);
-       if (status < 0) {
-               last_error_from_errno();
-               return -1;
-       }
-
-       return 0;
-}
-
-int gpiod_errno(void)
-{
-       return last_error;
-}
-
-static const char * strerror_r_wrapper(int errnum, char *buf, size_t buflen)
-{
-#ifdef STRERROR_R_CHAR_P
-       return strerror_r(errnum, buf, buflen);
-#else
-       int status;
-
-       status = strerror_r(errnum, buf, buflen);
-       if (status != 0)
-               snprintf(buf, buflen, "error in strerror_r(): %d", status);
-
-       return buf;
-#endif
-}
-
-const char * gpiod_strerror(int errnum)
-{
-       if (errnum < _GPIOD_ERRNO_OFFSET)
-               return strerror_r_wrapper(errnum, errmsg, sizeof(errmsg));
-       else if (errnum > _GPIOD_MAX_ERR)
-               return "invalid error number";
-       else
-               return error_descr[errnum - _GPIOD_ERRNO_OFFSET];
-}
-
-const char * gpiod_last_strerror(void)
-{
-       return gpiod_strerror(gpiod_errno());
+       return ioctl(fd, request, data);
 }
 
 int gpiod_simple_get_value_multiple(const char *consumer, const char *device,
@@ -184,7 +109,7 @@ int gpiod_simple_get_value_multiple(const char *consumer, const char *device,
        int status;
 
        if (num_lines > GPIOD_REQUEST_MAX_LINES) {
-               set_last_error(GPIOD_ELINEMAX);
+               errno = EINVAL;
                return -1;
        }
 
@@ -232,7 +157,7 @@ int gpiod_simple_set_value_multiple(const char *consumer, const char *device,
        int status;
 
        if (num_lines > GPIOD_REQUEST_MAX_LINES) {
-               set_last_error(GPIOD_ELINEMAX);
+               errno = EINVAL;
                return -1;
        }
 
@@ -297,7 +222,7 @@ int gpiod_simple_event_loop(const char *consumer, const char *device,
        for (;;) {
                status = gpiod_line_event_wait(line, timeout);
                if (status < 0) {
-                       if (gpiod_errno() == EINTR)
+                       if (errno == EINTR)
                                return evtype = GPIOD_EVENT_CB_TIMEOUT;
                        else
                                goto out;
@@ -539,12 +464,12 @@ static bool verify_line_bulk(struct gpiod_line_bulk *bulk)
                line = bulk->lines[i];
 
                if (i > 0 && chip != gpiod_line_get_chip(line)) {
-                       set_last_error(GPIOD_EBULKINCOH);
+                       errno = EINVAL;
                        return false;
                }
 
                if (!gpiod_line_is_free(line)) {
-                       set_last_error(GPIOD_ELINEBUSY);
+                       errno = EBUSY;
                        return false;
                }
        }
@@ -701,7 +626,7 @@ int gpiod_line_get_value_bulk(struct gpiod_line_bulk *bulk, int *values)
 
        if (!line_bulk_is_reserved(bulk) &&
            !line_bulk_is_event_configured(bulk)) {
-               set_last_error(GPIOD_EREQUEST);
+               errno = EPERM;
                return -1;
        }
 
@@ -739,7 +664,7 @@ int gpiod_line_set_value_bulk(struct gpiod_line_bulk *bulk, int *values)
        int status;
 
        if (!line_bulk_is_reserved(bulk)) {
-               set_last_error(GPIOD_EREQUEST);
+               errno = EPERM;
                return -1;
        }
 
@@ -801,7 +726,7 @@ int gpiod_line_event_request(struct gpiod_line *line,
        int status, fd;
 
        if (!gpiod_line_is_free(line)) {
-               set_last_error(GPIOD_ELINEBUSY);
+               errno = EBUSY;
                return -1;
        }
 
@@ -907,7 +832,7 @@ int gpiod_line_event_wait_bulk(struct gpiod_line_bulk *bulk,
        int status;
 
        if (!line_bulk_is_event_configured(bulk)) {
-               set_last_error(GPIOD_EEVREQUEST);
+               errno = EPERM;
                return -1;
        }
 
@@ -921,12 +846,10 @@ int gpiod_line_event_wait_bulk(struct gpiod_line_bulk *bulk,
        }
 
        status = ppoll(fds, bulk->num_lines, timeout, NULL);
-       if (status < 0) {
-               last_error_from_errno();
+       if (status < 0)
                return -1;
-       } else if (status == 0) {
+       else if (status == 0)
                return 0;
-       }
 
        for (i = 0; !fds[i].revents; i++);
        if (line)
@@ -941,7 +864,7 @@ int gpiod_line_event_read(struct gpiod_line *line,
        int fd;
 
        if (!gpiod_line_event_configured(line)) {
-               set_last_error(GPIOD_EEVREQUEST);
+               errno = EPERM;
                return -1;
        }
 
@@ -965,10 +888,9 @@ int gpiod_line_event_read_fd(int fd, struct gpiod_line_event *event)
 
        rd = read(fd, &evdata, sizeof(evdata));
        if (rd < 0) {
-               last_error_from_errno();
                return -1;
        } else if (rd != sizeof(evdata)) {
-               set_last_error(EIO);
+               errno = EIO;
                return -1;
        }
 
@@ -986,10 +908,8 @@ struct gpiod_chip * gpiod_chip_open(const char *path)
        int status, fd;
 
        fd = open(path, O_RDWR | O_CLOEXEC);
-       if (fd < 0) {
-               last_error_from_errno();
+       if (fd < 0)
                return NULL;
-       }
 
        chip = zalloc(sizeof(*chip));
        if (!chip) {
@@ -1023,10 +943,8 @@ struct gpiod_chip * gpiod_chip_open_by_name(const char *name)
        int status;
 
        status = asprintf(&path, "%s%s", dev_dir, name);
-       if (status < 0) {
-               last_error_from_errno();
+       if (status < 0)
                return NULL;
-       }
 
        chip = gpiod_chip_open(path);
        free(path);
@@ -1041,10 +959,8 @@ struct gpiod_chip * gpiod_chip_open_by_number(unsigned int num)
        int status;
 
        status = asprintf(&path, "%s%s%u", dev_dir, cdev_prefix, num);
-       if (!status) {
-               last_error_from_errno();
+       if (!status)
                return NULL;
-       }
 
        chip = gpiod_chip_open(path);
        free(path);
@@ -1136,7 +1052,7 @@ gpiod_chip_get_line(struct gpiod_chip *chip, unsigned int offset)
        int status;
 
        if (offset >= chip->cinfo.lines) {
-               set_last_error(EINVAL);
+               errno = EINVAL;
                return NULL;
        }
 
@@ -1165,10 +1081,8 @@ struct gpiod_chip_iter * gpiod_chip_iter_new(void)
                return NULL;
 
        new->dir = opendir(dev_dir);
-       if (!new->dir) {
-               last_error_from_errno();
+       if (!new->dir)
                return NULL;
-       }
 
        new->state = CHIP_ITER_INIT;
 
index 5c2df531c39d749fb3487adbd741a17bfc3ec317..74a85bc411949b6d5ad8e5e6789b5a427c1a376f 100644 (file)
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <stdarg.h>
 #include <libgen.h>
+#include <errno.h>
 
 #define NORETURN               __attribute__((noreturn))
 
@@ -51,7 +52,7 @@ void NORETURN PRINTF(1, 2) die_perror(const char *fmt, ...)
        va_start(va, fmt);
        fprintf(stderr, "%s: ", progname);
        vfprintf(stderr, fmt, va);
-       fprintf(stderr, ": %s\n", gpiod_last_strerror());
+       fprintf(stderr, ": %s\n", strerror(errno));
        va_end(va);
 
        exit(EXIT_FAILURE);
index 09fe82ea5f79d754e0f0ed6738f74c0a05b7b865..693ccdf3c23b7145c0239ae2a0cf0ed6a8b49abd 100644 (file)
@@ -30,7 +30,7 @@ static void chip_open_nonexistent(void)
 
        chip = gpiod_chip_open("/dev/nonexistent_gpiochip");
        TEST_ASSERT_NULL(chip);
-       TEST_ASSERT_EQ(gpiod_errno(), ENOENT);
+       TEST_ASSERT_EQ(errno, ENOENT);
 }
 TEST_DEFINE(chip_open_nonexistent,
            "gpiod_chip_open() - nonexistent chip",
@@ -42,7 +42,7 @@ static void chip_open_notty(void)
 
        chip = gpiod_chip_open("/dev/null");
        TEST_ASSERT_NULL(chip);
-       TEST_ASSERT_EQ(gpiod_errno(), ENOTTY);
+       TEST_ASSERT_EQ(errno, ENOTTY);
 }
 TEST_DEFINE(chip_open_notty,
            "gpiod_chip_open() - notty",
index 44031afeb9a7b577c74931bde7eef3f4f5cd36e6..3b36a20663beea1b92f3c724a6b955bd35dff90f 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "gpiod-test.h"
 
+#include <errno.h>
+
 static void line_request_output(void)
 {
        TEST_CLEANUP(test_close_chip) struct gpiod_chip *chip = NULL;
@@ -57,7 +59,7 @@ static void line_request_already_requested(void)
 
        status = gpiod_line_request_input(line, TEST_CONSUMER, false);
        TEST_ASSERT_NOTEQ(status, 0);
-       TEST_ASSERT_EQ(gpiod_errno(), GPIOD_ELINEBUSY);
+       TEST_ASSERT_EQ(errno, EBUSY);
 }
 TEST_DEFINE(line_request_already_requested,
            "gpiod_line_request() - already requested",
@@ -217,7 +219,7 @@ static void line_request_bulk_different_chips(void)
 
        status = gpiod_line_request_bulk(&bulk, &req, NULL);
        TEST_ASSERT_NOTEQ(status, 0);
-       TEST_ASSERT_EQ(gpiod_errno(), GPIOD_EBULKINCOH);
+       TEST_ASSERT_EQ(errno, EINVAL);
 }
 TEST_DEFINE(line_request_bulk_different_chips,
            "gpiod_line_request_bulk() - different chips",
index 178c277b828c9fb996dcdd3f126f6a1b035e9e67..5806376bf74686b4fabfddb539180e442602d0dd 100644 (file)
@@ -23,22 +23,3 @@ static void version_string(void)
 TEST_DEFINE(version_string,
            "gpiod_version_string()",
            0, { });
-
-static void error_handling(void)
-{
-       struct gpiod_chip *chip;
-       int err;
-
-       chip = gpiod_chip_open("/dev/nonexistent_gpiochip");
-       TEST_ASSERT_NULL(chip);
-
-       err = gpiod_errno();
-       TEST_ASSERT_EQ(err, ENOENT);
-
-       TEST_ASSERT_NOT_NULL(gpiod_strerror(err));
-       TEST_ASSERT(strlen(gpiod_strerror(err)) > 0);
-       TEST_ASSERT_STR_EQ(gpiod_strerror(err), gpiod_last_strerror());
-}
-TEST_DEFINE(error_handling,
-           "error handling",
-           0, { });
index 24f5a8acffd28ad4cd4643d891ba4de61d03aa5a..7f5a031dfd4a4e54669209775f6653acb8bdb905 100644 (file)
@@ -10,6 +10,8 @@
 
 #include "gpiod-test.h"
 
+#include <errno.h>
+
 static void simple_set_get_value(void)
 {
        int ret;
@@ -95,7 +97,7 @@ static void simple_get_value_multiple_max_lines(void)
                                              GPIOD_REQUEST_MAX_LINES + 1,
                                              false);
        TEST_ASSERT_NOTEQ(ret, 0);
-       TEST_ASSERT_EQ(gpiod_errno(), GPIOD_ELINEMAX);
+       TEST_ASSERT_EQ(errno, EINVAL);
 }
 TEST_DEFINE(simple_get_value_multiple_max_lines,
            "gpiod_simple_get_value_multiple() exceed max lines",
@@ -111,7 +113,7 @@ static void simple_set_value_multiple_max_lines(void)
                                              GPIOD_REQUEST_MAX_LINES + 1,
                                              false, NULL, NULL);
        TEST_ASSERT_NOTEQ(ret, 0);
-       TEST_ASSERT_EQ(gpiod_errno(), GPIOD_ELINEMAX);
+       TEST_ASSERT_EQ(errno, EINVAL);
 }
 TEST_DEFINE(simple_set_value_multiple_max_lines,
            "gpiod_simple_set_value_multiple() exceed max lines",