From: Bartosz Golaszewski Date: Sat, 24 Jun 2017 10:21:57 +0000 (+0200) Subject: core: kill custom error handling X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=cc0b3fac72db7c6c04ea4571c5c2af6cb823e0a6;p=qemu-gpiodev%2Flibgpiod.git core: kill custom error handling 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 --- diff --git a/configure.ac b/configure.ac index 7972c4b..383cdf1 100644 --- a/configure.ac +++ b/configure.ac @@ -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])]) diff --git a/include/gpiod.h b/include/gpiod.h index 2750f49..e1bfa78 100644 --- a/include/gpiod.h +++ b/include/gpiod.h @@ -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; - /** * @} * diff --git a/src/lib/core.c b/src/lib/core.c index 680f5c1..8d38694 100644 --- a/src/lib/core.c +++ b/src/lib/core.c @@ -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; diff --git a/src/tools/tools-common.c b/src/tools/tools-common.c index 5c2df53..74a85bc 100644 --- a/src/tools/tools-common.c +++ b/src/tools/tools-common.c @@ -16,6 +16,7 @@ #include #include #include +#include #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); diff --git a/tests/tests-chip.c b/tests/tests-chip.c index 09fe82e..693ccdf 100644 --- a/tests/tests-chip.c +++ b/tests/tests-chip.c @@ -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", diff --git a/tests/tests-line.c b/tests/tests-line.c index 44031af..3b36a20 100644 --- a/tests/tests-line.c +++ b/tests/tests-line.c @@ -10,6 +10,8 @@ #include "gpiod-test.h" +#include + 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", diff --git a/tests/tests-misc.c b/tests/tests-misc.c index 178c277..5806376 100644 --- a/tests/tests-misc.c +++ b/tests/tests-misc.c @@ -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, { }); diff --git a/tests/tests-simple-api.c b/tests/tests-simple-api.c index 24f5a8a..7f5a031 100644 --- a/tests/tests-simple-api.c +++ b/tests/tests-simple-api.c @@ -10,6 +10,8 @@ #include "gpiod-test.h" +#include + 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",