From 89940dfc601d5689aef54d5dfc6ca734406c0e0d Mon Sep 17 00:00:00 2001 From: Shane Bryldt Date: Tue, 31 Jan 2017 19:28:21 +0000 Subject: [PATCH] FS-9952: Fixed some stuff to get the blade service tested upto the point of processing config and listening on the same port across multiple interfaces --- libs/libblade/src/blade_service.c | 52 +++++-- libs/libblade/src/blade_stack.c | 15 +- libs/libblade/test/Makefile.am | 2 +- libs/libblade/test/bladec | 228 ++++++++++++++++++++++++++++++ libs/libblade/test/bladec.c | 40 +++++- libs/libblade/test/bladec.cfg | 50 +++++++ libs/libks/src/include/simclist.h | 143 +++++++++---------- libs/libks/src/ks_socket.c | 9 ++ libs/libks/src/simclist.c | 88 ++++++------ 9 files changed, 492 insertions(+), 135 deletions(-) create mode 100755 libs/libblade/test/bladec create mode 100644 libs/libblade/test/bladec.cfg diff --git a/libs/libblade/src/blade_service.c b/libs/libblade/src/blade_service.c index b52e7d06a9..4eabd669af 100644 --- a/libs/libblade/src/blade_service.c +++ b/libs/libblade/src/blade_service.c @@ -130,13 +130,25 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config) ks_assert(bs); - if (!config) return KS_STATUS_FAIL; - if (!config_setting_is_group(config)) return KS_STATUS_FAIL; + if (!config) { + ks_log(KS_LOG_DEBUG, "!config\n"); + return KS_STATUS_FAIL; + } + if (!config_setting_is_group(config)) { + ks_log(KS_LOG_DEBUG, "!config_setting_is_group(config)\n"); + return KS_STATUS_FAIL; + } websockets = config_setting_get_member(config, "websockets"); - if (!websockets) return KS_STATUS_FAIL; - websockets_endpoints = config_setting_get_member(config, "endpoints"); - if (!websockets_endpoints) return KS_STATUS_FAIL; + if (!websockets) { + ks_log(KS_LOG_DEBUG, "!websockets\n"); + return KS_STATUS_FAIL; + } + websockets_endpoints = config_setting_get_member(websockets, "endpoints"); + if (!websockets_endpoints) { + ks_log(KS_LOG_DEBUG, "!websockets_endpoints\n"); + return KS_STATUS_FAIL; + } websockets_endpoints_ipv4 = config_lookup_from(websockets_endpoints, "ipv4"); websockets_endpoints_ipv6 = config_lookup_from(websockets_endpoints, "ipv6"); if (websockets_endpoints_ipv4) { @@ -156,6 +168,10 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config) config_setting_get_string(tmp1), config_setting_get_int(tmp2), AF_INET) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + ks_log(KS_LOG_DEBUG, + "Binding to IPV4 %s on port %d\n", + ks_addr_get_host(&config_websockets_endpoints_ipv4[index]), + ks_addr_get_port(&config_websockets_endpoints_ipv4[index])); } } if (websockets_endpoints_ipv6) { @@ -175,6 +191,10 @@ ks_status_t blade_service_config(blade_service_t *bs, config_setting_t *config) config_setting_get_string(tmp1), config_setting_get_int(tmp2), AF_INET6) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + ks_log(KS_LOG_DEBUG, + "Binding to IPV6 %s on port %d\n", + ks_addr_get_host(&config_websockets_endpoints_ipv6[index]), + ks_addr_get_port(&config_websockets_endpoints_ipv6[index])); } } if (config_websockets_endpoints_ipv4_length + config_websockets_endpoints_ipv6_length <= 0) return KS_STATUS_FAIL; @@ -212,13 +232,22 @@ KS_DECLARE(ks_status_t) blade_service_startup(blade_service_t *bs, config_settin // @todo: If the configuration is invalid, and this is a case of reloading a new config, then the service shutdown shouldn't occur // but the service may use configuration that changes before we shutdown if it is read successfully, may require a config reader/writer mutex? - if (blade_service_config(bs, config) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_service_config(bs, config) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_service_config failed\n"); + return KS_STATUS_FAIL; + } for (int32_t index = 0; index < bs->config_websockets_endpoints_ipv4_length; ++index) { - if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv4[index]) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv4[index]) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_service_listen (v4) failed\n"); + return KS_STATUS_FAIL; + } } for (int32_t index = 0; index < bs->config_websockets_endpoints_ipv6_length; ++index) { - if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv6[index]) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_service_listen(bs, &bs->config_websockets_endpoints_ipv6[index]) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_service_listen (v6) failed\n"); + return KS_STATUS_FAIL; + } } if (ks_thread_create_ex(&bs->listeners_thread, @@ -282,20 +311,23 @@ ks_status_t blade_service_listen(blade_service_t *bs, ks_sockaddr_t *addr) ks_assert(addr); if ((listener = socket(addr->family, SOCK_STREAM, IPPROTO_TCP)) == KS_SOCK_INVALID) { + ks_log(KS_LOG_DEBUG, "listener == KS_SOCK_INVALID\n"); ret = KS_STATUS_FAIL; goto done; } ks_socket_option(listener, SO_REUSEADDR, KS_TRUE); ks_socket_option(listener, TCP_NODELAY, KS_TRUE); - // @todo make sure v6 does not automatically map to a v4 using socket option IPV6_V6ONLY? + if (addr->family == AF_INET6) ks_socket_option(listener, IPV6_V6ONLY, KS_TRUE); if (ks_addr_bind(listener, addr) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "ks_addr_bind(listener, addr) != KS_STATUS_SUCCESS\n"); ret = KS_STATUS_FAIL; goto done; } if (listen(listener, bs->config_websockets_endpoints_backlog) != 0) { + ks_log(KS_LOG_DEBUG, "listen(listener, backlog) != 0\n"); ret = KS_STATUS_FAIL; goto done; } @@ -327,6 +359,8 @@ void *blade_service_listeners_thread(ks_thread_t *thread, void *data) ks_assert(data); service = (blade_service_t *)data; + + ks_log(KS_LOG_DEBUG, "Service running\n"); // @todo 1 more callback for blade_service_state_callback_t? providing event up the stack on service startup, shutdown, and service errors? diff --git a/libs/libblade/src/blade_stack.c b/libs/libblade/src/blade_stack.c index 48a89afe0d..8504af02c4 100644 --- a/libs/libblade/src/blade_stack.c +++ b/libs/libblade/src/blade_stack.c @@ -147,18 +147,27 @@ KS_DECLARE(ks_status_t) blade_handle_startup(blade_handle_t *bh, config_setting_ { ks_assert(bh); - if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_handle_config(bh, config) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_handle_config failed\n"); + return KS_STATUS_FAIL; + } if (bh->config_service && !blade_handle_service_available(bh)) { blade_service_create(&bh->service, bh->pool, bh->tpool, bh, service_peer_state_callback); ks_assert(bh->service); - if (blade_service_startup(bh->service, bh->config_service) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_service_startup(bh->service, bh->config_service) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_service_startup failed\n"); + return KS_STATUS_FAIL; + } } if (bh->config_datastore && !blade_handle_datastore_available(bh)) { blade_datastore_create(&bh->datastore, bh->pool, bh->tpool); ks_assert(bh->datastore); - if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) return KS_STATUS_FAIL; + if (blade_datastore_startup(bh->datastore, bh->config_datastore) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_DEBUG, "blade_datastore_startup failed\n"); + return KS_STATUS_FAIL; + } } return KS_STATUS_SUCCESS; diff --git a/libs/libblade/test/Makefile.am b/libs/libblade/test/Makefile.am index d577b95507..9bc1a688df 100644 --- a/libs/libblade/test/Makefile.am +++ b/libs/libblade/test/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS += -I$(abs_top_srcdir)/src/include -g -ggdb -O0 -TEST_LDADD = $(abs_top_builddir)/libblade.la +TEST_LDADD = $(abs_top_builddir)/libblade.la -lconfig -lm -lpthread check_PROGRAMS = check_PROGRAMS += testbuild diff --git a/libs/libblade/test/bladec b/libs/libblade/test/bladec new file mode 100755 index 0000000000..805d6501b3 --- /dev/null +++ b/libs/libblade/test/bladec @@ -0,0 +1,228 @@ +#! /bin/bash + +# bladec - temporary wrapper script for .libs/bladec +# Generated by libtool (GNU libtool) 2.4.2 Debian-2.4.2-1.11 +# +# The bladec program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +sed_quote_subst='s/\([`"$\\]\)/\\\1/g' + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac +fi +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +relink_command="(cd /usr/src/freeswitch/libs/libblade/test; { test -z \"\${LIBRARY_PATH+set}\" || unset LIBRARY_PATH || { LIBRARY_PATH=; export LIBRARY_PATH; }; }; { test -z \"\${COMPILER_PATH+set}\" || unset COMPILER_PATH || { COMPILER_PATH=; export COMPILER_PATH; }; }; { test -z \"\${GCC_EXEC_PREFIX+set}\" || unset GCC_EXEC_PREFIX || { GCC_EXEC_PREFIX=; export GCC_EXEC_PREFIX; }; }; { test -z \"\${LD_RUN_PATH+set}\" || unset LD_RUN_PATH || { LD_RUN_PATH=; export LD_RUN_PATH; }; }; { test -z \"\${LD_LIBRARY_PATH+set}\" || unset LD_LIBRARY_PATH || { LD_LIBRARY_PATH=; export LD_LIBRARY_PATH; }; }; PATH=/usr/lib/ccache:/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin:/opt/bin:/usr/local/bin:/usr/local/sbin:/usr/local/freeswitch/bin; export PATH; gcc -fPIC -Wall -std=c99 -pedantic -DUSE_SCHED_SETSCHEDULER=1 -DKS_API_VISIBILITY=1 -fvisibility=hidden -Werror -DHAVE_PTHREAD_SETSCHEDPARAM=1 -DHAVE_OPENSSL -fsanitize=address -fno-omit-frame-pointer -I/usr/src/freeswitch/libs/libblade/src/include -g -ggdb -O0 -g -O2 -fsanitize=address -o \$progdir/\$file bladec-bladec.o bladec-tap.o -L/usr/src/freeswitch/libs/libblade/../libks/.libs/ /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.so -lsodium /usr/src/freeswitch/libs/libblade/.libs/libblade.so -lconfig -lm -lpthread -lssl -lcrypto -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/../libks/.libs/ -Wl,-rpath -Wl,/usr/src/freeswitch/libs/libblade/.libs)" + +# This environment variable determines our operation mode. +if test "$libtool_install_magic" = "%%%MAGIC variable%%%"; then + # install mode needs the following variables: + generated_by_libtool_version='2.4.2' + notinst_deplibs=' /usr/src/freeswitch/libs/libblade/../libks/.libs//libks.la /usr/src/freeswitch/libs/libblade/libblade.la' +else + # When we are sourced in execute mode, $file and $ECHO are already set. + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + file="$0" + +# A function that is used when there is no print builtin or printf. +func_fallback_echo () +{ + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' +} + ECHO="printf %s\\n" + fi + +# Very basic option parsing. These options are (a) specific to +# the libtool wrapper, (b) are identical between the wrapper +# /script/ and the wrapper /executable/ which is used only on +# windows platforms, and (c) all begin with the string --lt- +# (application programs are unlikely to have options which match +# this pattern). +# +# There are only two supported options: --lt-debug and +# --lt-dump-script. There is, deliberately, no --lt-help. +# +# The first argument to this parsing function should be the +# script's ../libtool value, followed by no. +lt_option_debug= +func_parse_lt_options () +{ + lt_script_arg0=$0 + shift + for lt_opt + do + case "$lt_opt" in + --lt-debug) lt_option_debug=1 ;; + --lt-dump-script) + lt_dump_D=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%/[^/]*$%%'` + test "X$lt_dump_D" = "X$lt_script_arg0" && lt_dump_D=. + lt_dump_F=`$ECHO "X$lt_script_arg0" | /bin/sed -e 's/^X//' -e 's%^.*/%%'` + cat "$lt_dump_D/$lt_dump_F" + exit 0 + ;; + --lt-*) + $ECHO "Unrecognized --lt- option: '$lt_opt'" 1>&2 + exit 1 + ;; + esac + done + + # Print the debug banner immediately: + if test -n "$lt_option_debug"; then + echo "bladec:bladec:${LINENO}: libtool wrapper (GNU libtool) 2.4.2 Debian-2.4.2-1.11" 1>&2 + fi +} + +# Used when --lt-debug. Prints its arguments to stdout +# (redirection is the responsibility of the caller) +func_lt_dump_args () +{ + lt_dump_args_N=1; + for lt_arg + do + $ECHO "bladec:bladec:${LINENO}: newargv[$lt_dump_args_N]: $lt_arg" + lt_dump_args_N=`expr $lt_dump_args_N + 1` + done +} + +# Core function for launching the target application +func_exec_program_core () +{ + + if test -n "$lt_option_debug"; then + $ECHO "bladec:bladec:${LINENO}: newargv[0]: $progdir/$program" 1>&2 + func_lt_dump_args ${1+"$@"} 1>&2 + fi + exec "$progdir/$program" ${1+"$@"} + + $ECHO "$0: cannot exec $program $*" 1>&2 + exit 1 +} + +# A function to encapsulate launching the target application +# Strips options in the --lt-* namespace from $@ and +# launches target application with the remaining arguments. +func_exec_program () +{ + case " $* " in + *\ --lt-*) + for lt_wr_arg + do + case $lt_wr_arg in + --lt-*) ;; + *) set x "$@" "$lt_wr_arg"; shift;; + esac + shift + done ;; + esac + func_exec_program_core ${1+"$@"} +} + + # Parse options + func_parse_lt_options "$0" ${1+"$@"} + + # Find the directory that this script lives in. + thisdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'` + test "x$thisdir" = "x$file" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=`ls -ld "$file" | /bin/sed -n 's/.*-> //p'` + while test -n "$file"; do + destdir=`$ECHO "$file" | /bin/sed 's%/[^/]*$%%'` + + # If there was a directory component, then change thisdir. + if test "x$destdir" != "x$file"; then + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir="$destdir" ;; + *) thisdir="$thisdir/$destdir" ;; + esac + fi + + file=`$ECHO "$file" | /bin/sed 's%^.*/%%'` + file=`ls -ld "$thisdir/$file" | /bin/sed -n 's/.*-> //p'` + done + + # Usually 'no', except on cygwin/mingw when embedded into + # the cwrapper. + WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=no + if test "$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR" = "yes"; then + # special case for '.' + if test "$thisdir" = "."; then + thisdir=`pwd` + fi + # remove .libs from thisdir + case "$thisdir" in + *[\\/].libs ) thisdir=`$ECHO "$thisdir" | /bin/sed 's%[\\/][^\\/]*$%%'` ;; + .libs ) thisdir=. ;; + esac + fi + + # Try to get the absolute directory name. + absdir=`cd "$thisdir" && pwd` + test -n "$absdir" && thisdir="$absdir" + + program=lt-'bladec' + progdir="$thisdir/.libs" + + if test ! -f "$progdir/$program" || + { file=`ls -1dt "$progdir/$program" "$progdir/../$program" 2>/dev/null | /bin/sed 1q`; \ + test "X$file" != "X$progdir/$program"; }; then + + file="$$-$program" + + if test ! -d "$progdir"; then + mkdir "$progdir" + else + rm -f "$progdir/$file" + fi + + # relink executable if necessary + if test -n "$relink_command"; then + if relink_command_output=`eval $relink_command 2>&1`; then : + else + printf %s\n "$relink_command_output" >&2 + rm -f "$progdir/$file" + exit 1 + fi + fi + + mv -f "$progdir/$file" "$progdir/$program" 2>/dev/null || + { rm -f "$progdir/$program"; + mv -f "$progdir/$file" "$progdir/$program"; } + rm -f "$progdir/$file" + fi + + if test -f "$progdir/$program"; then + if test "$libtool_execute_magic" != "%%%MAGIC variable%%%"; then + # Run the actual program with our arguments. + func_exec_program ${1+"$@"} + fi + else + # The program doesn't exist. + $ECHO "$0: error: \`$progdir/$program' does not exist" 1>&2 + $ECHO "This script is just a wrapper for $program." 1>&2 + $ECHO "See the libtool documentation for more information." 1>&2 + exit 1 + fi +fi diff --git a/libs/libblade/test/bladec.c b/libs/libblade/test/bladec.c index 09e821edc2..aadfed612e 100644 --- a/libs/libblade/test/bladec.c +++ b/libs/libblade/test/bladec.c @@ -16,6 +16,7 @@ char g_console_input[CONSOLE_INPUT_MAX]; size_t g_console_input_length = 0; size_t g_console_input_eol = 0; +void service_peer_state_callback(blade_service_t *service, blade_peer_t *peer, blade_peerstate_t state); void loop(blade_handle_t *bh); void process_console_input(blade_handle_t *bh, char *line); @@ -40,10 +41,11 @@ static const struct command_def_s command_defs[] = { { NULL, NULL } }; - int main(int argc, char **argv) { blade_handle_t *bh = NULL; + config_t config; + config_setting_t *config_blade = NULL; ks_global_set_default_logger(KS_LOG_LEVEL_DEBUG); @@ -51,8 +53,31 @@ int main(int argc, char **argv) blade_handle_create(&bh, NULL, NULL); - loop(bh); + // @todo load config file, and lookup "blade" setting to put into config_blade + config_init(&config); + if (!config_read_file(&config, "bladec.cfg")) { + ks_log(KS_LOG_ERROR, "%s:%d - %s\n", config_error_file(&config), config_error_line(&config), config_error_text(&config)); + config_destroy(&config); + return EXIT_FAILURE; + } + config_blade = config_lookup(&config, "blade"); + if (!config_blade) { + ks_log(KS_LOG_ERROR, "Missing 'blade' config group\n"); + config_destroy(&config); + return EXIT_FAILURE; + } + if (config_setting_type(config_blade) != CONFIG_TYPE_GROUP) { + ks_log(KS_LOG_ERROR, "The 'blade' config setting is not a group\n"); + return EXIT_FAILURE; + } + if (blade_handle_startup(bh, config_blade, service_peer_state_callback) != KS_STATUS_SUCCESS) { + ks_log(KS_LOG_ERROR, "Blade startup failed\n"); + return EXIT_FAILURE; + } + + loop(bh); + blade_handle_destroy(&bh); blade_shutdown(); @@ -60,6 +85,12 @@ int main(int argc, char **argv) return 0; } +void service_peer_state_callback(blade_service_t *service, blade_peer_t *peer, blade_peerstate_t state) +{ + // @todo log output and pop peer messages if state == BLADE_PEERSTATE_RECEIVING + ks_log(KS_LOG_INFO, "service peer state callback: %d\n", (int)state); +} + void buffer_console_input(void) { ssize_t bytes = 0; @@ -110,7 +141,6 @@ void loop(blade_handle_t *bh) // @todo lines must not exceed 512 bytes, treat as error and ignore buffer until next new line? ks_assert(0); } - blade_handle_pulse(bh); } } @@ -175,8 +205,6 @@ void command_store(blade_handle_t *bh, char *args) ks_assert(args); - blade_handle_datastore_startup(bh, NULL); - parse_argument(&args, &key, ' '); parse_argument(&args, &data, ' '); @@ -195,8 +223,6 @@ void command_fetch(blade_handle_t *bh, char *args) ks_assert(args); - blade_handle_datastore_startup(bh, NULL); - parse_argument(&args, &key, ' '); blade_handle_datastore_fetch(bh, blade_datastore_fetch_callback, key, strlen(key), bh); diff --git a/libs/libblade/test/bladec.cfg b/libs/libblade/test/bladec.cfg new file mode 100644 index 0000000000..a14a4e7f7a --- /dev/null +++ b/libs/libblade/test/bladec.cfg @@ -0,0 +1,50 @@ +blade: +{ + # client stuff, for peers who connect out to services + client: + { + directory: + { + # todo: hints for ways to find a directory service, at least kws client_data for now + # add DNS SRV in the future + uri = "???:127.0.0.1+2100:???"; # todo: confirm expected format, "uri:host:proto" + + websocket: + { + # SSL group is optional, disabled when absent + ssl: + { + # todo: client SSL stuffs here + }; + }; + }; + }; + + + # server stuff, for services that peers connect to + # todo: consider encapsulating in a "server" group for organizational structure + datastore: + { + database: + { + path = ":mem:"; + }; + }; + service: + { + websockets: + { + endpoints: + { + ipv4 = ( { address = "0.0.0.0", port = 2100 } ); + ipv6 = ( { address = "::", port = 2100 } ); + backlog = 128; + }; + # SSL group is optional, disabled when absent + ssl: + { + # todo: service SSL stuffs here + }; + }; + }; +}; diff --git a/libs/libks/src/include/simclist.h b/libs/libks/src/include/simclist.h index d22587df33..90cdd0cead 100755 --- a/libs/libks/src/include/simclist.h +++ b/libs/libks/src/include/simclist.h @@ -27,6 +27,7 @@ extern "C" { #endif +#include #include #include #include @@ -209,7 +210,7 @@ extern "C" { * @param l must point to a user-provided memory location * @return 0 for success. -1 for failure */ - int list_init(list_t *restrict l); + KS_DECLARE(int) list_init(list_t *restrict l); /** * completely remove the list from memory. @@ -220,7 +221,7 @@ extern "C" { * * @param l list to destroy */ - void list_destroy(list_t *restrict l); + KS_DECLARE(void) list_destroy(list_t *restrict l); /** * set the comparator function for list elements. @@ -234,7 +235,7 @@ extern "C" { * * @see element_comparator() */ - int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); + KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); /** * set a seeker function for list elements. @@ -248,7 +249,7 @@ extern "C" { * * @see element_seeker() */ - int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); + KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); /** * require to free element data when list entry is removed (default: don't free). @@ -280,7 +281,7 @@ extern "C" { * @see list_meter_double() * @see list_meter_string() */ - int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); + KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); /** * set the element hash computing function for the list elements. @@ -300,7 +301,7 @@ extern "C" { * * @see element_hash_computer() */ - int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); + KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); /** * set the element serializer function for the list elements. @@ -321,7 +322,7 @@ extern "C" { * @see list_dump_filedescriptor() * @see list_restore_filedescriptor() */ - int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); + KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); /** * set the element unserializer function for the list elements. @@ -343,7 +344,7 @@ extern "C" { * @see list_dump_filedescriptor() * @see list_restore_filedescriptor() */ - int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); + KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); /** * append data at the end of the list. @@ -355,7 +356,7 @@ extern "C" { * * @return 1 for success. < 0 for failure */ - int list_append(list_t *restrict l, const void *data); + KS_DECLARE(int) list_append(list_t *restrict l, const void *data); /** * insert data in the head of the list. @@ -367,7 +368,7 @@ extern "C" { * * @return 1 for success. < 0 for failure */ - int list_prepend(list_t *restrict l, const void *restrict data); + KS_DECLARE(int) list_prepend(list_t *restrict l, const void *restrict data); /** * extract the element in the top of the list. @@ -377,7 +378,7 @@ extern "C" { * @param l list to operate * @return reference to user datum, or NULL on errors */ - void *list_fetch(list_t *restrict l); + KS_DECLARE(void *) list_fetch(list_t *restrict l); /** * retrieve an element at a given position. @@ -386,7 +387,7 @@ extern "C" { * @param pos [0,size-1] position index of the element wanted * @return reference to user datum, or NULL on errors */ - void *list_get_at(const list_t *restrict l, unsigned int pos); + KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos); /** * return the maximum element of the list. @@ -400,7 +401,7 @@ extern "C" { * @param l list to operate * @return the reference to the element, or NULL */ - void *list_get_max(const list_t *restrict l); + KS_DECLARE(void *) list_get_max(const list_t *restrict l); /** * return the minimum element of the list. @@ -414,7 +415,7 @@ extern "C" { * @param l list to operate * @return the reference to the element, or NULL */ - void *list_get_min(const list_t *restrict l); + KS_DECLARE(void *) list_get_min(const list_t *restrict l); /** * retrieve and remove from list an element at a given position. @@ -423,7 +424,7 @@ extern "C" { * @param pos [0,size-1] position index of the element wanted * @return reference to user datum, or NULL on errors */ - void *list_extract_at(list_t *restrict l, unsigned int pos); + KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos); /** * insert an element at a given position. @@ -433,7 +434,7 @@ extern "C" { * @param pos [0,size-1] position index to insert the element at * @return positive value on success. Negative on failure */ - int list_insert_at(list_t *restrict l, const void *data, unsigned int pos); + KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos); /** * expunge the first found given element from the list. @@ -450,7 +451,7 @@ extern "C" { * @see list_attributes_comparator() * @see list_delete_at() */ - int list_delete(list_t *restrict l, const void *data); + KS_DECLARE(int) list_delete(list_t *restrict l, const void *data); /** * expunge an element at a given position from the list. @@ -459,7 +460,7 @@ extern "C" { * @param pos [0,size-1] position index of the element to be deleted * @return 0 on success. Negative value on failure */ - int list_delete_at(list_t *restrict l, unsigned int pos); + KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos); /** * expunge an array of elements from the list, given their position range. @@ -469,7 +470,7 @@ extern "C" { * @param posend [posstart,size-1] position of the last element to be deleted * @return the number of elements successfully removed on success, <0 on error */ - int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); + KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); /** * clear all the elements off of the list. @@ -482,7 +483,7 @@ extern "C" { * @param l list to operate * @return the number of elements removed on success, <0 on error */ - int list_clear(list_t *restrict l); + KS_DECLARE(int) list_clear(list_t *restrict l); /** * inspect the number of elements in the list. @@ -490,7 +491,7 @@ extern "C" { * @param l list to operate * @return number of elements currently held by the list */ - unsigned int list_size(const list_t *restrict l); + KS_DECLARE(unsigned int) list_size(const list_t *restrict l); /** * inspect whether the list is empty. @@ -500,7 +501,7 @@ extern "C" { * * @see list_size() */ - int list_empty(const list_t *restrict l); + KS_DECLARE(int) list_empty(const list_t *restrict l); /** * find the position of an element in a list. @@ -519,7 +520,7 @@ extern "C" { * @see list_attributes_comparator() * @see list_get_at() */ - int list_locate(const list_t *restrict l, const void *data); + KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data); /** * returns an element given an indicator. @@ -534,7 +535,7 @@ extern "C" { * @param indicator indicator data to pass to the seeker along with elements * @return reference to the element accepted by the seeker, or NULL if none found */ - void *list_seek(list_t *restrict l, const void *indicator); + KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator); /** * inspect whether some data is member of the list. @@ -555,7 +556,7 @@ extern "C" { * * @see list_attributes_comparator() */ - int list_contains(const list_t *restrict l, const void *data); + KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data); /** * concatenate two lists @@ -574,7 +575,7 @@ extern "C" { * @param dest reference to the destination list * @return 0 for success, -1 for errors */ - int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); + KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); /** * sort list elements. @@ -591,7 +592,7 @@ extern "C" { * * @see list_attributes_comparator() */ - int list_sort(list_t *restrict l, int versus); + KS_DECLARE(int) list_sort(list_t *restrict l, int versus); /** * start an iteration session. @@ -603,7 +604,7 @@ extern "C" { * * @see list_iterator_stop() */ - int list_iterator_start(list_t *restrict l); + KS_DECLARE(int) list_iterator_start(list_t *restrict l); /** * return the next element in the iteration session. @@ -611,7 +612,7 @@ extern "C" { * @param l list to operate * @return element datum, or NULL on errors */ - void *list_iterator_next(list_t *restrict l); + KS_DECLARE(void *) list_iterator_next(list_t *restrict l); /** * inspect whether more elements are available in the iteration session. @@ -619,7 +620,7 @@ extern "C" { * @param l list to operate * @return 0 iff no more elements are available. */ - int list_iterator_hasnext(const list_t *restrict l); + KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l); /** * end an iteration session. @@ -627,7 +628,7 @@ extern "C" { * @param l list to operate * @return 0 iff the iteration session cannot be stopped */ - int list_iterator_stop(list_t *restrict l); + KS_DECLARE(int) list_iterator_stop(list_t *restrict l); /** * return the hash of the current status of the list. @@ -637,7 +638,7 @@ extern "C" { * * @return 0 for success; <0 for failure */ - int list_hash(const list_t *restrict l, list_hash_t *restrict hash); + KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash); #ifndef SIMCLIST_NO_DUMPRESTORE /** @@ -655,7 +656,7 @@ extern "C" { * * @see list_dump_filedescriptor() */ - int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); + KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); /** * get meta informations on a list dump on file. @@ -670,7 +671,7 @@ extern "C" { * * @see list_dump_filedescriptor() */ - int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); + KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); /** * dump the list into an open, writable file descriptor. @@ -706,7 +707,7 @@ extern "C" { * @see list_attributes_copy() * @see list_attributes_serializer() */ - int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); + KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); /** * dump the list to a file name. @@ -729,7 +730,7 @@ extern "C" { * * This function stores a representation of the list */ - int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); + KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); /** * restore the list from an open, readable file descriptor to memory. @@ -749,7 +750,7 @@ extern "C" { * @param len location to store the length of the dump read (bytes), or NULL * @return 0 if successful; -1 otherwise */ - int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); + KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); /** * restore the list from a file name. @@ -767,7 +768,7 @@ extern "C" { * @param len location to store the length of the dump read (bytes), or NULL * @return 0 if successful; -1 otherwise */ - int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); + KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); #endif /* ready-made comparators, meters and hash computers */ @@ -776,201 +777,201 @@ extern "C" { * ready-made comparator for int8_t elements. * @see list_attributes_comparator() */ - int list_comparator_int8_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_int8_t (const void *a, const void *b); /** * ready-made comparator for int16_t elements. * @see list_attributes_comparator() */ - int list_comparator_int16_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_int16_t (const void *a, const void *b); /** * ready-made comparator for int32_t elements. * @see list_attributes_comparator() */ - int list_comparator_int32_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_int32_t (const void *a, const void *b); /** * ready-made comparator for int64_t elements. * @see list_attributes_comparator() */ - int list_comparator_int64_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_int64_t (const void *a, const void *b); /** * ready-made comparator for uint8_t elements. * @see list_attributes_comparator() */ - int list_comparator_uint8_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_uint8_t (const void *a, const void *b); /** * ready-made comparator for uint16_t elements. * @see list_attributes_comparator() */ - int list_comparator_uint16_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_uint16_t (const void *a, const void *b); /** * ready-made comparator for uint32_t elements. * @see list_attributes_comparator() */ - int list_comparator_uint32_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_uint32_t (const void *a, const void *b); /** * ready-made comparator for uint64_t elements. * @see list_attributes_comparator() */ - int list_comparator_uint64_t (const void *a, const void *b); + KS_DECLARE(int) list_comparator_uint64_t (const void *a, const void *b); /** * ready-made comparator for float elements. * @see list_attributes_comparator() */ - int list_comparator_float(const void *a, const void *b); + KS_DECLARE(int) list_comparator_float(const void *a, const void *b); /** * ready-made comparator for double elements. * @see list_attributes_comparator() */ - int list_comparator_double(const void *a, const void *b); + KS_DECLARE(int) list_comparator_double(const void *a, const void *b); /** * ready-made comparator for string elements. * @see list_attributes_comparator() */ - int list_comparator_string(const void *a, const void *b); + KS_DECLARE(int) list_comparator_string(const void *a, const void *b); /* metric functions */ /** * ready-made metric function for int8_t elements. * @see list_attributes_copy() */ - size_t list_meter_int8_t (const void *el); + KS_DECLARE(size_t) list_meter_int8_t (const void *el); /** * ready-made metric function for int16_t elements. * @see list_attributes_copy() */ - size_t list_meter_int16_t (const void *el); + KS_DECLARE(size_t) list_meter_int16_t (const void *el); /** * ready-made metric function for int32_t elements. * @see list_attributes_copy() */ - size_t list_meter_int32_t (const void *el); + KS_DECLARE(size_t) list_meter_int32_t (const void *el); /** * ready-made metric function for int64_t elements. * @see list_attributes_copy() */ - size_t list_meter_int64_t (const void *el); + KS_DECLARE(size_t) list_meter_int64_t (const void *el); /** * ready-made metric function for uint8_t elements. * @see list_attributes_copy() */ - size_t list_meter_uint8_t (const void *el); + KS_DECLARE(size_t) list_meter_uint8_t (const void *el); /** * ready-made metric function for uint16_t elements. * @see list_attributes_copy() */ - size_t list_meter_uint16_t (const void *el); + KS_DECLARE(size_t) list_meter_uint16_t (const void *el); /** * ready-made metric function for uint32_t elements. * @see list_attributes_copy() */ - size_t list_meter_uint32_t (const void *el); + KS_DECLARE(size_t) list_meter_uint32_t (const void *el); /** * ready-made metric function for uint64_t elements. * @see list_attributes_copy() */ - size_t list_meter_uint64_t (const void *el); + KS_DECLARE(size_t) list_meter_uint64_t (const void *el); /** * ready-made metric function for float elements. * @see list_attributes_copy() */ - size_t list_meter_float(const void *el); + KS_DECLARE(size_t) list_meter_float(const void *el); /** * ready-made metric function for double elements. * @see list_attributes_copy() */ - size_t list_meter_double(const void *el); + KS_DECLARE(size_t) list_meter_double(const void *el); /** * ready-made metric function for string elements. * @see list_attributes_copy() */ - size_t list_meter_string(const void *el); + KS_DECLARE(size_t) list_meter_string(const void *el); /* hash functions */ /** * ready-made hash function for int8_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_int8_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_int8_t(const void *el); /** * ready-made hash function for int16_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_int16_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_int16_t(const void *el); /** * ready-made hash function for int32_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_int32_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_int32_t(const void *el); /** * ready-made hash function for int64_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_int64_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_int64_t(const void *el); /** * ready-made hash function for uint8_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_uint8_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_uint8_t(const void *el); /** * ready-made hash function for uint16_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_uint16_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_uint16_t(const void *el); /** * ready-made hash function for uint32_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_uint32_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_uint32_t(const void *el); /** * ready-made hash function for uint64_t elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_uint64_t(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_uint64_t(const void *el); /** * ready-made hash function for float elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_float(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_float(const void *el); /** * ready-made hash function for double elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_double(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_double(const void *el); /** * ready-made hash function for string elements. * @see list_attributes_hash_computer() */ - list_hash_t list_hashcomputer_string(const void *el); + KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el); #ifdef __cplusplus } diff --git a/libs/libks/src/ks_socket.c b/libs/libks/src/ks_socket.c index 1696437924..5c951ea956 100644 --- a/libs/libks/src/ks_socket.c +++ b/libs/libks/src/ks_socket.c @@ -121,6 +121,15 @@ KS_DECLARE(ks_status_t) ks_socket_option(ks_socket_t socket, int option_name, ks #endif } break; + case IPV6_V6ONLY: +#ifdef WIN32 +#warning make sure windows works like linux for IPV6 to IPV4 automapping stuff + result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, (char *)&opt, sizeof(opt)); +#else + result = setsockopt(socket, SOL_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); +#endif + if (!result) status = KS_STATUS_SUCCESS; + break; default: break; } diff --git a/libs/libks/src/simclist.c b/libs/libks/src/simclist.c index e132022260..0f9885af56 100755 --- a/libs/libks/src/simclist.c +++ b/libs/libks/src/simclist.c @@ -268,7 +268,7 @@ static inline long get_random(void) /* list initialization */ -int list_init(list_t *restrict l) +KS_DECLARE(int) list_init(list_t *restrict l) { if (l == NULL) return -1; @@ -306,7 +306,7 @@ int list_init(list_t *restrict l) return 0; } -void list_destroy(list_t *restrict l) +KS_DECLARE(void) list_destroy(list_t *restrict l) { unsigned int i; @@ -340,7 +340,7 @@ int list_attributes_setdefaults(list_t *restrict l) } /* setting list properties */ -int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) +KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) { if (l == NULL) return -1; @@ -352,7 +352,7 @@ int list_attributes_comparator(list_t *restrict l, element_comparator comparator return 0; } -int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) +KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) { if (l == NULL) return -1; @@ -363,7 +363,7 @@ int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) return 0; } -int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) +KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) { if (l == NULL || (metric_fun == NULL && copy_data != 0)) return -1; @@ -376,7 +376,7 @@ int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_ return 0; } -int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) +KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) { if (l == NULL) return -1; @@ -386,7 +386,7 @@ int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash return 0; } -int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) +KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) { if (l == NULL) return -1; @@ -396,7 +396,7 @@ int list_attributes_serializer(list_t *restrict l, element_serializer serializer return 0; } -int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) +KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) { if (l == NULL) return -1; @@ -406,22 +406,22 @@ int list_attributes_unserializer(list_t *restrict l, element_unserializer unseri return 0; } -int list_append(list_t *restrict l, const void *data) +KS_DECLARE(int) list_append(list_t *restrict l, const void *data) { return list_insert_at(l, data, l->numels); } -int list_prepend(list_t *restrict l, const void *data) +KS_DECLARE(int) list_prepend(list_t *restrict l, const void *data) { return list_insert_at(l, data, 0); } -void *list_fetch(list_t *restrict l) +KS_DECLARE(void *) list_fetch(list_t *restrict l) { return list_extract_at(l, 0); } -void *list_get_at(const list_t *restrict l, unsigned int pos) +KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos) { struct list_entry_s *tmp; @@ -430,12 +430,12 @@ void *list_get_at(const list_t *restrict l, unsigned int pos) return (tmp != NULL ? tmp->data : NULL); } -void *list_get_max(const list_t *restrict l) +KS_DECLARE(void *) list_get_max(const list_t *restrict l) { return list_get_minmax(l, +1); } -void *list_get_min(const list_t *restrict l) +KS_DECLARE(void *) list_get_min(const list_t *restrict l) { return list_get_minmax(l, -1); } @@ -488,7 +488,7 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po return ptr; } -void *list_extract_at(list_t *restrict l, unsigned int pos) +KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos) { struct list_entry_s *tmp; void *data; @@ -508,7 +508,7 @@ void *list_extract_at(list_t *restrict l, unsigned int pos) return data; } -int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) +KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos) { struct list_entry_s *lent, *succ, *prec; @@ -561,7 +561,7 @@ int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) return 1; } -int list_delete(list_t *restrict l, const void *data) +KS_DECLARE(int) list_delete(list_t *restrict l, const void *data) { int pos, r; @@ -578,7 +578,7 @@ int list_delete(list_t *restrict l, const void *data) return 0; } -int list_delete_at(list_t *restrict l, unsigned int pos) +KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos) { struct list_entry_s *delendo; @@ -598,7 +598,7 @@ int list_delete_at(list_t *restrict l, unsigned int pos) return 0; } -int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) +KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) { struct list_entry_s *lastvalid, *tmp, *tmp2; unsigned int numdel, midposafter, i; @@ -665,7 +665,7 @@ int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int po return numdel; } -int list_clear(list_t *restrict l) +KS_DECLARE(int) list_clear(list_t *restrict l) { struct list_entry_s *s; unsigned int numels; @@ -715,17 +715,17 @@ int list_clear(list_t *restrict l) return numels; } -unsigned int list_size(const list_t *restrict l) +KS_DECLARE(unsigned int) list_size(const list_t *restrict l) { return l->numels; } -int list_empty(const list_t *restrict l) +KS_DECLARE(int) list_empty(const list_t *restrict l) { return (l->numels == 0); } -int list_locate(const list_t *restrict l, const void *data) +KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data) { struct list_entry_s *el; int pos = 0; @@ -749,7 +749,7 @@ int list_locate(const list_t *restrict l, const void *data) return pos; } -void *list_seek(list_t *restrict l, const void *indicator) +KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator) { const struct list_entry_s *iter; @@ -764,12 +764,12 @@ void *list_seek(list_t *restrict l, const void *indicator) return NULL; } -int list_contains(const list_t *restrict l, const void *data) +KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data) { return (list_locate(l, data) >= 0); } -int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) +KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { struct list_entry_s *el, *srcel; unsigned int cnt; @@ -825,7 +825,7 @@ int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) return 0; } -int list_sort(list_t *restrict l, int versus) +KS_DECLARE(int) list_sort(list_t *restrict l, int versus) { if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */ return -1; @@ -1005,7 +1005,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir #endif } -int list_iterator_start(list_t *restrict l) +KS_DECLARE(int) list_iterator_start(list_t *restrict l) { if (l->iter_active) return 0; @@ -1015,7 +1015,7 @@ int list_iterator_start(list_t *restrict l) return 1; } -void *list_iterator_next(list_t *restrict l) +KS_DECLARE(void *) list_iterator_next(list_t *restrict l) { void *toret; @@ -1029,14 +1029,14 @@ void *list_iterator_next(list_t *restrict l) return toret; } -int list_iterator_hasnext(const list_t *restrict l) +KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l) { if (!l->iter_active) return 0; return (l->iter_pos < l->numels); } -int list_iterator_stop(list_t *restrict l) +KS_DECLARE(int) list_iterator_stop(list_t *restrict l) { if (!l->iter_active) return 0; @@ -1045,7 +1045,7 @@ int list_iterator_stop(list_t *restrict l) return 1; } -int list_hash(const list_t *restrict l, list_hash_t *restrict hash) +KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash) { struct list_entry_s *x; list_hash_t tmphash; @@ -1083,7 +1083,7 @@ int list_hash(const list_t *restrict l, list_hash_t *restrict hash) } #ifndef SIMCLIST_NO_DUMPRESTORE -int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) +KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) { int32_t terminator_head, terminator_tail; uint32_t elemlen; @@ -1148,7 +1148,7 @@ int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) return 0; } -int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) +KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) { int fd, ret; @@ -1162,7 +1162,7 @@ int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *rest return ret; } -int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) +KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) { struct list_entry_s *x; void *ser_buf; @@ -1311,7 +1311,7 @@ int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict return 0; } -int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) +KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) { struct list_dump_header_s header; unsigned long cnt; @@ -1436,7 +1436,7 @@ int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len return 0; } -int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) +KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) { int fd, oflag, mode; @@ -1457,7 +1457,7 @@ int list_dump_file(const list_t *restrict l, const char *restrict filename, size return 0; } -int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) +KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) { int fd; @@ -1507,38 +1507,38 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned } /* ready-made comparators and meters */ -#define SIMCLIST_NUMBER_COMPARATOR(type) int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } +#define SIMCLIST_NUMBER_COMPARATOR(type) KS_DECLARE(int) list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } SIMCLIST_NUMBER_COMPARATOR(int8_t) SIMCLIST_NUMBER_COMPARATOR(int16_t) SIMCLIST_NUMBER_COMPARATOR(int32_t) SIMCLIST_NUMBER_COMPARATOR(int64_t) SIMCLIST_NUMBER_COMPARATOR(uint8_t) SIMCLIST_NUMBER_COMPARATOR(uint16_t) SIMCLIST_NUMBER_COMPARATOR(uint32_t) SIMCLIST_NUMBER_COMPARATOR(uint64_t) SIMCLIST_NUMBER_COMPARATOR(float) SIMCLIST_NUMBER_COMPARATOR(double) - int list_comparator_string(const void *a, const void *b) +KS_DECLARE(int) list_comparator_string(const void *a, const void *b) { return strcmp((const char *) b, (const char *) a); } /* ready-made metric functions */ -#define SIMCLIST_METER(type) size_t list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); } +#define SIMCLIST_METER(type) KS_DECLARE(size_t) list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); } SIMCLIST_METER(int8_t) SIMCLIST_METER(int16_t) SIMCLIST_METER(int32_t) SIMCLIST_METER(int64_t) SIMCLIST_METER(uint8_t) SIMCLIST_METER(uint16_t) SIMCLIST_METER(uint32_t) SIMCLIST_METER(uint64_t) SIMCLIST_METER(float) SIMCLIST_METER(double) - size_t list_meter_string(const void *el) +KS_DECLARE(size_t) list_meter_string(const void *el) { return strlen((const char *) el) + 1; } /* ready-made hashing functions */ -#define SIMCLIST_HASHCOMPUTER(type) list_hash_t list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); } +#define SIMCLIST_HASHCOMPUTER(type) KS_DECLARE(list_hash_t) list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); } SIMCLIST_HASHCOMPUTER(int8_t) SIMCLIST_HASHCOMPUTER(int16_t) SIMCLIST_HASHCOMPUTER(int32_t) SIMCLIST_HASHCOMPUTER(int64_t) SIMCLIST_HASHCOMPUTER(uint8_t) SIMCLIST_HASHCOMPUTER(uint16_t) SIMCLIST_HASHCOMPUTER(uint32_t) SIMCLIST_HASHCOMPUTER(uint64_t) SIMCLIST_HASHCOMPUTER(float) SIMCLIST_HASHCOMPUTER(double) - list_hash_t list_hashcomputer_string(const void *el) +KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el) { size_t l; list_hash_t hash = 123;