Hello community, here is the log from the commit of package librelp for openSUSE:Factory checked in at 2013-07-16 16:42:49 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/librelp (Old) and /work/SRC/openSUSE:Factory/.librelp.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "librelp" Changes: -------- --- /work/SRC/openSUSE:Factory/librelp/librelp.changes 2013-07-12 20:47:58.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.librelp.new/librelp.changes 2013-07-16 16:42:51.000000000 +0200 @@ -1,0 +2,7 @@ +Tue Jul 16 10:52:06 UTC 2013 - [email protected] + +- update to 1.2.0: + - support for epoll() added + - API extension: relpEngineSetOnGenericErr + +------------------------------------------------------------------- Old: ---- librelp-1.1.5.tar.gz New: ---- librelp-1.2.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ librelp.spec ++++++ --- /var/tmp/diff_new_pack.bIUJYM/_old 2013-07-16 16:42:52.000000000 +0200 +++ /var/tmp/diff_new_pack.bIUJYM/_new 2013-07-16 16:42:52.000000000 +0200 @@ -18,7 +18,7 @@ Name: librelp %define library_name librelp0 -Version: 1.1.5 +Version: 1.2.0 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build Url: http://www.librelp.com/ ++++++ librelp-1.1.5.tar.gz -> librelp-1.2.0.tar.gz ++++++ ++++ 4689 lines of diff (skipped) ++++ retrying with extended exclude list diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/ChangeLog new/librelp-1.2.0/ChangeLog --- old/librelp-1.1.5/ChangeLog 2013-07-05 09:55:19.000000000 +0200 +++ new/librelp-1.2.0/ChangeLog 2013-07-14 16:53:38.000000000 +0200 @@ -1,4 +1,9 @@ ---------------------------------------------------------------------- +Version 1.2.0 - 2013-07-15 +- support for epoll() added + platforms that do not support it fall back to select() +- API extension: relpEngineSetOnGenericErr +---------------------------------------------------------------------- Version 1.1.5 - 2013-07-05 - bugfix: memory leak on connection close around 60 bytes of memory were lost on each connection close at the diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/INSTALL new/librelp-1.2.0/INSTALL --- old/librelp-1.1.5/INSTALL 2013-07-05 07:33:29.000000000 +0200 +++ new/librelp-1.2.0/INSTALL 2013-06-03 13:07:36.000000000 +0200 @@ -1,7 +1,7 @@ Installation Instructions ************************* -Copyright (C) 1994-1996, 1999-2002, 2004-2012 Free Software Foundation, +Copyright (C) 1994-1996, 1999-2002, 2004-2011 Free Software Foundation, Inc. Copying and distribution of this file, with or without modification, @@ -309,10 +309,9 @@ overridden in the site shell script). Unfortunately, this technique does not work for `CONFIG_SHELL' due to -an Autoconf limitation. Until the limitation is lifted, you can use -this workaround: +an Autoconf bug. Until the bug is fixed you can use this workaround: - CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash `configure' Invocation ====================== @@ -368,3 +367,4 @@ `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/compile new/librelp-1.2.0/compile --- old/librelp-1.1.5/compile 2013-07-05 07:33:28.000000000 +0200 +++ new/librelp-1.2.0/compile 2013-06-03 13:07:35.000000000 +0200 @@ -1,9 +1,10 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-03-05.13; # UTC +scriptversion=2012-01-04.17; # UTC -# Copyright (C) 1999-2012 Free Software Foundation, Inc. +# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2009, 2010, 2012 Free +# Software Foundation, Inc. # Written by Tom Tromey <[email protected]>. # # This program is free software; you can redistribute it and/or modify @@ -78,48 +79,6 @@ esac } -# func_cl_dashL linkdir -# Make cl look for libraries in LINKDIR -func_cl_dashL () -{ - func_file_conv "$1" - if test -z "$lib_path"; then - lib_path=$file - else - lib_path="$lib_path;$file" - fi - linker_opts="$linker_opts -LIBPATH:$file" -} - -# func_cl_dashl library -# Do a library search-path lookup for cl -func_cl_dashl () -{ - lib=$1 - found=no - save_IFS=$IFS - IFS=';' - for dir in $lib_path $LIB - do - IFS=$save_IFS - if $shared && test -f "$dir/$lib.dll.lib"; then - found=yes - lib=$dir/$lib.dll.lib - break - fi - if test -f "$dir/$lib.lib"; then - found=yes - lib=$dir/$lib.lib - break - fi - done - IFS=$save_IFS - - if test "$found" != yes; then - lib=$lib.lib - fi -} - # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () @@ -150,34 +109,43 @@ ;; esac ;; - -I) - eat=1 - func_file_conv "$2" mingw - set x "$@" -I"$file" - shift - ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; - -l) - eat=1 - func_cl_dashl "$2" - set x "$@" "$lib" - shift - ;; -l*) - func_cl_dashl "${1#-l}" - set x "$@" "$lib" + lib=${1#-l} + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + set x "$@" "$dir/$lib.dll.lib" + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + set x "$@" "$dir/$lib.lib" + break + fi + done + IFS=$save_IFS + + test "$found" != yes && set x "$@" "$lib.lib" shift ;; - -L) - eat=1 - func_cl_dashL "$2" - ;; -L*) - func_cl_dashL "${1#-L}" + func_file_conv "${1#-L}" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" ;; -static) shared=false diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/config.h.in new/librelp-1.2.0/config.h.in --- old/librelp-1.1.5/config.h.in 2013-07-05 10:31:28.000000000 +0200 +++ new/librelp-1.2.0/config.h.in 2013-07-08 18:26:13.000000000 +0200 @@ -3,9 +3,19 @@ /* Defined if debug mode is enabled (it's easier to check in the code). */ #undef DEBUG +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR_R + /* Define to 1 if you have the <dlfcn.h> header file. */ #undef HAVE_DLFCN_H +/* Define to 1 if you have the `epoll_create' function. */ +#undef HAVE_EPOLL_CREATE + +/* Define to 1 if you have the `epoll_create1' function. */ +#undef HAVE_EPOLL_CREATE1 + /* Define to 1 if you have the <inttypes.h> header file. */ #undef HAVE_INTTYPES_H @@ -22,6 +32,9 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R + /* Define to 1 if you have the <strings.h> header file. */ #undef HAVE_STRINGS_H @@ -31,6 +44,9 @@ /* Define to 1 if `sa_len' is a member of `struct sockaddr'. */ #undef HAVE_STRUCT_SOCKADDR_SA_LEN +/* Define to 1 if you have the <sys/epoll.h> header file. */ +#undef HAVE_SYS_EPOLL_H + /* Define to 1 if you have the <sys/select.h> header file. */ #undef HAVE_SYS_SELECT_H @@ -92,6 +108,9 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* Define to 1 if strerror_r returns char *. */ +#undef STRERROR_R_CHAR_P + /* Version number of package */ #undef VERSION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/configure.ac new/librelp-1.2.0/configure.ac --- old/librelp-1.1.5/configure.ac 2013-07-05 09:55:36.000000000 +0200 +++ new/librelp-1.2.0/configure.ac 2013-07-08 12:03:48.000000000 +0200 @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.61) -AC_INIT([librelp], [1.1.5], [[email protected]]) +AC_INIT([librelp], [1.2.0], [[email protected]]) AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -30,7 +30,7 @@ # Checks for header files. AC_HEADER_STDC -#AC_CHECK_HEADERS([]) +AC_CHECK_HEADERS([sys/epoll.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -43,8 +43,9 @@ # Checks for library functions. AC_FUNC_MALLOC AC_FUNC_SELECT_ARGTYPES +AC_FUNC_STRERROR_R AC_TYPE_SIGNAL -#AC_CHECK_FUNCS([]) +AC_CHECK_FUNCS([strerror_r epoll_create epoll_create1]) PKG_CHECK_MODULES(GNUTLS, gnutls >= 1.4.0) # debug mode settings diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/missing new/librelp-1.2.0/missing --- old/librelp-1.1.5/missing 2013-07-05 07:33:28.000000000 +0200 +++ new/librelp-1.2.0/missing 2013-06-03 13:07:35.000000000 +0200 @@ -1,9 +1,10 @@ #! /bin/sh # Common stub for a few missing GNU programs while installing. -scriptversion=2012-01-06.18; # UTC +scriptversion=2012-01-06.13; # UTC -# Copyright (C) 1996-2012 Free Software Foundation, Inc. +# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, +# 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. # Originally by Fran,cois Pinard <[email protected]>, 1996. # This program is free software; you can redistribute it and/or modify @@ -25,7 +26,7 @@ # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi @@ -33,7 +34,7 @@ sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' -# In the cases where this matters, 'missing' is being run in the +# In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac @@ -64,7 +65,7 @@ echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... -Handle 'PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: @@ -73,20 +74,20 @@ --run try to run the given command, and emulate it if it fails Supported PROGRAM values: - aclocal touch file 'aclocal.m4' - autoconf touch file 'configure' - autoheader touch file 'config.h.in' + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one - automake touch all 'Makefile.in' files - bison create 'y.tab.[ch]', if possible, from existing .[ch] - flex create 'lex.yy.c', if possible, from existing .c + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file - lex create 'lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file - yacc create 'y.tab.[ch]', if possible, from existing .[ch] + yacc create \`y.tab.[ch]', if possible, from existing .[ch] -Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and -'g' are ignored when checking the name. +Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and +\`g' are ignored when checking the name. Send bug reports to <[email protected]>." exit $? @@ -98,8 +99,8 @@ ;; -*) - echo 1>&2 "$0: Unknown '$1' option" - echo 1>&2 "Try '$0 --help' for more information" + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; @@ -126,7 +127,7 @@ exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone - # running '$TOOL --version' or '$TOOL --help' to check whether + # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi @@ -138,27 +139,27 @@ case $program in aclocal*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'acinclude.m4' or '${configure_ac}'. You might want - to install the Automake and Perl packages. Grab them from +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified '${configure_ac}'. You might want to install the - Autoconf and GNU m4 packages. Grab them from any GNU +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'acconfig.h' or '${configure_ac}'. You might want - to install the Autoconf and GNU m4 packages. Grab them +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" @@ -175,9 +176,9 @@ automake*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified 'Makefile.am', 'acinclude.m4' or '${configure_ac}'. - You might want to install the Automake and Perl packages. +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | @@ -186,10 +187,10 @@ autom4te*) echo 1>&2 "\ -WARNING: '$1' is needed, but is $msg. +WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. - You can get '$1' as part of Autoconf from any GNU + You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` @@ -209,10 +210,10 @@ bison*|yacc*) echo 1>&2 "\ -WARNING: '$1' $msg. You should only need it if - you modified a '.y' file. You may need the Bison package +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get - Bison from any GNU archive site." + \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG=\${$#} @@ -239,10 +240,10 @@ lex*|flex*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified a '.l' file. You may need the Flex package +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get - Flex from any GNU archive site." + \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG=\${$#} @@ -262,10 +263,10 @@ help2man*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if +WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the - Help2man package in order for those modifications to take - effect. You can get Help2man from any GNU archive site." + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` @@ -280,12 +281,12 @@ makeinfo*) echo 1>&2 "\ -WARNING: '$1' is $msg. You should only need it if - you modified a '.texi' or '.texinfo' file, or any other file +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious - call might also be the consequence of using a buggy 'make' (AIX, - DU, IRIX). You might want to install the Texinfo package or - the GNU make package. Grab either from any GNU archive site." + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` @@ -309,12 +310,12 @@ *) echo 1>&2 "\ -WARNING: '$1' is needed, and is $msg. +WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the - proper tools for further handling them. Check the 'README' file, + proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case - some other package would contain this missing '$1' program." + some other package would contain this missing \`$1' program." exit 1 ;; esac diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/src/librelp.h new/librelp-1.2.0/src/librelp.h --- old/librelp-1.1.5/src/librelp.h 2013-07-05 09:54:46.000000000 +0200 +++ new/librelp-1.2.0/src/librelp.h 2013-07-08 12:03:48.000000000 +0200 @@ -149,6 +149,8 @@ #define RELP_RET_ERR_TLS_HANDS RELPERR_BASE + 39 /**< TLS handshake failed */ #define RELP_RET_ERR_TLS RELPERR_BASE + 40 /**< generic TLS error */ #define RELP_RET_ERR_INVAL RELPERR_BASE + 41 /**< some parameter is invalid (like EINVAL) */ +#define RELP_RET_ERR_EPOLL_CTL RELPERR_BASE + 42 /**< epoll_ctl() failed */ +#define RELP_RET_ERR_INTERNAL RELPERR_BASE + 43 /**< internal error in librelp (bug) */ /* some macros to work with librelp error codes */ #define CHKRet(code) if((iRet = code) != RELP_RET_OK) goto finalize_it @@ -180,6 +182,8 @@ void (*pCB)(void*pUsr, char *authinfo, char*errmsg, relpRetVal errcode) ); relpRetVal relpEngineSetOnErr(relpEngine_t *pThis, void (*pCB)(void*pUsr, char *objinfo, char*errmsg, relpRetVal errcode) ); +relpRetVal relpEngineSetOnGenericErr(relpEngine_t *pThis, + void (*pCB)(char *objinfo, char*errmsg, relpRetVal errcode) ); /* exposed server property set functions */ relpRetVal relpSrvSetLstnPort(relpSrv_t *pThis, unsigned char *pLstnPort); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/src/relp.c new/librelp-1.2.0/src/relp.c --- old/librelp-1.1.5/src/relp.c 2013-07-05 09:54:46.000000000 +0200 +++ new/librelp-1.2.0/src/relp.c 2013-07-08 18:28:30.000000000 +0200 @@ -31,10 +31,13 @@ * development. */ #include "config.h" +#include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #include <sys/select.h> #include <string.h> #include <errno.h> +#include <unistd.h> #include <assert.h> #include "relp.h" #include "relpsrv.h" @@ -48,6 +51,112 @@ /* ------------------------------ some internal functions ------------------------------ */ +void __attribute__((format(printf, 4, 5))) +relpEngineCallOnGenericErr(relpEngine_t *pThis, char *eobj, relpRetVal ecode, char *fmt, ...) +{ + va_list ap; + char emsg[1024]; + + va_start(ap, fmt); + vsnprintf(emsg, sizeof(emsg), fmt, ap); + emsg[sizeof(emsg)/sizeof(char) - 1] = '\0'; /* just to be on the safe side... */ + va_end(ap); + + pThis->dbgprint("librelp: generic error: ecode %d, eobj %s," + "emsg '%s'\n", ecode, eobj, emsg); + if(pThis->onGenericErr != NULL) { + pThis->onGenericErr(eobj, emsg, ecode); + } +} + +static char * +relpEngine_strerror_r(int errnum, char *buf, size_t buflen) { +#ifndef HAVE_STRERROR_R + char *p; + p = strerror(errnum); + strncpy(buf, emsg, buflen); + buf[buflen-1] = '\0'; +#else +# ifdef STRERROR_R_CHAR_P + char *p; + p = strerror_r(errnum, buf, buflen); + if(p != buf) { + strncpy(buf, p, buflen); + buf[buflen - 1] = '\0'; + } +# else + strerror_r(errnum, buf, buflen); +# endif +#endif + return buf; +} + +#if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) +static relpRetVal +addToEpollSet(relpEngine_t *pThis, epolld_type_t typ, void *ptr, int sock, epolld_t **pepd) +{ + epolld_t *epd = NULL; + ENTER_RELPFUNC; + + CHKmalloc(epd = calloc(sizeof(epolld_t), 1)); + epd->typ = typ; + epd->ptr = ptr; + epd->sock = sock; + epd->ev.events = EPOLLIN; + epd->ev.data.ptr = (void*) epd; + + pThis->dbgprint("librelp: add socket %d to epoll set (ptr %p)\n", sock, ptr); + if(epoll_ctl(pThis->efd, EPOLL_CTL_ADD, sock, &epd->ev) != 0) { + char errStr[1024]; + int eno = errno; + relpEngineCallOnGenericErr(pThis, "librelp", RELP_RET_ERR_EPOLL_CTL, + "os error (%d) during EPOLL_CTL_ADD: %s", + eno, relpEngine_strerror_r(eno, errStr, sizeof(errStr))); + ABORT_FINALIZE(RELP_RET_ERR_EPOLL_CTL); + } + *pepd = epd; + +finalize_it: + if(iRet != RELP_RET_OK) { + free(epd); + } + LEAVE_RELPFUNC; +} + +/* we do not return error states, as we are unable to handle them intelligently + * in any case... + */ +static void +delFromEpollSet(relpEngine_t *pThis, epolld_t *epd) +{ + int r; + pThis->dbgprint("librelp: delete sock %d from epoll set\n", epd->sock); + if((r = epoll_ctl(pThis->efd, EPOLL_CTL_DEL, epd->sock, &epd->ev)) != 0) { + char errStr[1024]; + int eno = errno; + relpEngineCallOnGenericErr(pThis, "librelp", RELP_RET_ERR_EPOLL_CTL, + "os error (%d) during EPOLL_CTL_DEL: %s", + eno, relpEngine_strerror_r(eno, errStr, sizeof(errStr))); + } + free(epd); +} + +static relpRetVal +addSessToEpoll(relpEngine_t *pThis, relpEngSessLst_t *pSessLstEntry) +{ + addToEpollSet(pThis, epolld_sess, pSessLstEntry, + relpSessGetSock(pSessLstEntry->pSess), &pSessLstEntry->epevt); + pSessLstEntry->epollState = epoll_rdonly; + return RELP_RET_OK; +} + +static void +delSessFromEpoll(relpEngine_t *pThis, relpEngSessLst_t *pSessEtry) +{ + delFromEpollSet(pThis, pSessEtry->epevt); +} +#endif + /* add an entry to our server list. The server object is handed over and must * no longer be accessed by the caller. * rgerhards, 2008-03-17 @@ -98,6 +207,9 @@ DLL_Add(pSessLstEntry, pThis->pSessLstRoot, pThis->pSessLstLast); ++pThis->lenSessLst; pthread_mutex_unlock(&pThis->mutSessLst); +# if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + addSessToEpoll(pThis, pSessLstEntry); +# endif finalize_it: LEAVE_RELPFUNC; @@ -114,6 +226,9 @@ RELPOBJ_assert(pThis, Engine); assert(pSessLstEntry != NULL); +# if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + delSessFromEpoll(pThis, pSessLstEntry); +# endif pthread_mutex_lock(&pThis->mutSessLst); DLL_Del(pSessLstEntry, pThis->pSessLstRoot, pThis->pSessLstLast); --pThis->lenSessLst; @@ -328,6 +443,26 @@ LEAVE_RELPFUNC; } +/** + * Set an event handler that shall receive information when some GENERIC + * error occured for which no special handler exists. A generic error is + * one that cannot be assigned to a specific listener or session. + * Callback parameters: + * + * objinfo - some information identifying the object in error; depends + * on the actual error case. + * errmsg - error message as far as librelp is concerned + * errcode - contains librelp error status + */ +relpRetVal +relpEngineSetOnGenericErr(relpEngine_t *pThis, void (*pCB)(char *objinfo, char*errmsg, relpRetVal errcode) ) +{ + ENTER_RELPFUNC; + RELPOBJ_assert(pThis, Engine); + pThis->onGenericErr = pCB; + LEAVE_RELPFUNC; +} + /* Deprecated, use relpEngineListnerConstruct() family of functions. * See there for further information. */ @@ -443,28 +578,208 @@ relpEngineDelSess(pThis, pSessEtry); } } -/* The "Run" method starts the relp engine. Most importantly, this means the engine begins - * to read and write data to its peers. This method must be called on its own thread as it - * will not return until the engine is finished. Note that the engine itself may (or may - * not ;)) spawn additional threads. This is an implementation detail not to be cared of by - * caller. - * Note that the engine MUST be running even if the caller intends to just SEND messages. - * This is necessary because relp is a full-duplex protcol where acks and commands (e.g. - * "abort" may be received at any time. - * - * This function is implemented as a select() server. I know that epoll() wold probably - * be much better, but I implement the first version as select() because of portability. - * Once everything has matured, we may begin to provide performance-optimized versions for - * the several flavours of enhanced OS APIs. - * rgerhards, 2008-03-17 - */ -relpRetVal -relpEngineRun(relpEngine_t *pThis) + +static void +handleConnectionRequest(relpEngine_t *pThis, relpSrv_t *pSrv, int sock) +{ + relpRetVal localRet; + relpSess_t *pNewSess; + + pThis->dbgprint("new connect on RELP socket #%d\n", sock); + localRet = relpSessAcceptAndConstruct(&pNewSess, pSrv, sock); + if(localRet == RELP_RET_OK) { + relpEngineAddToSess(pThis, pNewSess); + } +} + + +#if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + +static relpRetVal +epoll_set_events(relpEngine_t *pThis, relpEngSessLst_t *pSessEtry, int sock, uint32_t events) +{ + ENTER_RELPFUNC; + /* TODO: remove the status dbgprint's once we have some practice drill 2013-07-05 */ + pThis->dbgprint("librelp: epoll_set_events sock %d, target bits %2.2x, current %2.2x\n", sock, events, pSessEtry->epevt->ev.events); + if(pSessEtry->epevt->ev.events != events) { + pSessEtry->epevt->ev.events = events; + pThis->dbgprint("librelp: epoll_set_events sock %d, setting new bits\n", sock); + if(epoll_ctl(pThis->efd, EPOLL_CTL_MOD, sock, &pSessEtry->epevt->ev) != 0) { + char errStr[1024]; + int eno = errno; + relpEngineCallOnGenericErr(pThis, "librelp", RELP_RET_ERR_EPOLL_CTL, + "os error (%d) during EPOLL_CTL_MOD: %s", + eno, relpEngine_strerror_r(eno, errStr, sizeof(errStr))); + ABORT_FINALIZE(RELP_RET_ERR_EPOLL_CTL); + } + } +finalize_it: + LEAVE_RELPFUNC; +} + +static inline relpRetVal +engineEventLoopInit(relpEngine_t __attribute__((unused)) *pThis) +{ +# define NUM_EPOLL_EVENTS 10 + relpEngSrvLst_t *pSrvEtry; + int i; + int nLstn; + int sock; + ENTER_RELPFUNC; +#if defined(EPOLL_CLOEXEC) && defined(HAVE_EPOLL_CREATE1) + pThis->efd = epoll_create1(EPOLL_CLOEXEC); + if(pThis->efd < 0 && errno == ENOSYS) +#endif + { + pThis->efd = epoll_create(NUM_EPOLL_EVENTS); + } + + if(pThis->efd < 0) { + pThis->dbgprint("epoll_create1() could not create fd\n"); + ABORT_FINALIZE(RELP_RET_IO_ERR); + } + + /* Add the listen sockets to the epoll set. These + * never change, so we can do it just once in init. + */ + for(pSrvEtry = pThis->pSrvLstRoot ; pSrvEtry != NULL ; pSrvEtry = pSrvEtry->pNext) { + nLstn = relpSrvGetNumLstnSocks(pSrvEtry->pSrv); + CHKmalloc(pSrvEtry->epevts = malloc(sizeof(epolld_t) * nLstn)); + for(i = 0 ; i < nLstn ; ++i) { + sock = relpSrvGetLstnSock(pSrvEtry->pSrv, i+1); + addToEpollSet(pThis, epolld_lstn, pSrvEtry->pSrv, sock, &(pSrvEtry->epevts[i])); + } + } +finalize_it: + LEAVE_RELPFUNC; +} +static inline relpRetVal +engineEventLoopExit(relpEngine_t __attribute__((unused)) *pThis) +{ + relpEngSrvLst_t *pSrvEtry; + int i; + int nLstn; + ENTER_RELPFUNC; + for(pSrvEtry = pThis->pSrvLstRoot ; pSrvEtry != NULL ; pSrvEtry = pSrvEtry->pNext) { + nLstn = relpSrvGetNumLstnSocks(pSrvEtry->pSrv); + for(i = 0 ; i < nLstn ; ++i) { + delFromEpollSet(pThis, pSrvEtry->epevts[i]); + } + free(pSrvEtry->epevts); + } + if(pThis->efd != -1) { + close(pThis->efd); + pThis->efd = -1; + } + LEAVE_RELPFUNC; +} + +static relpRetVal +handleSessIO(relpEngine_t *pThis, epolld_t *epd) +{ + relpEngSessLst_t *pSessEtry; + relpTcp_t *pTcp; + relpRetVal localRet; + + pSessEtry = (relpEngSessLst_t*) epd->ptr; + if(relpSessTcpRequiresRtry(pSessEtry->pSess)) { + pTcp = pSessEtry->pSess->pTcp; + if(relpTcpRtryOp(pTcp) == relpTCP_RETRY_send) { + doSend(pThis, pSessEtry, epd->sock); + } else if(relpTcpRtryOp(pTcp) == relpTCP_RETRY_recv) { + doRecv(pThis, pSessEtry, epd->sock); + } else { + localRet = relpTcpRtryHandshake(pTcp); + if(localRet != RELP_RET_OK) { + pThis->dbgprint("relp session %d handshake iRet %d, tearing it down\n", + epd->sock, localRet); + relpEngineDelSess(pThis, pSessEtry); + } + } + } else { + if(doRecv(pThis, pSessEtry, epd->sock) == RELP_RET_OK) { + if(epd->ev.events & EPOLLOUT) { + doSend(pThis, pSessEtry, epd->sock); + } + } + } + return RELP_RET_OK; +} + +static relpRetVal +engineEventLoopRun(relpEngine_t *pThis) +{ + relpEngSessLst_t *pSessEtry; + int i; + int sock; + struct epoll_event events[128]; + epolld_t *epd; + int nEvents; + + ENTER_RELPFUNC; + RELPOBJ_assert(pThis, Engine); + + pThis->bStop = 0; + while(!relpEngineShouldStop(pThis)) { + /* very naive implementation, O(n) - can change this once things work... + * But even the naive implementation is better than select, e.g. has no + * limit on the number of sockets. + */ + for(pSessEtry = pThis->pSessLstRoot ; pSessEtry != NULL ; pSessEtry = pSessEtry->pNext) { + sock = relpSessGetSock(pSessEtry->pSess); + if(relpSessTcpRequiresRtry(pSessEtry->pSess)) { + pThis->dbgprint("librelp: retry op requested for sock %d\n", sock); + if(relpTcpGetRtryDirection(pSessEtry->pSess->pTcp) == 0) { + epoll_set_events(pThis, pSessEtry, sock, EPOLLIN); + } else { + epoll_set_events(pThis, pSessEtry, sock, EPOLLOUT); + } + } else { + /* now check if a send request is outstanding and, if so, add it */ + if(relpSendqIsEmpty(pSessEtry->pSess->pSendq)) { + epoll_set_events(pThis, pSessEtry, sock, EPOLLIN); + } else { + epoll_set_events(pThis, pSessEtry, sock, EPOLLIN | EPOLLOUT); + } + } + } + + /* wait for io to become ready */ + if(relpEngineShouldStop(pThis)) break; + pThis->dbgprint("librelp: doing epoll_wait\n"); + nEvents = epoll_wait(pThis->efd, events, sizeof(events)/sizeof(struct epoll_event), -1); + pThis->dbgprint("librelp: done epoll_wait, nEvents:%d\n", nEvents); + if(relpEngineShouldStop(pThis)) break; + + for(i = 0 ; i < nEvents ; ++i) { + if(relpEngineShouldStop(pThis)) break; + epd = (epolld_t*) events[i].data.ptr; + switch(epd->typ) { + case epolld_lstn: + handleConnectionRequest(pThis, epd->ptr, epd->sock); + break; + case epolld_sess: + handleSessIO(pThis, epd); + break; + default: + relpEngineCallOnGenericErr(pThis, "librelp", RELP_RET_ERR_INTERNAL, + "invalid epolld_type_t %d after epoll", epd->typ); + break; + } + } + } + + LEAVE_RELPFUNC; +} +#else /* no epoll support available */ +static inline relpRetVal engineEventLoopInit(relpEngine_t __attribute__((unused)) *pThis) { return RELP_RET_OK; } +static inline relpRetVal engineEventLoopExit(relpEngine_t __attribute__((unused)) *pThis) { return RELP_RET_OK; } +static relpRetVal +engineEventLoopRun(relpEngine_t *pThis) { relpEngSrvLst_t *pSrvEtry; relpEngSessLst_t *pSessEtry; relpEngSessLst_t *pSessEtryNext; - relpSess_t *pNewSess; relpTcp_t *pTcp; relpRetVal localRet; int iSocks; @@ -542,12 +857,7 @@ if(relpEngineShouldStop(pThis)) break; sock = relpSrvGetLstnSock(pSrvEtry->pSrv, iSocks); if(FD_ISSET(sock, &readfds)) { - pThis->dbgprint("new connect on RELP socket #%d\n", sock); - localRet = relpSessAcceptAndConstruct(&pNewSess, pSrvEtry->pSrv, sock); - if(localRet == RELP_RET_OK) { - localRet = relpEngineAddToSess(pThis, pNewSess); - } - /* TODO: check localret, emit error msg! */ + handleConnectionRequest(pThis, pSrvEtry->pSrv, sock); --nfds; /* indicate we have processed one */ } } @@ -593,6 +903,35 @@ LEAVE_RELPFUNC; } +#endif /* epoll/select support */ + +/* The "Run" method starts the relp engine. Most importantly, this means the engine begins + * to read and write data to its peers. This method must be called on its own thread as it + * will not return until the engine is finished. Note that the engine itself may (or may + * not ;)) spawn additional threads. This is an implementation detail not to be cared of by + * caller. + * Note that the engine MUST be running even if the caller intends to just SEND messages. + * This is necessary because relp is a full-duplex protcol where acks and commands (e.g. + * "abort" may be received at any time. + * + * This function is implemented as a select() server. I know that epoll() wold probably + * be much better, but I implement the first version as select() because of portability. + * Once everything has matured, we may begin to provide performance-optimized versions for + * the several flavours of enhanced OS APIs. + * rgerhards, 2008-03-17 + */ +relpRetVal +relpEngineRun(relpEngine_t *pThis) +{ + ENTER_RELPFUNC; + RELPOBJ_assert(pThis, Engine); + + CHKRet(engineEventLoopInit(pThis)); + engineEventLoopRun(pThis); + engineEventLoopExit(pThis); +finalize_it: + LEAVE_RELPFUNC; +} /* as a quick hack, we provide our command handler prototypes here diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 --exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh old/librelp-1.1.5/src/relp.h new/librelp-1.2.0/src/relp.h --- old/librelp-1.1.5/src/relp.h 2013-07-05 09:54:46.000000000 +0200 +++ new/librelp-1.2.0/src/relp.h 2013-07-08 18:29:21.000000000 +0200 @@ -34,6 +34,9 @@ #define RELP_H_INCLUDED #include <pthread.h> +#if HAVE_SYS_EPOLL_H +# include <sys/epoll.h> +#endif #include "librelp.h" @@ -59,19 +62,47 @@ char **name; } relpPermittedPeers_t; +#if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) +typedef struct epolld_s epolld_t; +#endif /* a linked list entry for the list of relp servers (of this engine) */ typedef struct relpEngSrvLst_s { struct relpEngSrvLst_s *pPrev; struct relpEngSrvLst_s *pNext; +# if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + epolld_t **epevts; +# endif struct relpSrv_s *pSrv; } relpEngSrvLst_t; +#if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) +/* type of object stored in epoll descriptor */ +typedef enum { + epolld_lstn, + epolld_sess +} epolld_type_t; + +/* an epoll descriptor. contains all information necessary to process + * the result of epoll. + */ +struct epolld_s { + epolld_type_t typ; + void *ptr; + int sock; + struct epoll_event ev; +}; +#endif + /* a linked list entry for the list of relp sessions (of this engine) */ typedef struct relpEngSessLst_s { struct relpEngSessLst_s *pPrev; struct relpEngSessLst_s *pNext; struct relpSess_s *pSess; +# if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + enum { epoll_wronly, epoll_rdonly, epoll_rdwr } epollState; + epolld_t *epevt; +# endif } relpEngSessLst_t; @@ -93,6 +124,7 @@ unsigned char *pMsg, size_t lenMsg); /**< callback for "syslog" cmd */ void (*onAuthErr)(void*pUsr, char *authinfo, char*errmsg, relpRetVal errcode); void (*onErr)(void*pUsr, char *objinfo, char*errmsg, relpRetVal errcode); + void (*onGenericErr)(char *objinfo, char*errmsg, relpRetVal errcode); int protocolVersion; /**< version of the relp protocol supported by this engine */ /* Flags */ @@ -115,6 +147,9 @@ int lenSessLst; pthread_mutex_t mutSessLst; +# if defined(HAVE_EPOLL_CREATE1) || defined(HAVE_EPOLL_CREATE) + int efd; /**< file descriptor for epoll */ +# endif int bStop; /* set to 1 to stop server after next select */ int *bShutdownImmdt; /* if non-NULL provides a kind of "external" */ /* bStop functionality. This is in support for rsyslog, @@ -159,6 +194,7 @@ /* some macros to work with librelp error codes */ #define CHKRet(code) if((iRet = code) != RELP_RET_OK) goto finalize_it +#define CHKmalloc(r) if((r) == NULL) { iRet = RELP_RET_OUT_OF_MEMORY; goto finalize_it; } /* macro below is to be used if we need our own handling, eg for cleanup */ #define CHKRet_Hdlr(code) if((iRet = code) != RELP_RET_OK) /* macro below is used in conjunction with CHKiRet_Hdlr, else use ABORT_FINALIZE */ @@ -184,5 +220,6 @@ /* prototypes needed by library itself (rest is in librelp.h) */ relpRetVal relpEngineDispatchFrame(relpEngine_t *pThis, relpSess_t *pSess, relpFrame_t *pFrame); +void __attribute__((format(printf, 4, 5))) relpEngineCallOnGenericErr(relpEngine_t *pThis, char *eobj, relpRetVal ecode, char *fmt, ...); #endif /* #ifndef RELP_H_INCLUDED */ -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
