1
0
mirror of https://gitlab.xiph.org/xiph/icecast-common.git synced 2024-09-22 04:15:55 -04:00

Merge branch 'update-interface-io' into libigloo

This commit is contained in:
Philipp Schafft 2019-10-03 11:13:18 +00:00
commit 0589e0b97b
4 changed files with 157 additions and 108 deletions

View File

@ -105,17 +105,18 @@ 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 (*peek)(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 +144,14 @@ 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);
/* Peeks on the input side of the handle.
*
* This does the same as igloo_io_read() expect that the data is not removed from the read queue.
* This is likely not to be supported by some backends.
*/
ssize_t igloo_io_peek(igloo_io_t *io, void *buffer, size_t len, igloo_error_t *error);
/* Write data to a IO handle.
* Parameters:
* io
@ -155,7 +163,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 +174,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 +184,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 +193,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 +216,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,20 +238,9 @@ 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
/* On a listen socket accept a new connection.
* Parameters:
* io
* The IO handle to operate on.
* Returns:
* The new connection or igloo_RO_NULL.
*/
/* TODO: Allow accept to accept()'s and accept4()'s additional parameters.
igloo_io_t *igloo_io_accept(igloo_io_t *io);
*/
/* Advanced control interface.
* Parameters:
* io
@ -259,7 +256,7 @@ igloo_io_t *igloo_io_accept(igloo_io_t *io);
* 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
}

161
src/io.c
View File

@ -15,6 +15,7 @@
#include <igloo/ro.h>
#include <igloo/io.h>
#include <igloo/error.h>
#include "private.h"
struct igloo_io_tag {
@ -57,13 +58,51 @@ igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_ob
return io;
}
#define __read_fun(x) \
ssize_t igloo_io_ ## x (igloo_io_t *io, void *buffer, size_t len, igloo_error_t *error) \
{ \
ssize_t ret = -1; \
igloo_error_t error_store; \
\
if (!error) \
error = &error_store; \
\
if (!io || !buffer) {\
*error = igloo_ERROR_FAULT; \
return -1; \
} \
\
if (!len) \
return 0; \
\
igloo_thread_mutex_lock(&(io->lock)); \
io->touched = 1; \
\
if (io->ifdesc->x) {\
ret = io->ifdesc->x(igloo_INTERFACE_BASIC_CALL(io), buffer, len, error); \
} else { \
*error = igloo_ERROR_GENERIC; \
} \
igloo_thread_mutex_unlock(&(io->lock)); \
\
return ret; \
}
ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len)
__read_fun(read)
__read_fun(peek)
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)
if (!error)
error = &error_store;
if (!io || !buffer) {
*error = igloo_ERROR_FAULT;
return -1;
}
if (!len)
return 0;
@ -71,39 +110,22 @@ ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len)
igloo_thread_mutex_lock(&(io->lock));
io->touched = 1;
if (io->ifdesc->read)
ret = io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
if (io->ifdesc->write) {
ret = io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len, error);
} else {
*error = igloo_ERROR_GENERIC;
}
igloo_thread_mutex_unlock(&(io->lock));
return ret;
}
ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len)
igloo_error_t igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags)
{
ssize_t ret = -1;
if (!io || !buffer)
return -1;
if (!len)
return 0;
igloo_thread_mutex_lock(&(io->lock));
io->touched = 1;
if (io->ifdesc->write)
ret = io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
igloo_thread_mutex_unlock(&(io->lock));
return ret;
}
int 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 +137,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 +150,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 +162,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 +184,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 +245,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 +282,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 +296,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 +316,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 +339,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 +358,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
}

View File

@ -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)

View File

@ -13,6 +13,7 @@
#include <stdio.h>
#include <igloo/io.h>
#include <igloo/error.h>
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 = {