diff --git a/include/igloo/io.h b/include/igloo/io.h index da002fd..3e42e53 100644 --- a/include/igloo/io.h +++ b/include/igloo/io.h @@ -105,17 +105,17 @@ typedef enum { typedef struct { igloo_interface_base_ifdesc_t __base; - ssize_t (*read)(igloo_INTERFACE_BASIC_ARGS, void *buffer, size_t len); - ssize_t (*write)(igloo_INTERFACE_BASIC_ARGS, const void *buffer, size_t len); - int (*flush)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags); - int (*sync)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags); - int (*set_blockingmode)(igloo_INTERFACE_BASIC_ARGS, libigloo_io_blockingmode_t mode); - libigloo_io_blockingmode_t (*get_blockingmode)(igloo_INTERFACE_BASIC_ARGS); - int (*get_fd_for_systemcall)(igloo_INTERFACE_BASIC_ARGS); + ssize_t (*read)(igloo_INTERFACE_BASIC_ARGS, void *buffer, size_t len, igloo_error_t *error); + ssize_t (*write)(igloo_INTERFACE_BASIC_ARGS, const void *buffer, size_t len, igloo_error_t *error); + igloo_error_t (*flush)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags); + igloo_error_t (*sync)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags); + igloo_error_t (*set_blockingmode)(igloo_INTERFACE_BASIC_ARGS, libigloo_io_blockingmode_t mode); + igloo_error_t (*get_blockingmode)(igloo_INTERFACE_BASIC_ARGS, libigloo_io_blockingmode_t *mode); + igloo_error_t (*get_fd_for_systemcall)(igloo_INTERFACE_BASIC_ARGS, int *fd); #ifdef IGLOO_CTC_STDC_HEADERS - int (*control)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags, igloo_io_control_t control, va_list ap); + igloo_error_t (*control)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags, igloo_io_control_t control, va_list ap); #else - int (*control)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags, igloo_io_control_t control, ...); + igloo_error_t (*control)(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags, igloo_io_control_t control, ...); #endif } igloo_io_ifdesc_t; @@ -143,7 +143,7 @@ igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_ob * Returns: * The actual amount of bytes read. */ -ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len); +ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len, igloo_error_t *error); /* Write data to a IO handle. * Parameters: * io @@ -155,7 +155,7 @@ ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len); * Returns: * The actual amount of bytes written. */ -ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len); +ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len, igloo_error_t *error); /* Flush internal buffers to the underlying object. * This does not guarantee that all data has been written to the physical level @@ -166,7 +166,7 @@ ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len); * flags * Flags for this operation. */ -int igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags); +igloo_error_t igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags); /* Sync object with physical state. This is used to get the object into a state * that allows passing the underlying object to other software. * This may also flush internal buffers. @@ -176,7 +176,7 @@ int igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags); * flags * Flags for this operation. */ -int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags); +igloo_error_t igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags); /* Set and get the blocking state of the object. * Parameters: @@ -185,8 +185,8 @@ int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags); * mode * The new blocking mode. */ -int igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode); -libigloo_io_blockingmode_t igloo_io_get_blockingmode(igloo_io_t *io); +igloo_error_t igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode); +igloo_error_t igloo_io_get_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t *mode); #ifdef IGLOO_CTC_HAVE_SYS_SELECT_H /* Those functions act as igloo's replacement for FD_SET(), FD_CLR(), and FD_SET() and @@ -208,8 +208,8 @@ libigloo_io_blockingmode_t igloo_io_get_blockingmode(igloo_io_t *io); * to avoid this, as finding the correct parameters for igloo_io_sync() might be tricky. * The object MUST NOT be touched between select() and igloo_io_select_isset(). */ -int igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag_t flags); -int igloo_io_select_clear(igloo_io_t *io, fd_set *set); +igloo_error_t igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag_t flags); +igloo_error_t igloo_io_select_clear(igloo_io_t *io, fd_set *set); int igloo_io_select_isset(igloo_io_t *io, fd_set *set); #endif @@ -230,7 +230,7 @@ int igloo_io_select_isset(igloo_io_t *io, fd_set *set); * poll() the user MUST call igloo_io_sync() with the correct flags. It is RECOMMENDED * to avoid this, as finding the correct parameters for igloo_io_sync() might be tricky. */ -int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events); +igloo_error_t igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events); #endif /* Advanced control interface. @@ -248,7 +248,7 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events); * Additional parameters if any. * Values are always passed as pointers. */ -int igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t control, ...); +igloo_error_t igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t control, ...); #ifdef __cplusplus } diff --git a/src/io.c b/src/io.c index b65aa35..84c4217 100644 --- a/src/io.c +++ b/src/io.c @@ -15,6 +15,7 @@ #include #include +#include #include "private.h" struct igloo_io_tag { @@ -58,9 +59,10 @@ igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_ob } -ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len) +ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len, igloo_error_t *error) { ssize_t ret = -1; + igloo_error_t error_store; if (!io || !buffer) return -1; @@ -68,19 +70,23 @@ ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len) if (!len) return 0; + if (!error) + error = &error_store; + igloo_thread_mutex_lock(&(io->lock)); io->touched = 1; if (io->ifdesc->read) - ret = io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len); + ret = io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len, error); igloo_thread_mutex_unlock(&(io->lock)); return ret; } -ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len) +ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len, igloo_error_t *error) { ssize_t ret = -1; + igloo_error_t error_store; if (!io || !buffer) return -1; @@ -88,22 +94,25 @@ ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len) if (!len) return 0; + if (!error) + error = &error_store; + igloo_thread_mutex_lock(&(io->lock)); io->touched = 1; if (io->ifdesc->write) - ret = io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len); + ret = io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len, error); igloo_thread_mutex_unlock(&(io->lock)); return ret; } -int igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags) +igloo_error_t igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags) { - int ret = -1; + igloo_error_t ret = igloo_ERROR_GENERIC; if (!io) - return -1; + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); io->touched = 1; @@ -115,12 +124,12 @@ int igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags) return ret; } -int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags) +igloo_error_t igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags) { - int ret; + igloo_error_t ret; if (!io) - return -1; + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); if (io->ifdesc->flush) @@ -128,7 +137,7 @@ int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags) if (io->ifdesc->sync) { ret = io->ifdesc->sync(igloo_INTERFACE_BASIC_CALL(io), flags); - if (ret != 0) { + if (ret != igloo_ERROR_NONE) { igloo_thread_mutex_unlock(&(io->lock)); return ret; } @@ -140,18 +149,18 @@ int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags) } igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } -int igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode) +igloo_error_t igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode) { - int ret = -1; + igloo_error_t ret = igloo_ERROR_GENERIC; if (!io) - return -1; + return igloo_ERROR_FAULT; if (mode != igloo_IO_BLOCKINGMODE_NONE && mode != igloo_IO_BLOCKINGMODE_FULL) - return -1; + return igloo_ERROR_INVAL; igloo_thread_mutex_lock(&(io->lock)); io->touched = 1; @@ -162,52 +171,60 @@ int igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode) return ret; } -libigloo_io_blockingmode_t igloo_io_get_blockingmode(igloo_io_t *io) +igloo_error_t igloo_io_get_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t *mode) { libigloo_io_blockingmode_t ret = igloo_IO_BLOCKINGMODE_ERROR; + igloo_error_t error = igloo_ERROR_GENERIC; - if (!io) - return igloo_IO_BLOCKINGMODE_ERROR; + if (!io || !mode) + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); if (io->ifdesc->get_blockingmode) - ret = io->ifdesc->get_blockingmode(igloo_INTERFACE_BASIC_CALL(io)); + error = io->ifdesc->get_blockingmode(igloo_INTERFACE_BASIC_CALL(io), &ret); igloo_thread_mutex_unlock(&(io->lock)); - return ret; + if (error != igloo_ERROR_NONE) + return error; + + *mode = ret; + + return igloo_ERROR_NONE; } #ifdef IGLOO_CTC_HAVE_SYS_SELECT_H -int igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag_t flags) +igloo_error_t igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag_t flags) { - int ret; + igloo_error_t ret; if (!io || !set || !maxfd) - return -1; + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); if (!io->ifdesc->get_fd_for_systemcall) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } if (io->touched || !(flags & igloo_IO_OPFLAG_NOWRITE)) { igloo_thread_mutex_unlock(&(io->lock)); ret = igloo_io_sync(io, igloo_IO_OPFLAG_DEFAULTS|(flags & igloo_IO_OPFLAG_NOWRITE)); - if (ret != 0) + if (ret != igloo_ERROR_NONE) return ret; igloo_thread_mutex_lock(&(io->lock)); if (io->touched) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } } - io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io)); + ret = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io), &(io->fd)); + if (ret != igloo_ERROR_NONE) + return ret; if (io->fd < 0) - return -1; + return igloo_ERROR_GENERIC; FD_SET(io->fd, set); if (*maxfd < io->fd) @@ -215,24 +232,24 @@ int igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag igloo_thread_mutex_unlock(&(io->lock)); - return 0; + return igloo_ERROR_NONE; } -int igloo_io_select_clear(igloo_io_t *io, fd_set *set) +igloo_error_t igloo_io_select_clear(igloo_io_t *io, fd_set *set) { if (!io || !set) - return -1; + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); if (io->touched || io->fd < 0) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } FD_CLR(io->fd, set); igloo_thread_mutex_unlock(&(io->lock)); - return 0; + return igloo_ERROR_GENERIC; } int igloo_io_select_isset(igloo_io_t *io, fd_set *set) @@ -252,7 +269,7 @@ int igloo_io_select_isset(igloo_io_t *io, fd_set *set) #endif #ifdef IGLOO_CTC_HAVE_POLL -int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events) +igloo_error_t igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events) { static const short safe_events = POLLIN|POLLPRI #ifdef POLLRDHUP @@ -266,14 +283,14 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events) int ret; if (!io || !fd) - return -1; + return igloo_ERROR_FAULT; is_safe = !((events|safe_events) - safe_events); igloo_thread_mutex_lock(&(io->lock)); if (!io->ifdesc->get_fd_for_systemcall) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } if (io->touched || !is_safe) { @@ -286,14 +303,17 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events) igloo_thread_mutex_lock(&(io->lock)); if (io->touched) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } } - io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io)); + ret = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io), &(io->fd)); if (io->fd < 0) { + ret = igloo_ERROR_GENERIC; + } + if (ret != igloo_ERROR_NONE) { igloo_thread_mutex_unlock(&(io->lock)); - return -1; + return igloo_ERROR_GENERIC; } memset(fd, 0, sizeof(*fd)); @@ -306,14 +326,14 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events) } #endif -int igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t control, ...) +igloo_error_t igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t control, ...) { #ifdef IGLOO_CTC_STDC_HEADERS - int ret = -1; + igloo_error_t ret = igloo_ERROR_GENERIC; va_list ap; if (!io) - return -1; + return igloo_ERROR_FAULT; igloo_thread_mutex_lock(&(io->lock)); if (io->ifdesc->control) { @@ -325,6 +345,6 @@ int igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t return ret; #else - return -1; + return igloo_ERROR_GENERIC; #endif } diff --git a/src/logmsg.c b/src/logmsg.c index 9588071..2ae6669 100644 --- a/src/logmsg.c +++ b/src/logmsg.c @@ -227,7 +227,7 @@ static igloo_filter_result_t __handle(igloo_INTERFACE_BASIC_ARGS, igloo_ro_t obj break; } - igloo_io_write(igloo_RO_TO_TYPE(*backend_object, igloo_io_t), pre, strlen(pre)); + igloo_io_write(igloo_RO_TO_TYPE(*backend_object, igloo_io_t), pre, strlen(pre), NULL); return igloo_FILTER_RESULT_PASS; } @@ -239,7 +239,7 @@ static int __flush(igloo_INTERFACE_BASIC_ARGS) if (!io) return 0; - return igloo_io_flush(io, igloo_IO_OPFLAG_DEFAULTS|igloo_IO_OPFLAG_FULL); + return igloo_io_flush(io, igloo_IO_OPFLAG_DEFAULTS|igloo_IO_OPFLAG_FULL) == igloo_ERROR_NONE ? 0 : -1; } static int __set_backend(igloo_INTERFACE_BASIC_ARGS, igloo_ro_t backend) diff --git a/src/stdio.c b/src/stdio.c index c62fc0a..5e9ab9f 100644 --- a/src/stdio.c +++ b/src/stdio.c @@ -13,6 +13,7 @@ #include #include +#include static int __free(igloo_INTERFACE_BASIC_ARGS) { @@ -22,30 +23,48 @@ static int __free(igloo_INTERFACE_BASIC_ARGS) } -static ssize_t __read(igloo_INTERFACE_BASIC_ARGS, void *buffer, size_t len) +static ssize_t __read(igloo_INTERFACE_BASIC_ARGS, void *buffer, size_t len, igloo_error_t *error) { - return fread(buffer, 1, len, *backend_userdata); + ssize_t ret = fread(buffer, 1, len, *backend_userdata); + + if (ret < 0) { + *error = igloo_ERROR_IO; + } else { + *error = igloo_ERROR_NONE; + } + + return ret; } -static ssize_t __write(igloo_INTERFACE_BASIC_ARGS, const void *buffer, size_t len) +static ssize_t __write(igloo_INTERFACE_BASIC_ARGS, const void *buffer, size_t len, igloo_error_t *error) { - return fwrite(buffer, 1, len, *backend_userdata); + ssize_t ret = fwrite(buffer, 1, len, *backend_userdata); + + if (ret < 0) { + *error = igloo_ERROR_IO; + } else { + *error = igloo_ERROR_NONE; + } + + return ret; } -static int __flush(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags) +static igloo_error_t __flush(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags) { - return fflush(*backend_userdata) == 0 ? 0 : -1; + return fflush(*backend_userdata) == 0 ? igloo_ERROR_NONE : igloo_ERROR_GENERIC; } -static int __sync(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags) +static igloo_error_t __sync(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags) { - return 0; + return igloo_ERROR_NONE; } -static libigloo_io_blockingmode_t __get_blockingmode(igloo_INTERFACE_BASIC_ARGS) +static igloo_error_t __get_blockingmode(igloo_INTERFACE_BASIC_ARGS, libigloo_io_blockingmode_t *mode) { - return igloo_IO_BLOCKINGMODE_FULL; + *mode = igloo_IO_BLOCKINGMODE_FULL; + return igloo_ERROR_NONE; } -static int __get_fd_for_systemcall(igloo_INTERFACE_BASIC_ARGS) +static igloo_error_t __get_fd_for_systemcall(igloo_INTERFACE_BASIC_ARGS, int *fd) { - return fileno(*backend_userdata); + *fd = fileno(*backend_userdata); + return igloo_ERROR_NONE; } static const igloo_io_ifdesc_t igloo_stdio_ifdesc = {