mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-12-04 14:46:31 -05:00
commit
e35629a35c
@ -20,13 +20,19 @@ pkginclude_HEADERS = \
|
|||||||
include/igloo/ro.h \
|
include/igloo/ro.h \
|
||||||
include/igloo/types.h \
|
include/igloo/types.h \
|
||||||
include/igloo/typedef.h \
|
include/igloo/typedef.h \
|
||||||
|
include/igloo/interface.h \
|
||||||
|
include/igloo/io.h \
|
||||||
|
include/igloo/stdio.h \
|
||||||
include/igloo/buffer.h \
|
include/igloo/buffer.h \
|
||||||
include/igloo/list.h \
|
include/igloo/list.h \
|
||||||
include/igloo/reportxml.h
|
include/igloo/reportxml.h
|
||||||
|
|
||||||
libigloo_la_SOURCES = \
|
libigloo_la_SOURCES = \
|
||||||
src/libigloo.c \
|
src/libigloo.c \
|
||||||
|
src/interface.c \
|
||||||
src/ro.c \
|
src/ro.c \
|
||||||
|
src/io.c \
|
||||||
|
src/stdio.c \
|
||||||
src/buffer.c \
|
src/buffer.c \
|
||||||
src/list.c \
|
src/list.c \
|
||||||
src/reportxml.c
|
src/reportxml.c
|
||||||
|
66
include/igloo/interface.h
Normal file
66
include/igloo/interface.h
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
/* Copyright (C) 2019 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBIGLOO__INTERFACE_H_
|
||||||
|
#define _LIBIGLOO__INTERFACE_H_
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Put a good description of this file here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Put stuff here */
|
||||||
|
|
||||||
|
#include "ro.h"
|
||||||
|
|
||||||
|
/* Basic arguments that should be passed to all interface functions */
|
||||||
|
#define igloo_INTERFACE_BASIC_ARGS igloo_ro_t self, igloo_ro_t *backend_object, void **backend_userdata
|
||||||
|
|
||||||
|
/* Basic free callback.
|
||||||
|
* If this does not set *backend_object to igloo_RO_NULL
|
||||||
|
* backend_object will be freed by calling igloo_ro_unref().
|
||||||
|
* If this does not set *backend_userdata to NULL
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef int (*igloo_interface_free_t)(igloo_INTERFACE_BASIC_ARGS);
|
||||||
|
|
||||||
|
#define igloo_INTERFACE_DESCRIPTION_BASE__VERSION 1
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t base_length;
|
||||||
|
int base_version;
|
||||||
|
size_t description_length;
|
||||||
|
igloo_interface_free_t free;
|
||||||
|
} igloo_interface_base_ifdesc_t;
|
||||||
|
|
||||||
|
#define igloo_INTERFACE_DESCRIPTION_BASE(type, ...) \
|
||||||
|
.__base = { \
|
||||||
|
.base_length = sizeof(igloo_interface_base_ifdesc_t), \
|
||||||
|
.base_version = igloo_INTERFACE_DESCRIPTION_BASE__VERSION, \
|
||||||
|
.description_length = sizeof(type) \
|
||||||
|
, ## __VA_ARGS__ \
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! _LIBIGLOO__INTERFACE_H_ */
|
268
include/igloo/io.h
Normal file
268
include/igloo/io.h
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
/* Copyright (C) 2019 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBIGLOO__IO_H_
|
||||||
|
#define _LIBIGLOO__IO_H_
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Put a good description of this file here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Put stuff here */
|
||||||
|
|
||||||
|
#include <igloo/config.h>
|
||||||
|
|
||||||
|
#ifdef IGLOO_CTC_HAVE_SYS_SELECT_H
|
||||||
|
#include <sys/select.h>
|
||||||
|
#endif
|
||||||
|
#ifdef IGLOO_CTC_HAVE_POLL
|
||||||
|
#include <poll.h>
|
||||||
|
#endif
|
||||||
|
#ifdef IGLOO_CTC_HAVE_STDINT_H
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
#ifdef IGLOO_CTC_STDC_HEADERS
|
||||||
|
#include <stdarg.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ro.h"
|
||||||
|
#include "interface.h"
|
||||||
|
|
||||||
|
/* About thread safety:
|
||||||
|
* This set of functions is thread safe.
|
||||||
|
*/
|
||||||
|
|
||||||
|
igloo_RO_FORWARD_TYPE(igloo_io_t);
|
||||||
|
|
||||||
|
/* Type of blocking.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/* Error state, used as return value only. */
|
||||||
|
igloo_IO_BLOCKINGMODE_ERROR = -1,
|
||||||
|
/* No blocking is done. This is the eqivalent of setting O_NONBLOCK on a POSIX system. */
|
||||||
|
igloo_IO_BLOCKINGMODE_NONE = 0,
|
||||||
|
/* Full blocking is done. This is the eqivalent of unsetting O_NONBLOCK on a POSIX system. */
|
||||||
|
igloo_IO_BLOCKINGMODE_FULL
|
||||||
|
} libigloo_io_blockingmode_t;
|
||||||
|
|
||||||
|
/* Type for operaton flags.
|
||||||
|
*/
|
||||||
|
#ifdef IGLOO_CTC_HAVE_STDINT_H
|
||||||
|
typedef uint_least32_t igloo_io_opflag_t;
|
||||||
|
#else
|
||||||
|
typedef unsigned long int igloo_io_opflag_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* No operation flags set. Usefull for variable initialization. */
|
||||||
|
#define igloo_IO_OPFLAG_NONE ((igloo_io_opflag_t)0x0000)
|
||||||
|
/* Use default flags. Other flags can be set in addition. */
|
||||||
|
#define igloo_IO_OPFLAG_DEFAULTS ((igloo_io_opflag_t)0x8000)
|
||||||
|
|
||||||
|
/* Operate on actual data. */
|
||||||
|
#define igloo_IO_OPFLAG_DATA ((igloo_io_opflag_t)0x0001)
|
||||||
|
/* Operate on metadata. */
|
||||||
|
#define igloo_IO_OPFLAG_METADATA ((igloo_io_opflag_t)0x0002)
|
||||||
|
/* Operate on data and metadata. */
|
||||||
|
#define igloo_IO_OPFLAG_FULL (igloo_IO_OPFLAG_DATAONLY|igloo_IO_OPFLAG_METADATAONLY)
|
||||||
|
/* Instructs the operation that it should ignore the output state of the object.
|
||||||
|
* This may improve performance as buffer flushes may be skipped.
|
||||||
|
* However with this set any external software interacting with this object
|
||||||
|
* MUST NOT interact with the output side of this object.
|
||||||
|
*/
|
||||||
|
#define igloo_IO_OPFLAG_NOWRITE ((igloo_io_opflag_t)0x0010)
|
||||||
|
|
||||||
|
/* Get the referenced value */
|
||||||
|
#define igloo_IO_OPFLAG_GET ((igloo_io_opflag_t)0x0100)
|
||||||
|
/* Set the referenced value */
|
||||||
|
#define igloo_IO_OPFLAG_SET ((igloo_io_opflag_t)0x0200)
|
||||||
|
|
||||||
|
/* Advanced control functions.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
igloo_IO_CONTROL_NONE = 0
|
||||||
|
} igloo_io_control_t;
|
||||||
|
|
||||||
|
/* Interface description */
|
||||||
|
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);
|
||||||
|
#ifdef IGLOO_CTC_STDC_HEADERS
|
||||||
|
int (*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, ...);
|
||||||
|
#endif
|
||||||
|
} igloo_io_ifdesc_t;
|
||||||
|
|
||||||
|
/* This creates a new IO handle from a interface description and state.
|
||||||
|
* Parameters:
|
||||||
|
* ifdesc
|
||||||
|
* The interface description to use.
|
||||||
|
* backend_object
|
||||||
|
* A object used by the backend or igloo_RO_NULL.
|
||||||
|
* backend_userdata
|
||||||
|
* A userdata pointer used by the backend or NULL.
|
||||||
|
* name, associated
|
||||||
|
* See refobject_new().
|
||||||
|
*/
|
||||||
|
igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_object, void *backend_userdata, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
/* Read data from a IO handle.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* buffer
|
||||||
|
* The buffer to read to.
|
||||||
|
* len
|
||||||
|
* The maximum amount of bytes to read.
|
||||||
|
* Returns:
|
||||||
|
* The actual amount of bytes read.
|
||||||
|
*/
|
||||||
|
ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len);
|
||||||
|
/* Write data to a IO handle.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* buffer
|
||||||
|
* The buffer to write from.
|
||||||
|
* len
|
||||||
|
* The maximum amount of bytes to write.
|
||||||
|
* Returns:
|
||||||
|
* The actual amount of bytes written.
|
||||||
|
*/
|
||||||
|
ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len);
|
||||||
|
|
||||||
|
/* Flush internal buffers to the underlying object.
|
||||||
|
* This does not guarantee that all data has been written to the physical level
|
||||||
|
* on return. It just queues the flush.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* flags
|
||||||
|
* Flags for this operation.
|
||||||
|
*/
|
||||||
|
int 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.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* flags
|
||||||
|
* Flags for this operation.
|
||||||
|
*/
|
||||||
|
int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags);
|
||||||
|
|
||||||
|
/* Set and get the blocking state of the object.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
#ifdef IGLOO_CTC_HAVE_SYS_SELECT_H
|
||||||
|
/* Those functions act as igloo's replacement for FD_SET(), FD_CLR(), and FD_SET() and
|
||||||
|
* allow the caller to use the select() system call.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* set
|
||||||
|
* The fd_set to operate on.
|
||||||
|
* maxfd
|
||||||
|
* This parameter is updated to reflect the added handle(s)
|
||||||
|
* in select()'s nfds parameter.
|
||||||
|
* flags
|
||||||
|
* Flags for this operation.
|
||||||
|
* It may be useful to igloo_IO_OPFLAG_NOWRITE in some cases. See it's definition.
|
||||||
|
* Notes:
|
||||||
|
* This may call igloo_io_sync(). If the object is touched between calls to igloo_io_select_set(),
|
||||||
|
* select() 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.
|
||||||
|
* 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);
|
||||||
|
int igloo_io_select_isset(igloo_io_t *io, fd_set *set);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IGLOO_CTC_HAVE_POLL
|
||||||
|
/* This function initializes the pollfd structure to use this handle
|
||||||
|
* with the poll() system call.
|
||||||
|
* Parameters:
|
||||||
|
* io
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* fd
|
||||||
|
* The structure to initialize.
|
||||||
|
* events
|
||||||
|
* The events to set. libigloo uses different internal parameters based
|
||||||
|
* on this parameter's value. The parameter MUST NOT be changed in the structre
|
||||||
|
* after initialization.
|
||||||
|
* Notes:
|
||||||
|
* This may call igloo_io_sync(). If the object is touched between calls to igloo_io_poll_fill(),
|
||||||
|
* 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);
|
||||||
|
#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
|
||||||
|
* The IO handle to operate on.
|
||||||
|
* flags
|
||||||
|
* Flags for this operation.
|
||||||
|
* Most controls accept igloo_IO_OPFLAG_GET and igloo_IO_OPFLAG_SET.
|
||||||
|
* If both are set the value is first set as with igloo_IO_OPFLAG_SET and
|
||||||
|
* the OLD value is returned as with igloo_IO_OPFLAG_GET.
|
||||||
|
* control
|
||||||
|
* The control command to use.
|
||||||
|
* ...
|
||||||
|
* 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, ...);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! _LIBIGLOO__IO_H_ */
|
40
include/igloo/stdio.h
Normal file
40
include/igloo/stdio.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright (C) 2019 Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Library General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LIBIGLOO__STDIO_H_
|
||||||
|
#define _LIBIGLOO__STDIO_H_
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Put a good description of this file here
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Put stuff here */
|
||||||
|
|
||||||
|
#include "io.h"
|
||||||
|
|
||||||
|
igloo_io_t * igloo_stdio_new_file(const char *filename, const char *mode, const char *name, igloo_ro_t associated);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! _LIBIGLOO__STDIO_H_ */
|
@ -32,6 +32,7 @@ extern "C" {
|
|||||||
/* Included in case is not yet included */
|
/* Included in case is not yet included */
|
||||||
#include "typedef.h"
|
#include "typedef.h"
|
||||||
|
|
||||||
|
typedef struct igloo_io_tag igloo_io_t;
|
||||||
typedef struct igloo_buffer_tag igloo_buffer_t;
|
typedef struct igloo_buffer_tag igloo_buffer_t;
|
||||||
typedef struct igloo_list_tag igloo_list_t;
|
typedef struct igloo_list_tag igloo_list_t;
|
||||||
|
|
||||||
@ -50,6 +51,7 @@ igloo_RO_FORWARD_TYPE(igloo_ro_base_t);
|
|||||||
typedef union __attribute__ ((__transparent_union__)) {
|
typedef union __attribute__ ((__transparent_union__)) {
|
||||||
/* Those are libigloo's own types */
|
/* Those are libigloo's own types */
|
||||||
igloo_RO_TYPE(igloo_ro_base_t)
|
igloo_RO_TYPE(igloo_ro_base_t)
|
||||||
|
igloo_RO_TYPE(igloo_io_t)
|
||||||
igloo_RO_TYPE(igloo_buffer_t)
|
igloo_RO_TYPE(igloo_buffer_t)
|
||||||
igloo_RO_TYPE(igloo_list_t)
|
igloo_RO_TYPE(igloo_list_t)
|
||||||
igloo_RO_TYPE(igloo_reportxml_t)
|
igloo_RO_TYPE(igloo_reportxml_t)
|
||||||
|
62
src/interface.c
Normal file
62
src/interface.c
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/* Icecast
|
||||||
|
*
|
||||||
|
* This program is distributed under the GNU General Public License, version 2.
|
||||||
|
* A copy of this license is included with this source.
|
||||||
|
*
|
||||||
|
* Copyright 2019, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <igloo/ro.h>
|
||||||
|
#include <igloo/io.h>
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
void igloo_interface_base_free(igloo_ro_t self)
|
||||||
|
{
|
||||||
|
igloo__interface_base_t *iface = igloo_INTERFACE_CAST(self);
|
||||||
|
|
||||||
|
if (iface->ifdesc && iface->ifdesc->free)
|
||||||
|
iface->ifdesc->free(igloo_INTERFACE_BASIC_CALL(self));
|
||||||
|
|
||||||
|
if (!igloo_RO_IS_NULL(iface->backend_object))
|
||||||
|
igloo_ro_unref(iface->backend_object);
|
||||||
|
|
||||||
|
if (iface->backend_userdata)
|
||||||
|
free(iface->backend_userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_ro_t igloo_interface_base_new_real(const igloo_ro_type_t *type, size_t description_length, const igloo_interface_base_ifdesc_t *ifdesc, igloo_ro_t backend_object, void *backend_userdata, const char *name, igloo_ro_t associated)
|
||||||
|
{
|
||||||
|
igloo_ro_t self;
|
||||||
|
igloo__interface_base_t *base;
|
||||||
|
|
||||||
|
if (!ifdesc)
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
|
||||||
|
if (ifdesc->base_length != sizeof(igloo_interface_base_ifdesc_t) || ifdesc->base_version != igloo_INTERFACE_DESCRIPTION_BASE__VERSION || ifdesc->description_length != description_length)
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
|
||||||
|
self = igloo_ro_new__raw(type, name, associated);
|
||||||
|
base = igloo_INTERFACE_CAST(self);
|
||||||
|
|
||||||
|
if (igloo_RO_IS_NULL(self))
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
|
||||||
|
if (!igloo_RO_IS_NULL(backend_object)) {
|
||||||
|
if (igloo_ro_ref(backend_object) != 0) {
|
||||||
|
igloo_ro_unref(self);
|
||||||
|
return igloo_RO_NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
base->ifdesc = ifdesc;
|
||||||
|
base->backend_object = backend_object;
|
||||||
|
base->backend_userdata = backend_userdata;
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
330
src/io.c
Normal file
330
src/io.c
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
/* Icecast
|
||||||
|
*
|
||||||
|
* This program is distributed under the GNU General Public License, version 2.
|
||||||
|
* A copy of this license is included with this source.
|
||||||
|
*
|
||||||
|
* Copyright 2019, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <igloo/ro.h>
|
||||||
|
#include <igloo/io.h>
|
||||||
|
#include "private.h"
|
||||||
|
|
||||||
|
struct igloo_io_tag {
|
||||||
|
igloo_interface_base(io)
|
||||||
|
|
||||||
|
/* Mutex for igloo_ro_*(). */
|
||||||
|
igloo_mutex_t lock;
|
||||||
|
|
||||||
|
int touched;
|
||||||
|
#if defined(IGLOO_CTC_HAVE_SYS_SELECT_H) || defined(IGLOO_CTC_HAVE_POLL)
|
||||||
|
int fd;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __free(igloo_ro_t self)
|
||||||
|
{
|
||||||
|
igloo_io_t *io = igloo_RO_TO_TYPE(self, igloo_io_t);
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
igloo_thread_mutex_destroy(&(io->lock));
|
||||||
|
igloo_interface_base_free(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
igloo_RO_PUBLIC_TYPE(igloo_io_t,
|
||||||
|
igloo_RO_TYPEDECL_FREE(__free)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_object, void *backend_userdata, const char *name, igloo_ro_t associated)
|
||||||
|
{
|
||||||
|
igloo_io_t *io = igloo_interface_base_new(igloo_io_t, ifdesc, backend_object, backend_userdata, name, associated);
|
||||||
|
if (!io)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
igloo_thread_mutex_create(&(io->lock));
|
||||||
|
|
||||||
|
io->touched = 1;
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len)
|
||||||
|
{
|
||||||
|
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->read)
|
||||||
|
ret = io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
|
||||||
|
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 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;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
io->touched = 1;
|
||||||
|
|
||||||
|
if (io->ifdesc->flush)
|
||||||
|
ret = io->ifdesc->flush(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->ifdesc->flush)
|
||||||
|
io->ifdesc->flush(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||||
|
|
||||||
|
if (io->ifdesc->sync) {
|
||||||
|
ret = io->ifdesc->sync(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||||
|
if (ret != 0) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
io->touched = 0;
|
||||||
|
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (mode != igloo_IO_BLOCKINGMODE_NONE && mode != igloo_IO_BLOCKINGMODE_FULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
io->touched = 1;
|
||||||
|
|
||||||
|
if (io->ifdesc->set_blockingmode)
|
||||||
|
ret = io->ifdesc->set_blockingmode(igloo_INTERFACE_BASIC_CALL(io), mode);
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
libigloo_io_blockingmode_t igloo_io_get_blockingmode(igloo_io_t *io)
|
||||||
|
{
|
||||||
|
libigloo_io_blockingmode_t ret = igloo_IO_BLOCKINGMODE_ERROR;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
return igloo_IO_BLOCKINGMODE_ERROR;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->ifdesc->get_blockingmode)
|
||||||
|
ret = io->ifdesc->get_blockingmode(igloo_INTERFACE_BASIC_CALL(io));
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!io || !set || !maxfd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (!io->ifdesc->get_fd_for_systemcall) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->touched) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io));
|
||||||
|
if (io->fd < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
FD_SET(io->fd, set);
|
||||||
|
if (*maxfd < io->fd)
|
||||||
|
*maxfd = io->fd;
|
||||||
|
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int igloo_io_select_clear(igloo_io_t *io, fd_set *set)
|
||||||
|
{
|
||||||
|
if (!io || !set)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->touched || io->fd < 0) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FD_CLR(io->fd, set);
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int igloo_io_select_isset(igloo_io_t *io, fd_set *set)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (!io || !set)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (!io->touched && io->fd >= 0)
|
||||||
|
ret = FD_ISSET(io->fd, set) ? 1 : 0;
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IGLOO_CTC_HAVE_POLL
|
||||||
|
int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events)
|
||||||
|
{
|
||||||
|
static const short safe_events = POLLIN|POLLPRI
|
||||||
|
#ifdef POLLRDHUP
|
||||||
|
|POLLRDHUP
|
||||||
|
#endif
|
||||||
|
#ifdef POLLRDNORM
|
||||||
|
|POLLRDNORM
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
int is_safe;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (!io || !fd)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (io->touched || !is_safe) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
ret = igloo_io_sync(io, igloo_IO_OPFLAG_DEFAULTS|(is_safe ? 0 : igloo_IO_OPFLAG_NOWRITE));
|
||||||
|
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->touched) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io));
|
||||||
|
if (io->fd < 0) {
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(fd, 0, sizeof(*fd));
|
||||||
|
fd->fd = io->fd;
|
||||||
|
fd->events = events;
|
||||||
|
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int 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;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
if (!io)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
igloo_thread_mutex_lock(&(io->lock));
|
||||||
|
if (io->ifdesc->control) {
|
||||||
|
va_start(ap, control);
|
||||||
|
ret = io->ifdesc->control(igloo_INTERFACE_BASIC_CALL(io), flags, control, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
igloo_thread_mutex_unlock(&(io->lock));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
|
}
|
@ -19,6 +19,8 @@
|
|||||||
#ifndef _LIBIGLOO__PRIVATE_H_
|
#ifndef _LIBIGLOO__PRIVATE_H_
|
||||||
#define _LIBIGLOO__PRIVATE_H_
|
#define _LIBIGLOO__PRIVATE_H_
|
||||||
|
|
||||||
|
#include <igloo/interface.h>
|
||||||
|
|
||||||
/* init/shutdown of the library */
|
/* init/shutdown of the library */
|
||||||
void igloo_thread_initialize(void);
|
void igloo_thread_initialize(void);
|
||||||
void igloo_thread_initialize_with_log_id(int log_id);
|
void igloo_thread_initialize_with_log_id(int log_id);
|
||||||
@ -30,5 +32,27 @@ void igloo_resolver_shutdown(void);
|
|||||||
void igloo_log_initialize(void);
|
void igloo_log_initialize(void);
|
||||||
void igloo_log_shutdown(void);
|
void igloo_log_shutdown(void);
|
||||||
|
|
||||||
|
/* Basic interface */
|
||||||
|
#define igloo_interface_base(type) \
|
||||||
|
/* The base object. */ \
|
||||||
|
igloo_ro_base_t __base; \
|
||||||
|
/* The interface description */ \
|
||||||
|
const igloo_ ## type ## _ifdesc_t *ifdesc; \
|
||||||
|
/* Backend object */ \
|
||||||
|
igloo_ro_t backend_object; \
|
||||||
|
/* Backend userdata */ \
|
||||||
|
void *backend_userdata;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
igloo_interface_base(interface_base)
|
||||||
|
} igloo__interface_base_t;
|
||||||
|
|
||||||
|
void igloo_interface_base_free(igloo_ro_t self);
|
||||||
|
|
||||||
|
#define igloo_INTERFACE_CAST(obj) ((igloo__interface_base_t*)igloo_RO__GETBASE(obj))
|
||||||
|
#define igloo_INTERFACE_BASIC_CALL(obj) (obj), &(igloo_INTERFACE_CAST(obj)->backend_object), &(igloo_INTERFACE_CAST(obj)->backend_userdata)
|
||||||
|
|
||||||
|
igloo_ro_t igloo_interface_base_new_real(const igloo_ro_type_t *type, size_t description_length, const igloo_interface_base_ifdesc_t *ifdesc, igloo_ro_t backend_object, void *backend_userdata, const char *name, igloo_ro_t associated);
|
||||||
|
#define igloo_interface_base_new(type, ifdesc, backend_object, backend_userdata, name, associated) igloo_RO_TO_TYPE(igloo_interface_base_new_real(igloo_ro__type__ ## type, sizeof(*(ifdesc)), (const igloo_interface_base_ifdesc_t*)(ifdesc), (backend_object), (backend_userdata), (name), (associated)), type)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
78
src/stdio.c
Normal file
78
src/stdio.c
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* Icecast
|
||||||
|
*
|
||||||
|
* This program is distributed under the GNU General Public License, version 2.
|
||||||
|
* A copy of this license is included with this source.
|
||||||
|
*
|
||||||
|
* Copyright 2019, Philipp "ph3-der-loewe" Schafft <lion@lion.leolix.org>,
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include <config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include <igloo/io.h>
|
||||||
|
|
||||||
|
static int __free(igloo_INTERFACE_BASIC_ARGS)
|
||||||
|
{
|
||||||
|
fclose(*backend_userdata);
|
||||||
|
*backend_userdata = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ssize_t __read(igloo_INTERFACE_BASIC_ARGS, void *buffer, size_t len)
|
||||||
|
{
|
||||||
|
return fread(buffer, 1, len, *backend_userdata);
|
||||||
|
}
|
||||||
|
static ssize_t __write(igloo_INTERFACE_BASIC_ARGS, const void *buffer, size_t len)
|
||||||
|
{
|
||||||
|
return fwrite(buffer, 1, len, *backend_userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __flush(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags)
|
||||||
|
{
|
||||||
|
return fflush(*backend_userdata) == 0 ? 0 : -1;
|
||||||
|
}
|
||||||
|
static int __sync(igloo_INTERFACE_BASIC_ARGS, igloo_io_opflag_t flags)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
static libigloo_io_blockingmode_t __get_blockingmode(igloo_INTERFACE_BASIC_ARGS)
|
||||||
|
{
|
||||||
|
return igloo_IO_BLOCKINGMODE_FULL;
|
||||||
|
}
|
||||||
|
static int __get_fd_for_systemcall(igloo_INTERFACE_BASIC_ARGS)
|
||||||
|
{
|
||||||
|
return fileno(*backend_userdata);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const igloo_io_ifdesc_t igloo_stdio_ifdesc = {
|
||||||
|
igloo_INTERFACE_DESCRIPTION_BASE(igloo_io_ifdesc_t,
|
||||||
|
.free = __free
|
||||||
|
),
|
||||||
|
.read = __read,
|
||||||
|
.write = __write,
|
||||||
|
.flush = __flush,
|
||||||
|
.sync = __sync,
|
||||||
|
.get_blockingmode = __get_blockingmode,
|
||||||
|
.get_fd_for_systemcall = __get_fd_for_systemcall
|
||||||
|
};
|
||||||
|
|
||||||
|
igloo_io_t * igloo_stdio_new_file(const char *filename, const char *mode, const char *name, igloo_ro_t associated)
|
||||||
|
{
|
||||||
|
FILE *file = fopen(filename, mode);
|
||||||
|
igloo_io_t *io;
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
io = igloo_io_new(&igloo_stdio_ifdesc, igloo_RO_NULL, file, name, associated);
|
||||||
|
if (!io) {
|
||||||
|
fclose(file);
|
||||||
|
return io;
|
||||||
|
}
|
||||||
|
|
||||||
|
return io;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user