diff --git a/.tarball-version b/.tarball-version index af88ba8..e867cc2 100644 --- a/.tarball-version +++ b/.tarball-version @@ -1 +1 @@ -0.11.1 +0.14.2 diff --git a/.version b/.version index af88ba8..e867cc2 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -0.11.1 +0.14.2 diff --git a/ChangeLog b/ChangeLog index f09fe61..81968d9 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,626 @@ +2012-09-10 The Quarterback Library Release Team + + Fix "make distcheck" + + Bump the version to 0.14.2 + +2012-09-07 Виноградов Василий + + Get libqb building on cygwin. + +2012-09-06 Angus Salkeld + + Merge pull request #42 from jsgf/master + Three fixes for ipc_us.c + +2012-09-06 Jeremy Fitzhardinge + + ipc_us: slightly more robust cmsg handling + Cope with multiple cmsg structures in the received msg. + + ipc_us: on Linux, set SO_PASSCRED on the sending socket too + Linux doesn't pass credential information by default, only when it has + been specifically requested with SO_PASSCRED. This means there's a + race between when the ipc server side has set up and is listening on the + socket, and when the client may connect; if the client connects and sends + its first message before the server has set SO_PASSCRED on the socket, + then there will be no ucred information associated with the message. + + The fix is to set SO_PASSCRED on the client socket as well, so that + the message will always have a ucred associated with it when the server + reads it. + + Without this change, around 1% of cpg_model_initialize() calls fail + with CS_ERR_ACCESS. + + (This Linux behaviour was introduced just on a year ago in + 16e5726269611b71c930054ffe9b858c1cea88eb "af_unix: dont send + SCM_CREDENTIALS by default".) + + ipc_us: clear request unused fields + Clear unused request fields and padding so that valgrind doesn't complain + about undefined data being sent over the socket. + +2012-09-05 Andrew Beekhof + + TEST: Include writing and reading the blackbox in the log_long_msg test + +2012-09-05 Angus Salkeld + + LOG: fix qb_vsnprintf_deserialize() + the strlcat was not call correctly, it needs the + original string to find the end and return the + correct length. + +2012-09-01 Angus Salkeld + + Merge pull request #41 from jsgf/master + Fix some 64-bit big-endian issues + +2012-09-01 Jeremy Fitzhardinge + + blackbox: fix 64-bit big-endian issues + Two issues: + 1. when writing out the function name length, don't just write the 4 MSB + of the size + 2. when reading the time, don't just use the 4 MSB of the time as the + timestamp; the log contains a full time_t, so we may as well use it. + +2012-08-31 Angus Salkeld + + Remove IPC_NEEDS_RESPONSE_ACK and turn off shm ipc on solaris + + Define unix path max for openbsd + + Only turn on ipc_needs_response_ack=yes for solaris + Hopefully I can kill this option. + + Some improvements to kqueue usage. + +2012-08-30 Angus Salkeld + + kqueue: drop log message to trace. + +2012-08-29 Angus Salkeld + + Fix splint warning + + openbsd requires netinet/in.h before arpa/inet.h + + Avoid strcpy() use strlcpy() instead. + + Fix kqueue complile warnings + + openbsd doesn't have EBADMSG + + openbsd has a different UNIX_PATH_MAX + 103 other bsd's are 108 + + LOG: change qb_vsprintf_serialize() into qb_vsnprintf_serialize() + This is to prevent overwriting the ringbuffer. + Also remove stpcpy() as it is not used anymore. + + TEST: increase timeout to 6 secs as the recv timeout is 5 secs + + TEST: get the logic right - grrr. + + Turn off attribute_section on netbsd + + Some missing pshared semaphore checks + + Cleanup the checks for pshared semaphores + + Add a config check for pthread_mutexattr_setpshared + Not available on netbsd + +2012-08-28 Angus Salkeld + + Remove uses of timersub and use qb_util_stopwatch + + RB: change the #error to ENOTSUP if no usable shared process sem + This is mainly on mac. + + LOOP-KQUEUE: fix reference before assignment. + +2012-08-27 Fabio M. Di Nitto + + build: fix libqb.pc creation and make maintainer-clean + LIB_RT is unnecessary around. AC_CHECK_LIBS will do the right thing + + similar for the other libs that are all exported via LIBS + +2012-08-27 Angus Salkeld + + LOG: Make sure the semaphores are initialized. + +2012-08-24 Fabio M. Di Nitto + + build: remove bashism in cc support check + this is required for all systems that don't use bash for /bin/sh + +2012-08-24 Angus Salkeld + + Catch disconnected sockets on Solaris + It seems like poll() was not producing a POLLHUP + so we rely on qb_ipc_us_recv() returning -ENOTCONN. + + Merge pull request #40 from jsgf/master + Merge Jeremy's clang bugfixes. + +2012-08-24 Jeremy Fitzhardinge + + Don't free rb->shared_hdr in qb_rb_create_from_file() + Since qb_rb_close() frees it by munmapping it. + + Check error return of qb_ipcs_uc_recv_and_auth() + If it fails, then &ugp isn't initialized. + +2012-08-23 Andrew Beekhof + + Fix removal of automatically installed doc files when building rpms + +2012-08-22 Angus Salkeld + + Add the mailing list to the travis email notifications. + + Work around debian not setting the arch path in splint. + So just adding both i386 and x86_64 to the path. + Ref: http://lists.gnu.org/archive/html/gpsd-dev/2012-05/msg00221.html + + Remove color-tests and parallel-tests automake options. + This is just too painful for buildsystems like koji and travis. + You can't get access to the detailed output (error logs) that + otherwise be printed to screen. + I can't find a way to disable them on the command line (that + would be the best solution). + + Add travis continuous integration config + +2012-07-20 Angus Salkeld + + Merge pull request #39 from davidvossel/log_tag_fix + LOG: Invoke custom log filter function if tag changes + +2012-07-20 David Vossel + + LOG: Invoke custom log filter function if tag changes + +2012-07-19 Jim Meyering + + tests/rbwriter: don't ignore write failure + Here's another fix. + In adjusting the printf, I added a cast and switched to %5ld. + I would have preferred to use %5jd as the printf format (i.e., then no + cast is needed), but saw no other uses of the "j" directive, so perhaps + you do not yet depend on printf with such support. + + From 6d5d3af35d1f6851537f7af8996d1106c1ebe435 Mon Sep 17 00:00:00 2001 + From: Jim Meyering + Date: Wed, 18 Jul 2012 17:54:38 +0200 + Subject: [PATCH] tests/rbwriter: don't ignore write failure + + Spotted by coverity: + This less-than-zero comparison of an unsigned value is never true. + "res < 0U". + http://libqb.org/html/0.14.1/coverity/1/7rbwriter.c.html#error + + ipcs: avoid use-after-free for size-0 || disconnect-request + Hi, + + Glancing through coverity-reported issues, + I saw that this one required attention: + + From 70f1f689022321710405f16dc45b3df30c22bc59 Mon Sep 17 00:00:00 2001 + From: Jim Meyering + Date: Wed, 18 Jul 2012 17:34:17 +0200 + Subject: [PATCH] ipcs: avoid use-after-free for size-0 || disconnect-request + + spotted by coverity: + http://libqb.org/html/0.14.1/coverity/1/265ipcs.c.html#error + +2012-07-17 The Quarterback Library Release Team + + Bump the version to 0.14.1 + +2012-07-17 Angus Salkeld + + RB: set the new read pointer after clearing the header. + This is to prevent a situation where a fast writer will + write their new chunk between setting the new read pointer + and clearing the header. + + RB: improve the debug print outs + + RB: be more explicit about the word alignment + + RB: cleanup the macros for wrapping the index + + RB: use sem_getvalue as a tie breaker when read_pt == write_pt + + RB: if read or peek don't get the message then re-post to the semaphore + + RB: convert the rb_peek() status into a recv like status. + peek returns 0 on no data, so convert that to -EAGAIN. + + RB: use internal reclaim function + + IPC: use calloc instead of malloc to fix valgrind warnings + This is to cleanup some valgrind warnings. + +2012-07-14 Angus Salkeld + + Upgrade the doxygen config. + The new doxygen says SHOW_DIRECTORIES is deprecated. + + Fix a valgrind error. + just use the receive buffer, as it will be big enough. + +2012-06-22 The Quarterback Library Release Team + + Bump the version to 0.14.0 + +2012-06-14 Angus Salkeld + + LOG: fix threaded logging. + This has been broken for a year - yikes! + Thanks to Voznesensky Vladimir for spotting it. + +2012-06-13 Angus Salkeld + + Add user control of the permissions that are set on the shared mem files + +2012-06-07 Andrew Beekhof + + LOG: Restrict string trucation during serialization to when a precision is specified + + LOG: Gracefully fail when the caller exceeds QB_LOG_MAX_LEN + + LOG: Observe field widths when serializing string arguments + +2012-06-07 Angus Salkeld + + RB: use the same mechanism in reclaim as read/peek to detect end-of-ring + +2012-06-06 Angus Salkeld + + Add needs_response_ack option to ./check + + RB: fix wrong sem_flg IPC_NOWAIT option + The #ifdef was the wrong way around causing + the sem to return early with EAGAIN. + + TESTS: fix warning about unused functions + + Remove D_FORTIFY_SOURCE from check. + Can't seem to get this to work on F17. + + Open shared mem file in /dev/shm only for linux + + Don't use msg_flags on solaris (recvmsg). + + Turn off attribute_section on solaris + + ipc example: add -e (events) option + use events instead of responses + + IPC: if the server returns EAGAIN or ETIMEOUT the check the connection + Mainly useful for shm, as the ringbuffer doesn't know the state + of the connection. + +2012-06-05 Angus Salkeld + + LOG: make it possible to fsync() on each file log. + +2012-06-04 Angus Salkeld + + IPC: make sure that the created callback happens before dispatches + This only happened on the socket ipc type. + + LOG: fix the printing of %p in the blackbox + +2012-06-01 Angus Salkeld + + IPC: On bsd's use the notifier for responses + The point of this is to catch connection failures + more reliably. + + IPC: interpret ECONNRESET and EPIPE as ENOTCONN + +2012-05-31 Angus Salkeld + + cleanup some warnings + + config: use newer AC_COMPILE_IFELSE() + +2012-05-28 Angus Salkeld + + blackbox: fix %p formatting + + LOG: put all fields in the blackbox (added priority and tags) + Fixes #36 + + example: make the priority uint8_t + + Remove strerror out of check_funcs + We only use strerror_r + + RB: fix compiler warning. + + Add replacement function stpcpy + + Add missing AC_TYPE_UINT16_T to configure.ac + + Use AC_FUNC_STRERROR_R and STRERROR_R_CHAR_P + + Add stpcpy strcasecmp to the check_funcs + + Move some conditional defines into code (from the configure script) + + Remove some unused configure checks + + Remove message queues + + Check for union semun properly + + Blackbox: provide more space for log messages when reading from the blackbox. + This is to allow for the header (16bytes and variable length function). + so if someone has a function name > 400 chars it will break. I + recon that will do:) + +2012-05-28 Andrew Beekhof + + Add the blackbox reader manpage to the spec file + + Enable error logging for the blackbox reader + + RB: Read the file size into an initialized variable of the correct size + +2012-05-28 Angus Salkeld + + Add a tool to dump the blackbox. + +2012-05-25 Angus Salkeld + + RB: to be safer save the read and write pointers at the top of the blackbox + +2012-05-24 Jim Meyering + + avoid unwarranted use of strncpy: use memcpy instead + * lib/log_format.c (qb_vsnprintf_deserialize): We know that there are + len or more non-NUL bytes in the source string, so it's clearer to + use memcpy. + +2012-05-24 Angus Salkeld + + blackbox: fix the print_from_file() + + RB: add an option to not use any semaphores + (brought over from the "speed" branch) + + LOG: tweak the blackbox format string + + LOG: accept NULL strings into the blackbox + + LOG: protect close and reload from calling log + Logging during these operations is temporarly disabled. + +2012-05-21 Angus Salkeld + + Add benchmark option (-b) to examples/ipcclient + + TEST: make rbreader/writer more like the other benchmarking apps + +2012-05-16 Angus Salkeld + + IPC: log the connection description in all logs + + TEST: re-organise the ipc test suites + + IPC: only modify the dispatch if we get EAGAIN + +2012-05-12 Jan Friesse + + Correctly display timestamp in blackbox + On little endian architectures where time_t is 64-bit long integer could + happen, that instead of displaying correct timestamp, random data was + used, because of memcpy. + + Solution is to memcpy to real 32-bit variable and then assing this value + to timestamp. This will let compiler decide endianity and store number + correctly. + +2012-05-10 Angus Salkeld + + Add a more verbose version of the library versioning text. + + Bump the library version to 0.13.0 + + Remove unneccessary __attribute__ ((aligned(8))) from internal headers + + IPC: add a new function to get (and alloc) the extended stats. + This should handle any further additions to the stats + as the library allocs the struct. + + Revert "Add the event queue length to the connection stats." + This reverts commit 6b7da3f5315473c05b5939903d97be2e8ade4c8c. + + IPC: cleanup better on a failed client connect. + + IPC(soc): be more consistent with control struct size + + IPC: kill a compiler warning + + IPC(soc): pass in the correct size into munmap() + +2012-05-10 The Quarterback Library Release Team + + Bump the lib version to 0.12.0 + +2012-05-10 Angus Salkeld + + TEST: Use /bin/sh not /bin/bash + + TEST: check for lost shared mem on bsd too + + rb: cleanup the semaphores + - the way they are selected + - rpl_sem.c the error handling + + Fix some small issues in ./check + +2012-05-09 Angus Salkeld + + Cleanup the .gitignore files + + configure.ac tweaks + Thanks again to Igor Pashev. + + Remove HZ and use sysconf instead. + + SUN_LEN() macro is present if __EXTENSIONS__ is defined on Illumos + A bit reworked but originally from Igor Pashev: + https://github.com/ip1981/libqb/commit/84c47f8160a9a78f068cc5b0d40b3901c065cfa2 + + Note: __EXTENSIONS__ also defines _GNU_SOURCE, so removing it as well. + +2012-05-09 Igor Pashev + + PF_UNIX is a POSIX standard name + + Test for log facility names + +2012-05-09 Angus Salkeld + + IPC: drop log message to debug. + this can be noisy when there are a lot of transient + connections. + +2012-05-03 Angus Salkeld + + IPC: fix retrying of partial recv's and sends. + Move to send() instead of sendmsg() as it's easier + to track resending partial messages. + + IPC: initialize enough shared mem for all 3 one way connections. + +2012-05-02 Angus Salkeld + + IPC: keep retrying to recv the socket message if partially recv'ed (part 2) + + IPC: keep retrying to recv the socket message if partially recv'ed + + IPC: handle the server shutdown better + + IPC: handle a connection disconnect from the server better + Only problem with SOCKET. + +2012-05-01 Angus Salkeld + + IPC: make it possible to send events in the connected callback. + This was only a problem with QB_IPC_SOCKET. + + Add the event queue length to the connection stats. + + IPC: add a is_connected client side function. + + Fix typo in ./check + + docs: clarify the need to use request/response headers + + Remove unused local variable + +2012-04-30 Angus Salkeld + + IPC: change the socket recv function to read the response header. + It needs to only recv the size of this message, else we recv more + than one message and effectively drop messages (hidden at the end + of the current message). + + Add some special commands into the ipc example + type "events" and the server will send 10 events. + type 'kill' into the client and this will simulate the server dying. + + TEST: improve the tracing in the ipc tests. + +2012-04-30 Andrew Beekhof + + Make "make (s)rpm" work more reliably + Make sure the version number is re-calculated on each run. + +2012-04-30 Angus Salkeld + + TEST: add a test to confirm we get the events we send. + + TEST: reuse send_and_check for events. + + IPC: make it possible for a root client to talk to a non-root server. + +2012-04-26 Angus Salkeld + + Run ./Lindent in the examples directory + + Add some debug code to the ipcclient example + + IPC: make sure ipc (socket) clients can connect to a server running as root. + +2012-04-23 Angus Salkeld + + IPC: allow qb to bump the max_message_size + I think this is more user friendly. + + IPC: check for a sane minimum max_message_size + + add rpl_sem.h loop_poll_int.h to noinst_headers + +2012-04-04 Angus Salkeld + + Handle errors more consistently + + call recv_ready on socket types + + Handle a recv of size 0 + + make bsd shm path better by default. + + Fix kqueue on freebsd. + + Get the example socket includes right. + + Fix kqueue compiling. + + POLL: seperate out the poll/epoll and add kqueue + +2012-04-03 Jan Friesse + + Test existence of getpeer* functions + + Add inet header to tcpclient example + + Don't link with setpshared if unavailable + + NetBSD doesn't have semun defined + +2012-03-28 Jan Friesse + + Use MADV_NOSYNC only on systems where available + + Use SCHED_BATCH only on platforms where available + +2012-03-27 Angus Salkeld + + Fix a bug introduced by the bsd patch. + I missed the non-native case. + + Cleanup the selection of semaphores to use + + Fix some leaks in the logging. + Mainly for valgrind purposes. + +2012-03-24 Angus Salkeld + + Try and improve the portability on bsd variants. + Also add a QB_IPC_NATIVE type that selects the best ipc type available. + 2012-03-11 The Quarterback Library Release Team Bump the version to 0.11.1 diff --git a/Makefile.am b/Makefile.am index 3420bea..74a464e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -41,7 +41,7 @@ ACLOCAL_AMFLAGS = -I m4 dist_doc_DATA = COPYING INSTALL README.markdown -SUBDIRS = include lib docs tests examples +SUBDIRS = include lib docs tools tests examples doxygen: $(MAKE) -C docs doxygen @@ -107,12 +107,16 @@ RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \ --define "_srcrpmdir $(abs_builddir)" \ --define "_rpmdir $(abs_builddir)" +tarball: $(TARFILE) + srpm: clean - $(MAKE) $(SPEC) $(TARFILE) + autoreconf -if + $(MAKE) $(SPEC) tarball rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC) rpm: clean - $(MAKE) $(SPEC) $(TARFILE) + autoreconf -if + $(MAKE) $(SPEC) tarball rpmbuild $(RPMBUILDOPTS) -ba $(SPEC) # release/versioning diff --git a/Makefile.in b/Makefile.in index 7b0b742..9aa0421 100644 --- a/Makefile.in +++ b/Makefile.in @@ -58,8 +58,9 @@ host_triplet = @host@ subdir = . DIST_COMMON = $(am__configure_deps) $(dist_doc_DATA) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ - $(top_srcdir)/configure COPYING INSTALL compile config.guess \ - config.sub depcomp install-sh ltmain.sh missing + $(top_srcdir)/configure COPYING INSTALL build-aux/compile \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ @@ -212,7 +213,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -315,7 +315,7 @@ MAINTAINERCLEANFILES = Makefile.in aclocal.m4 configure depcomp \ ACLOCAL_AMFLAGS = -I m4 dist_doc_DATA = COPYING INSTALL README.markdown -SUBDIRS = include lib docs tests examples +SUBDIRS = include lib docs tools tests examples RPMBUILDOPTS = --define "_sourcedir $(abs_builddir)" \ --define "_specdir $(abs_builddir)" \ --define "_builddir $(abs_builddir)" \ @@ -910,12 +910,16 @@ $(SPEC): $(SPEC).in $(TARFILE): $(MAKE) dist +tarball: $(TARFILE) + srpm: clean - $(MAKE) $(SPEC) $(TARFILE) + autoreconf -if + $(MAKE) $(SPEC) tarball rpmbuild $(RPMBUILDOPTS) --nodeps -bs $(SPEC) rpm: clean - $(MAKE) $(SPEC) $(TARFILE) + autoreconf -if + $(MAKE) $(SPEC) tarball rpmbuild $(RPMBUILDOPTS) -ba $(SPEC) .version: echo $(VERSION) > $@-t && mv $@-t $@ diff --git a/compile b/build-aux/compile similarity index 100% rename from compile rename to build-aux/compile diff --git a/config.guess b/build-aux/config.guess similarity index 100% rename from config.guess rename to build-aux/config.guess diff --git a/config.sub b/build-aux/config.sub similarity index 100% rename from config.sub rename to build-aux/config.sub diff --git a/depcomp b/build-aux/depcomp similarity index 100% rename from depcomp rename to build-aux/depcomp diff --git a/install-sh b/build-aux/install-sh similarity index 100% rename from install-sh rename to build-aux/install-sh diff --git a/ltmain.sh b/build-aux/ltmain.sh similarity index 100% rename from ltmain.sh rename to build-aux/ltmain.sh diff --git a/missing b/build-aux/missing similarity index 100% rename from missing rename to build-aux/missing diff --git a/configure b/configure index 16a9c54..e429674 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for libqb 0.11.1. +# Generated by GNU Autoconf 2.68 for libqb 0.14.2. # # Report bugs to . # @@ -174,6 +174,7 @@ test x\$exitcode = x0 || exit 1" as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 +test \$(( 1 + 1 )) = 2 || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' @@ -181,8 +182,7 @@ test x\$exitcode = x0 || exit 1" ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ - || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" + || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libqb' PACKAGE_TARNAME='libqb' -PACKAGE_VERSION='0.11.1' -PACKAGE_STRING='libqb 0.11.1' +PACKAGE_VERSION='0.14.2' +PACKAGE_STRING='libqb 0.14.2' PACKAGE_BUGREPORT='quarterback-devel@fedorahosted.org' PACKAGE_URL='' @@ -621,17 +621,20 @@ LINT_FLAGS SOCKETDIR HAVE_DICT_WORDS_FALSE HAVE_DICT_WORDS_TRUE -HAVE_POSIX_MQ_FALSE -HAVE_POSIX_MQ_TRUE -HAVE_SYSV_MQ_FALSE -HAVE_SYSV_MQ_TRUE HAVE_SLOW_TESTS_FALSE HAVE_SLOW_TESTS_TRUE -LIB_RT CP HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS_FALSE HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS_TRUE LIBOBJS +HAVE_KQUEUE_FALSE +HAVE_KQUEUE_TRUE +HAVE_POLL_FALSE +HAVE_POLL_TRUE +HAVE_EPOLL_FALSE +HAVE_EPOLL_TRUE +HAVE_SEM_TIMEDWAIT_FALSE +HAVE_SEM_TIMEDWAIT_TRUE HAVE_GLIB_FALSE HAVE_GLIB_TRUE GLIB_LIBS @@ -657,7 +660,6 @@ CXXDEPMODE ac_ct_CXX CXXFLAGS CXX -CPP OTOOL64 OTOOL LIPO @@ -675,26 +677,7 @@ ac_ct_DUMPBIN DUMPBIN LD FGREP -EGREP -GREP SED -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC host_os host_vendor host_cpu @@ -708,6 +691,16 @@ AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V +am__fastdepCC_FALSE +am__fastdepCC_TRUE +CCDEPMODE +am__nodep +AMDEPBACKSLASH +AMDEP_FALSE +AMDEP_TRUE +am__quote +am__include +DEPDIR am__untar am__tar AMTAR @@ -731,6 +724,16 @@ am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC target_alias host_alias build_alias @@ -772,12 +775,12 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking +enable_dependency_tracking enable_silent_rules enable_shared enable_static with_pic enable_fast_install -enable_dependency_tracking with_gnu_ld with_sysroot enable_libtool_lock @@ -1350,7 +1353,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures libqb 0.11.1 to adapt to many kinds of systems. +\`configure' configures libqb 0.14.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1420,7 +1423,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of libqb 0.11.1:";; + short | recursive ) echo "Configuration of libqb 0.14.2:";; esac cat <<\_ACEOF @@ -1428,14 +1431,14 @@ Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors --enable-silent-rules less verbose build output (undo: `make V=1') --disable-silent-rules verbose build output (undo: `make V=0') --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] - --disable-dependency-tracking speeds up one-time build - --enable-dependency-tracking do not reject slow dependency extractors --disable-libtool-lock avoid locking (might break parallel builds) --enable-ansi : force to build with ANSI standards. --enable-fatal-warnings : enable fatal warnings. @@ -1542,7 +1545,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -libqb configure 0.11.1 +libqb configure 0.14.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1594,6 +1597,207 @@ fi } # ac_fn_c_try_compile +# ac_fn_c_try_cpp LINENO +# ---------------------- +# Try to preprocess conftest.$ac_ext, and return whether this succeeded. +ac_fn_c_try_cpp () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err + ac_status=$? + if test -s conftest.err; then + grep -v '^ *+' conftest.err >conftest.er1 + cat conftest.er1 >&5 + mv -f conftest.er1 conftest.err + fi + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } > conftest.i && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then : + ac_retval=0 +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=1 +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_cpp + +# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists, giving a warning if it cannot be compiled using +# the include files in INCLUDES and setting the cache variable VAR +# accordingly. +ac_fn_c_check_header_mongrel () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if eval \${$3+:} false; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 +$as_echo_n "checking $2 usability... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_header_compiler=yes +else + ac_header_compiler=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 +$as_echo_n "checking $2 presence... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include <$2> +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + ac_header_preproc=yes +else + ac_header_preproc=no +fi +rm -f conftest.err conftest.i conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( + yes:no: ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} + ;; + no:yes:* ) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} +( $as_echo "## ------------------------------------------------- ## +## Report this to quarterback-devel@fedorahosted.org ## +## ------------------------------------------------- ##" + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + eval "$3=\$ac_header_compiler" +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +fi + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_mongrel + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes +# that executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +$as_echo "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; }; then : + ac_retval=0 +else + $as_echo "$as_me: program exited with status $ac_status" >&5 + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run + +# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES +# ------------------------------------------------------- +# Tests whether HEADER exists and can be compiled using the include files in +# INCLUDES, setting the cache variable VAR accordingly. +ac_fn_c_check_header_compile () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 +$as_echo_n "checking for $2... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +#include <$2> +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_header_compile + # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. @@ -1640,116 +1844,6 @@ fi } # ac_fn_c_try_link -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly @@ -1938,97 +2032,6 @@ fi } # ac_fn_cxx_try_link -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} -( $as_echo "## ------------------------------------------------- ## -## Report this to quarterback-devel@fedorahosted.org ## -## ------------------------------------------------- ##" - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel - # ac_fn_c_find_intX_t LINENO BITS VAR # ----------------------------------- # Finds a signed integer type with width BITS, setting cache variable VAR @@ -2209,11 +2212,114 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_find_uintX_t + +# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES +# ---------------------------------------------------- +# Tries to find if the field MEMBER exists in type AGGR, after including +# INCLUDES, setting cache variable VAR accordingly. +ac_fn_c_check_member () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5 +$as_echo_n "checking for $2.$3... " >&6; } +if eval \${$4+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$5 +int +main () +{ +static $2 ac_aggr; +if (sizeof ac_aggr.$3) +return 0; + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$4=yes" +else + eval "$4=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$4 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_member + +# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES +# --------------------------------------------- +# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR +# accordingly. +ac_fn_c_check_decl () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + as_decl_name=`echo $2|sed 's/ *(.*//'` + as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 +$as_echo_n "checking whether $as_decl_name is declared... " >&6; } +if eval \${$3+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +#ifndef $as_decl_name +#ifdef __cplusplus + (void) $as_decl_use; +#else + (void) $as_decl_name; +#endif +#endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + eval "$3=yes" +else + eval "$3=no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +eval ac_res=\$$3 + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + +} # ac_fn_c_check_decl cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by libqb $as_me 0.11.1, which was +It was created by libqb $as_me 0.14.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2564,13 +2670,8 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_config_headers="$ac_config_headers include/config.h include/qb/qbconfig.h" - -am__api_version='1.11' - ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do +for ac_dir in build-aux "$srcdir"/build-aux; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" @@ -2586,7 +2687,7 @@ for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do fi done if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 + as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 fi # These three variables are undocumented and unsupported, @@ -2598,749 +2699,8 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Just in case -sleep 1 -echo timestamp > conftest.file -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; -esac - -# Do `set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - rm -f conftest.file - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken -alias in your environment" "$LINENO" 5 - fi - - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --run true"; then - am_missing_run="$MISSING --run " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi - -# Installed binaries are usually stripped using `strip' when the user -# run `make install-strip'. However `strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the `STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } - -mkdir_p="$MKDIR_P" -case $mkdir_p in - [\\/$]* | ?:[\\/]*) ;; - */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; -esac - -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then - ac_cv_prog_AWK="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='libqb' - VERSION='0.11.1' - - -cat >>confdefs.h <<_ACEOF -#define PACKAGE "$PACKAGE" -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define VERSION "$VERSION" -_ACEOF - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in -yes) AM_DEFAULT_VERBOSITY=0;; -no) AM_DEFAULT_VERBOSITY=1;; -*) AM_DEFAULT_VERBOSITY=0;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - - -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.4.2' -macro_revision='1.3337' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -# Backslashify metacharacters that are still active within -# double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO -ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 -$as_echo_n "checking how to print strings... " >&6; } -# Test print first, because it will be a builtin if present. -if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ - test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='print -r --' -elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then - ECHO='printf %s\n' -else - # Use this function as a fallback that always works. - func_fallback_echo () - { - eval 'cat <<_LTECHO_EOF -$1 -_LTECHO_EOF' - } - ECHO='func_fallback_echo' -fi - -# func_echo_all arg... -# Invoke $ECHO with all args, space-separated. -func_echo_all () -{ - $ECHO "" -} - -case "$ECHO" in - printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 -$as_echo "printf" >&6; } ;; - print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 -$as_echo "print -r" >&6; } ;; - *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 -$as_echo "cat" >&6; } ;; -esac - - - - - - - - - - - - - - -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from `make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi +ac_config_headers="$ac_config_headers include/config.h include/qb/qbconfig.h" ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -4132,214 +3492,143 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -depcc="$CC" am_compiler_list= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if ${ac_cv_prog_CPP+:} false; then : $as_echo_n "(cached) " >&6 else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi else - ac_cv_path_SED=$SED + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : + break fi + done + ac_cv_prog_CPP=$CPP + fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 +$as_echo "$CPP" >&6; } +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : +else + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.i conftest.$ac_ext + # OK, works on sane cases. Now check whether nonexistent headers + # can be detected and how. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +_ACEOF +if ac_fn_c_try_cpp "$LINENO"; then : + # Broken: success on invalid input. +continue +else + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.i conftest.$ac_ext +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.i conftest.err conftest.$ac_ext +if $ac_preproc_ok; then : +else + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details" "$LINENO" 5; } +fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 @@ -4472,6 +3761,1153 @@ $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } +if ${ac_cv_header_stdc+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_header_stdc=yes +else + ac_cv_header_stdc=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then : + +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + return 2; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + +else + ac_cv_header_stdc=no +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } +if test $ac_cv_header_stdc = yes; then + +$as_echo "#define STDC_HEADERS 1" >>confdefs.h + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do : + as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default +" +if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : + cat >>confdefs.h <<_ACEOF +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default" +if test "x$ac_cv_header_minix_config_h" = xyes; then : + MINIX=yes +else + MINIX= +fi + + + if test "$MINIX" = yes; then + +$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h + + +$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h + + +$as_echo "#define _MINIX 1" >>confdefs.h + + fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5 +$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; } +if ${ac_cv_safe_to_define___extensions__+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# define __EXTENSIONS__ 1 + $ac_includes_default +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_safe_to_define___extensions__=yes +else + ac_cv_safe_to_define___extensions__=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5 +$as_echo "$ac_cv_safe_to_define___extensions__" >&6; } + test $ac_cv_safe_to_define___extensions__ = yes && + $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h + + $as_echo "#define _ALL_SOURCE 1" >>confdefs.h + + $as_echo "#define _GNU_SOURCE 1" >>confdefs.h + + $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h + + $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h + + + +am__api_version='1.11' + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } +if test -z "$INSTALL"; then +if ${ac_cv_path_install+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in #(( + ./ | .// | /[cC]/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + fi + done + done + ;; +esac + + done +IFS=$as_save_IFS + +rm -rf conftest.one conftest.two conftest.dir + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 +$as_echo_n "checking whether build environment is sane... " >&6; } +# Just in case +sleep 1 +echo timestamp > conftest.file +# Reject unsafe characters in $srcdir or the absolute working directory +# name. Accept space and tab only in the latter. +am_lf=' +' +case `pwd` in + *[\\\"\#\$\&\'\`$am_lf]*) + as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; +esac +case $srcdir in + *[\\\"\#\$\&\'\`$am_lf\ \ ]*) + as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;; +esac + +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t "$srcdir/configure" conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + as_fn_error $? "ls -t appears to fail. Make sure there is not a broken +alias in your environment" "$LINENO" 5 + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + as_fn_error $? "newly created file is older than distributed files! +Check your system clock" "$LINENO" 5 +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +test "$program_prefix" != NONE && + program_transform_name="s&^&$program_prefix&;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s&\$&$program_suffix&;$program_transform_name" +# Double any \ or $. +# By default was `s,x,x', remove it if useless. +ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' +program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +if test x"${MISSING+set}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; + *) + MISSING="\${SHELL} $am_aux_dir/missing" ;; + esac +fi +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 +$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if test x"${install_sh}" != xset; then + case $am_aux_dir in + *\ * | *\ *) + install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; + *) + install_sh="\${SHELL} $am_aux_dir/install-sh" + esac +fi + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 +$as_echo "$STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_STRIP+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_STRIP="strip" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 +$as_echo "$ac_ct_STRIP" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_STRIP" = x; then + STRIP=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + STRIP=$ac_ct_STRIP + fi +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 +$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } +if test -z "$MKDIR_P"; then + if ${ac_cv_path_mkdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in mkdir gmkdir; do + for ac_exec_ext in '' $ac_executable_extensions; do + { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue + case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( + 'mkdir (GNU coreutils) '* | \ + 'mkdir (coreutils) '* | \ + 'mkdir (fileutils) '4.1*) + ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext + break 3;; + esac + done + done + done +IFS=$as_save_IFS + +fi + + test -d ./--version && rmdir ./--version + if test "${ac_cv_path_mkdir+set}" = set; then + MKDIR_P="$ac_cv_path_mkdir -p" + else + # As a last resort, use the slow shell script. Don't cache a + # value for MKDIR_P within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + MKDIR_P="$ac_install_sh -d" + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 +$as_echo "$MKDIR_P" >&6; } + +mkdir_p="$MKDIR_P" +case $mkdir_p in + [\\/$]* | ?:[\\/]*) ;; + */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; +esac + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_AWK+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_AWK="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 +$as_echo "$AWK" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + test -n "$AWK" && break +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } +set x ${MAKE-make} +ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` +if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : + $as_echo_n "(cached) " >&6 +else + cat >conftest.make <<\_ACEOF +SHELL = /bin/sh +all: + @echo '@@@%%%=$(MAKE)=@@@%%%' +_ACEOF +# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. +case `${MAKE-make} -f conftest.make 2>/dev/null` in + *@@@%%%=?*=@@@%%%*) + eval ac_cv_prog_make_${ac_make}_set=yes;; + *) + eval ac_cv_prog_make_${ac_make}_set=no;; +esac +rm -f conftest.make +fi +if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + SET_MAKE= +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + +ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo this is the am__doit target +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 +$as_echo_n "checking for style of include used by $am_make... " >&6; } +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# Ignore all kinds of additional output from `make'. +case `$am_make -s -f confmf 2> /dev/null` in #( +*the\ am__doit\ target*) + am__include=include + am__quote= + _am_result=GNU + ;; +esac +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + case `$am_make -s -f confmf 2> /dev/null` in #( + *the\ am__doit\ target*) + am__include=.include + am__quote="\"" + _am_result=BSD + ;; + esac +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 +$as_echo "$_am_result" >&6; } +rm -f confinc confmf + +# Check whether --enable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then : + enableval=$enable_dependency_tracking; +fi + +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' + am__nodep='_no' +fi + if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + +if test "`cd $srcdir && pwd`" != "`pwd`"; then + # Use -I$(srcdir) only when $(srcdir) != ., so that make's output + # is not polluted with repeated "-I." + am__isrc=' -I$(srcdir)' + # test to see if srcdir already configured + if test -f $srcdir/config.status; then + as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 + fi +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE='libqb' + VERSION='0.14.2' + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. Yes, it's still used +# in the wild :-( We should find a proper way to deprecate it ... +AMTAR='$${TAR-tar}' + +am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' + + + + +depcc="$CC" am_compiler_list= + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 +$as_echo_n "checking dependency style of $depcc... " >&6; } +if ${am_cv_CC_dependencies_compiler_type+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + rm -rf conftest.dir + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + am__universal=false + case " $depcc " in #( + *\ -arch\ *\ -arch\ *) am__universal=true ;; + esac + + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. Also, some Intel + # versions had trouble with output in subdirs + am__obj=sub/conftest.${OBJEXT-o} + am__minus_obj="-o $am__obj" + case $depmode in + gcc) + # This depmode causes a compiler race in universal mode. + test "$am__universal" = false || continue + ;; + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + msvc7 | msvc7msys | msvisualcpp | msvcmsys) + # This compiler won't grok `-c -o', but also, the minuso test has + # not run yet. These depmodes are late enough in the game, and + # so weak that their functioning should not be impacted. + am__obj=conftest.${OBJEXT-o} + am__minus_obj= + ;; + none) break ;; + esac + if depmode=$depmode \ + source=sub/conftest.c object=$am__obj \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep $am__obj sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 +$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + +# Check whether --enable-silent-rules was given. +if test "${enable_silent_rules+set}" = set; then : + enableval=$enable_silent_rules; +fi + +case $enable_silent_rules in +yes) AM_DEFAULT_VERBOSITY=0;; +no) AM_DEFAULT_VERBOSITY=1;; +*) AM_DEFAULT_VERBOSITY=0;; +esac +am_make=${MAKE-make} +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 +$as_echo_n "checking whether $am_make supports nested variables... " >&6; } +if ${am_cv_make_support_nested_variables+:} false; then : + $as_echo_n "(cached) " >&6 +else + if $as_echo 'TRUE=$(BAR$(V)) +BAR0=false +BAR1=true +V=1 +am__doit: + @$(TRUE) +.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then + am_cv_make_support_nested_variables=yes +else + am_cv_make_support_nested_variables=no +fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 +$as_echo "$am_cv_make_support_nested_variables" >&6; } +if test $am_cv_make_support_nested_variables = yes; then + AM_V='$(V)' + AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' +else + AM_V=$AM_DEFAULT_VERBOSITY + AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY +fi +AM_BACKSLASH='\' + + +case `pwd` in + *\ * | *\ *) + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 +$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; +esac + + + +macro_version='2.4.2' +macro_revision='1.3337' + + + + + + + + + + + + + +ltmain="$ac_aux_dir/ltmain.sh" + +# Make sure we can run config.sub. +$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || + as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 +$as_echo_n "checking build system type... " >&6; } +if ${ac_cv_build+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_build_alias=$build_alias +test "x$ac_build_alias" = x && + ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` +test "x$ac_build_alias" = x && + as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 +ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 +$as_echo "$ac_cv_build" >&6; } +case $ac_cv_build in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; +esac +build=$ac_cv_build +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_build +shift +build_cpu=$1 +build_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +build_os=$* +IFS=$ac_save_IFS +case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 +$as_echo_n "checking host system type... " >&6; } +if ${ac_cv_host+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$host_alias" = x; then + ac_cv_host=$ac_cv_build +else + ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || + as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 +$as_echo "$ac_cv_host" >&6; } +case $ac_cv_host in +*-*-*) ;; +*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; +esac +host=$ac_cv_host +ac_save_IFS=$IFS; IFS='-' +set x $ac_cv_host +shift +host_cpu=$1 +host_vendor=$2 +shift; shift +# Remember, the first character of IFS is used to create $*, +# except with old shells: +host_os=$* +IFS=$ac_save_IFS +case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac + + +# Backslashify metacharacters that are still active within +# double-quoted strings. +sed_quote_subst='s/\(["`$\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\(["`\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to delay expansion of an escaped single quote. +delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO +ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 +$as_echo_n "checking how to print strings... " >&6; } +# Test print first, because it will be a builtin if present. +if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ + test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='print -r --' +elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then + ECHO='printf %s\n' +else + # Use this function as a fallback that always works. + func_fallback_echo () + { + eval 'cat <<_LTECHO_EOF +$1 +_LTECHO_EOF' + } + ECHO='func_fallback_echo' +fi + +# func_echo_all arg... +# Invoke $ECHO with all args, space-separated. +func_echo_all () +{ + $ECHO "" +} + +case "$ECHO" in + printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5 +$as_echo "printf" >&6; } ;; + print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 +$as_echo "print -r" >&6; } ;; + *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5 +$as_echo "cat" >&6; } ;; +esac + + + + + + + + + + + + + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 +$as_echo_n "checking for a sed that does not truncate output... " >&6; } +if ${ac_cv_path_SED+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ + for ac_i in 1 2 3 4 5 6 7; do + ac_script="$ac_script$as_nl$ac_script" + done + echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed + { ac_script=; unset ac_script;} + if test -z "$SED"; then + ac_path_SED_found=false + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue +# Check for GNU ac_path_SED and select it if it is found. + # Check for GNU $ac_path_SED +case `"$ac_path_SED" --version 2>&1` in +*GNU*) + ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; +*) + ac_count=0 + $as_echo_n 0123456789 >"conftest.in" + while : + do + cat "conftest.in" "conftest.in" >"conftest.tmp" + mv "conftest.tmp" "conftest.in" + cp "conftest.in" "conftest.nl" + $as_echo '' >> "conftest.nl" + "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break + diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break + as_fn_arith $ac_count + 1 && ac_count=$as_val + if test $ac_count -gt ${ac_path_SED_max-0}; then + # Best one so far, save it but keep looking for a better one + ac_cv_path_SED="$ac_path_SED" + ac_path_SED_max=$ac_count + fi + # 10*(2^10) chars as input seems more than enough + test $ac_count -gt 10 && break + done + rm -f conftest.in conftest.tmp conftest.nl conftest.out;; +esac + + $ac_path_SED_found && break 3 + done + done + done +IFS=$as_save_IFS + if test -z "$ac_cv_path_SED"; then + as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 + fi +else + ac_cv_path_SED=$SED +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 +$as_echo "$ac_cv_path_SED" >&6; } + SED="$ac_cv_path_SED" + rm -f conftest.sed + +test -z "$SED" && SED=sed +Xsed="$SED -e 1s/^X//" + + + + + + + + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if ${ac_cv_path_FGREP+:} false; then : @@ -5685,7 +6121,6 @@ test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO - if test -n "$ac_tool_prefix"; then for ac_prog in ar do @@ -7389,273 +7824,6 @@ $as_echo "$lt_cv_ld_force_load" >&6; } ;; esac -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default @@ -11685,6 +11853,7 @@ CC="$lt_save_CC" + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -15897,134 +16066,6 @@ ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named `D' -- because `-MD' means `put the output - # in D'. - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with - # Solaris 8's {/usr,}/bin/sh. - touch sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with `-c' and `-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle `-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # after this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok `-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -16479,7 +16520,8 @@ fi # this function checks if CC support options passed as # args. Global CFLAGS are ignored during this test. cc_supports_flag() { - local CPPFLAGS="$CPPFLAGS $@" + BACKUP="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $@" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports \"$@\"" >&5 $as_echo_n "checking whether $CC supports \"$@\"... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext @@ -16501,6 +16543,7 @@ else $as_echo "no" >&6; } fi rm -f conftest.err conftest.i conftest.$ac_ext + CPPFLAGS="$BACKUP" return $RC } @@ -16519,103 +16562,12 @@ case $exec_prefix in esac # Checks for libraries. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mq_open in -lrt" >&5 -$as_echo_n "checking for mq_open in -lrt... " >&6; } -if ${ac_cv_lib_rt_mq_open+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 +$as_echo_n "checking for library containing pthread_create... " >&6; } +if ${ac_cv_search_pthread_create+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lrt $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char mq_open (); -int -main () -{ -return mq_open (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_rt_mq_open=yes -else - ac_cv_lib_rt_mq_open=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_mq_open" >&5 -$as_echo "$ac_cv_lib_rt_mq_open" >&6; } -if test "x$ac_cv_lib_rt_mq_open" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBRT 1 -_ACEOF - - LIBS="-lrt $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBDL 1 -_ACEOF - - LIBS="-ldl $LIBS" - -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 -$as_echo_n "checking for pthread_create in -lpthread... " >&6; } -if ${ac_cv_lib_pthread_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lpthread $LIBS" + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -16634,33 +16586,156 @@ return pthread_create (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_pthread_pthread_create=yes -else - ac_cv_lib_pthread_pthread_create=no +for ac_lib in '' pthread; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_pthread_create=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_pthread_create+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 -$as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } -if test "x$ac_cv_lib_pthread_pthread_create" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBPTHREAD 1 -_ACEOF +done +if ${ac_cv_search_pthread_create+:} false; then : - LIBS="-lpthread $LIBS" +else + ac_cv_search_pthread_create=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 +$as_echo "$ac_cv_search_pthread_create" >&6; } +ac_res=$ac_cv_search_pthread_create +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5 -$as_echo_n "checking for socket in -lsocket... " >&6; } -if ${ac_cv_lib_socket_socket+:} false; then : +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing mq_open" >&5 +$as_echo_n "checking for library containing mq_open... " >&6; } +if ${ac_cv_search_mq_open+:} false; then : $as_echo_n "(cached) " >&6 else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsocket $LIBS" + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char mq_open (); +int +main () +{ +return mq_open (); + ; + return 0; +} +_ACEOF +for ac_lib in '' rt; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_mq_open=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_mq_open+:} false; then : + break +fi +done +if ${ac_cv_search_mq_open+:} false; then : + +else + ac_cv_search_mq_open=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_mq_open" >&5 +$as_echo "$ac_cv_search_mq_open" >&6; } +ac_res=$ac_cv_search_mq_open +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 +$as_echo_n "checking for library containing dlopen... " >&6; } +if ${ac_cv_search_dlopen+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char dlopen (); +int +main () +{ +return dlopen (); + ; + return 0; +} +_ACEOF +for ac_lib in '' dl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_dlopen=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_dlopen+:} false; then : + break +fi +done +if ${ac_cv_search_dlopen+:} false; then : + +else + ac_cv_search_dlopen=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 +$as_echo "$ac_cv_search_dlopen" >&6; } +ac_res=$ac_cv_search_dlopen +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5 +$as_echo_n "checking for library containing socket... " >&6; } +if ${ac_cv_search_socket+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -16679,23 +16754,91 @@ return socket (); return 0; } _ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_socket_socket=yes -else - ac_cv_lib_socket_socket=no +for ac_lib in '' socket; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_socket=$ac_res fi rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS + conftest$ac_exeext + if ${ac_cv_search_socket+:} false; then : + break fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5 -$as_echo "$ac_cv_lib_socket_socket" >&6; } -if test "x$ac_cv_lib_socket_socket" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_LIBSOCKET 1 -_ACEOF +done +if ${ac_cv_search_socket+:} false; then : - LIBS="-lsocket $LIBS" +else + ac_cv_search_socket=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5 +$as_echo "$ac_cv_search_socket" >&6; } +ac_res=$ac_cv_search_socket +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +fi + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5 +$as_echo_n "checking for library containing gethostbyname... " >&6; } +if ${ac_cv_search_gethostbyname+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char gethostbyname (); +int +main () +{ +return gethostbyname (); + ; + return 0; +} +_ACEOF +for ac_lib in '' nsl; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + if ac_fn_c_try_link "$LINENO"; then : + ac_cv_search_gethostbyname=$ac_res +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext + if ${ac_cv_search_gethostbyname+:} false; then : + break +fi +done +if ${ac_cv_search_gethostbyname+:} false; then : + +else + ac_cv_search_gethostbyname=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5 +$as_echo "$ac_cv_search_gethostbyname" >&6; } +ac_res=$ac_cv_search_gethostbyname +if test "$ac_res" != no; then : + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" fi @@ -17141,11 +17284,13 @@ $as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h fi -for ac_header in arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \ - dlfcn.h time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \ - sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h sys/uio.h \ - sys/sockio.h sys/un.h sys/resource.h syslog.h errno.h unistd.h sys/mman.h \ - sys/sem.h sys/ipc.h sys/msg.h mqueue.h +for ac_header in arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h \ + stdint.h stddef.h stdlib.h string.h strings.h \ + dlfcn.h time.h sys/time.h sys/types.h sys/stat.h \ + sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h \ + sys/uio.h sys/event.h sys/sockio.h sys/un.h sys/resource.h \ + syslog.h errno.h unistd.h sys/mman.h \ + sys/sem.h sys/ipc.h sys/msg.h netdb.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -17309,6 +17454,20 @@ _ACEOF fi +ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" +case $ac_cv_c_uint64_t in #( + no|yes) ;; #( + *) + +$as_echo "#define _UINT64_T 1" >>confdefs.h + + +cat >>confdefs.h <<_ACEOF +#define uint64_t $ac_cv_c_uint64_t +_ACEOF +;; + esac + ac_fn_c_find_uintX_t "$LINENO" "32" "ac_cv_c_uint32_t" case $ac_cv_c_uint32_t in #( no|yes) ;; #( @@ -17323,16 +17482,14 @@ _ACEOF ;; esac -ac_fn_c_find_uintX_t "$LINENO" "64" "ac_cv_c_uint64_t" -case $ac_cv_c_uint64_t in #( +ac_fn_c_find_uintX_t "$LINENO" "16" "ac_cv_c_uint16_t" +case $ac_cv_c_uint16_t in #( no|yes) ;; #( *) -$as_echo "#define _UINT64_T 1" >>confdefs.h - cat >>confdefs.h <<_ACEOF -#define uint64_t $ac_cv_c_uint64_t +#define uint16_t $ac_cv_c_uint16_t _ACEOF ;; esac @@ -17352,6 +17509,50 @@ _ACEOF esac +ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" "#include +" +if test "x$ac_cv_member_struct_sockaddr_un_sun_len" = xyes; then : + +$as_echo "#define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1" >>confdefs.h + +fi + + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking looking for union semun in sys/sem.h" >&5 +$as_echo_n "checking looking for union semun in sys/sem.h... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include + #include + #include +int +main () +{ +union semun arg; semctl(0, 0, 0, arg); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + +cat >>confdefs.h <<_ACEOF +#define HAVE_SEMUN 1 +_ACEOF + + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + # Checks for library functions. for ac_header in unistd.h do : @@ -17832,11 +18033,109 @@ $as_echo "#define HAVE_MMAP 1" >>confdefs.h fi rm -f conftest.mmap conftest.txt -for ac_func in alarm clock_gettime ftruncate gettimeofday localtime localtime_r \ - memset munmap socket strchr strrchr strdup strerror strstr \ - poll epoll_create epoll_create1 random rand getrlimit sysconf \ +ac_fn_c_check_decl "$LINENO" "strerror_r" "ac_cv_have_decl_strerror_r" "$ac_includes_default" +if test "x$ac_cv_have_decl_strerror_r" = xyes; then : + ac_have_decl=1 +else + ac_have_decl=0 +fi + +cat >>confdefs.h <<_ACEOF +#define HAVE_DECL_STRERROR_R $ac_have_decl +_ACEOF + +for ac_func in strerror_r +do : + ac_fn_c_check_func "$LINENO" "strerror_r" "ac_cv_func_strerror_r" +if test "x$ac_cv_func_strerror_r" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_STRERROR_R 1 +_ACEOF + +fi +done + +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether strerror_r returns char *" >&5 +$as_echo_n "checking whether strerror_r returns char *... " >&6; } +if ${ac_cv_func_strerror_r_char_p+:} false; then : + $as_echo_n "(cached) " >&6 +else + + ac_cv_func_strerror_r_char_p=no + if test $ac_cv_have_decl_strerror_r = yes; then + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ + + char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + char *p = strerror_r (0, buf, sizeof buf); + return !p || x; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_func_strerror_r_char_p=yes +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + else + # strerror_r is not declared. Choose between + # systems that have relatively inaccessible declarations for the + # function. BeOS and DEC UNIX 4.0 fall in this category, but the + # former has a strerror_r that returns char*, while the latter + # has a strerror_r that returns `int'. + # This test should segfault on the DEC system. + if test "$cross_compiling" = yes; then : + : +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default + extern char *strerror_r (); +int +main () +{ +char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + return ! isalpha (x); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + ac_cv_func_strerror_r_char_p=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_strerror_r_char_p" >&5 +$as_echo "$ac_cv_func_strerror_r_char_p" >&6; } +if test $ac_cv_func_strerror_r_char_p = yes; then + +$as_echo "#define STRERROR_R_CHAR_P 1" >>confdefs.h + +fi + +for ac_func in alarm clock_gettime ftruncate gettimeofday \ + localtime localtime_r memset munmap socket \ + strchr strrchr strdup strstr strcasecmp \ + poll epoll_create epoll_create1 kqueue \ + random rand getrlimit sysconf \ pthread_spin_lock pthread_setschedparam \ - sched_get_priority_max sched_setscheduler + pthread_mutexattr_setpshared \ + pthread_condattr_setpshared \ + sem_timedwait semtimedop \ + sched_get_priority_max sched_setscheduler \ + getpeerucred getpeereid do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" @@ -17849,6 +18148,39 @@ fi done + if test "x$ac_cv_func_sem_timedwait" = xyes; then + HAVE_SEM_TIMEDWAIT_TRUE= + HAVE_SEM_TIMEDWAIT_FALSE='#' +else + HAVE_SEM_TIMEDWAIT_TRUE='#' + HAVE_SEM_TIMEDWAIT_FALSE= +fi + + if test "x$ac_cv_func_epoll_create" = xyes; then + HAVE_EPOLL_TRUE= + HAVE_EPOLL_FALSE='#' +else + HAVE_EPOLL_TRUE='#' + HAVE_EPOLL_FALSE= +fi + + if test "x$ac_cv_func_poll" = xyes; then + HAVE_POLL_TRUE= + HAVE_POLL_FALSE='#' +else + HAVE_POLL_TRUE='#' + HAVE_POLL_FALSE= +fi + + if test "x$ac_cv_func_kqueue" = xyes; then + HAVE_KQUEUE_TRUE= + HAVE_KQUEUE_FALSE='#' +else + HAVE_KQUEUE_TRUE='#' + HAVE_KQUEUE_FALSE= +fi + + ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy" if test "x$ac_cv_func_strlcpy" = xyes; then : @@ -17894,9 +18226,6 @@ fi ## local defines PACKAGE_FEATURES="" -if test x$ac_cv_func_timerfd_create = xyes; then - PACKAGE_FEATURES="$PACKAGE_FEATURES timerfd" -fi if test x$ac_cv_func_epoll_create = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES epoll" fi @@ -17986,9 +18315,6 @@ fi # OS detection # THIS SECTION MUST DIE! CP=cp -LIB_RT=-lrt -supports_sysv_mq="yes" -supports_posix_mq="yes" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for os in ${host_os}" >&5 $as_echo_n "checking for os in ${host_os}... " >&6; } case "$host_os" in @@ -18000,6 +18326,18 @@ _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: result: Linux" >&5 $as_echo "Linux" >&6; } + ;; + *cygwin*) + +cat >>confdefs.h <<_ACEOF +#define QB_CYGWIN 1 +_ACEOF + + ac_cv_link_attribute_section=no + nongcc_memory_barrier_needed=yes + gcc_has_builtin_atomic_operations=no + { $as_echo "$as_me:${as_lineno-$LINENO}: result: Cygwin" >&5 +$as_echo "Cygwin" >&6; } ;; darwin*) @@ -18008,26 +18346,8 @@ cat >>confdefs.h <<_ACEOF _ACEOF CP=rsync - LIB_RT= - supports_sysv_mq="no" - supports_posix_mq="no" ac_cv_link_attribute_section=no -cat >>confdefs.h <<_ACEOF -#define MAP_ANONYMOUS MAP_ANON -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define PATH_MAX 4096 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define NAME_MAX 255 -_ACEOF - - cat >>confdefs.h <<_ACEOF #define DISABLE_POSIX_THREAD_PROCESS_SHARED 1 _ACEOF @@ -18041,11 +18361,6 @@ cat >>confdefs.h <<_ACEOF #define QB_BSD 1 _ACEOF - -cat >>confdefs.h <<_ACEOF -#define MAP_ANONYMOUS MAP_ANON -_ACEOF - case "$host_os" in *freebsd[234567]*) ;; @@ -18053,6 +18368,23 @@ _ACEOF cat >>confdefs.h <<_ACEOF #define QB_FREEBSD_GE_8 1 +_ACEOF + + ;; + *netbsd*) + # this is because dlopen within a dl_iterate_phdr + # callback locks up. + ac_cv_link_attribute_section=no + +cat >>confdefs.h <<_ACEOF +#define UNIX_PATH_MAX 103 +_ACEOF + + ;; + *openbsd*) + +cat >>confdefs.h <<_ACEOF +#define UNIX_PATH_MAX 104 _ACEOF ;; @@ -18061,21 +18393,17 @@ _ACEOF $as_echo "BSD" >&6; } ;; *solaris*) + ac_cv_link_attribute_section=no + +cat >>confdefs.h <<_ACEOF +#define DISABLE_IPC_SHM 1 +_ACEOF + cat >>confdefs.h <<_ACEOF #define QB_SOLARIS 1 _ACEOF - -cat >>confdefs.h <<_ACEOF -#define TS_CLASS 1 -_ACEOF - - -cat >>confdefs.h <<_ACEOF -#define _SEM_SEMUN_UNDEFINED 1 -_ACEOF - CP=rsync { $as_echo "$as_me:${as_lineno-$LINENO}: result: Solaris" >&5 $as_echo "Solaris" >&6; } @@ -18209,7 +18537,6 @@ fi - # *FLAGS handling goes here ENV_CFLAGS="$CFLAGS" @@ -18293,46 +18620,6 @@ else fi -if test -n "$ac_cv_supports_sysv_mq"; then - supports_sysv_mq=$ac_cv_supports_sysv_mq -fi -if test "x${supports_sysv_mq}" = xyes ; then - -$as_echo "#define HAVE_SYSV_MQ 1" >>confdefs.h - - PACKAGE_FEATURES="$PACKAGE_FEATURES sysv_mq" - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling SYSV Message Queues" >&5 -$as_echo "$as_me: Enabling SYSV Message Queues" >&6;} -fi - if test "x${supports_sysv_mq}" = xyes; then - HAVE_SYSV_MQ_TRUE= - HAVE_SYSV_MQ_FALSE='#' -else - HAVE_SYSV_MQ_TRUE='#' - HAVE_SYSV_MQ_FALSE= -fi - - -if test -n "$ac_cv_supports_posix_mq"; then - supports_posix_mq=$ac_cv_supports_posix_mq -fi -if test "x${supports_posix_mq}" = xyes ; then - -$as_echo "#define HAVE_POSIX_MQ 1" >>confdefs.h - - PACKAGE_FEATURES="$PACKAGE_FEATURES posix_mq" - { $as_echo "$as_me:${as_lineno-$LINENO}: Enabling POSIX Message Queues" >&5 -$as_echo "$as_me: Enabling POSIX Message Queues" >&6;} -fi - if test "x${supports_posix_mq}" = xyes; then - HAVE_POSIX_MQ_TRUE= - HAVE_POSIX_MQ_FALSE='#' -else - HAVE_POSIX_MQ_TRUE='#' - HAVE_POSIX_MQ_FALSE= -fi - - # --- callsite sections --- if test "x${GCC}" = xyes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC supports __attribute__((section())" >&5 @@ -18436,7 +18723,7 @@ cat >>confdefs.h <<_ACEOF _ACEOF -ac_config_files="$ac_config_files Makefile include/Makefile include/qb/Makefile lib/Makefile lib/libqb.pc tests/Makefile examples/Makefile docs/Makefile docs/man.dox docs/html.dox" +ac_config_files="$ac_config_files Makefile include/Makefile include/qb/Makefile lib/Makefile lib/libqb.pc tools/Makefile tests/Makefile examples/Makefile docs/Makefile docs/man.dox docs/html.dox" cat >confcache <<\_ACEOF @@ -18548,14 +18835,6 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18564,14 +18843,18 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi + if test -n "$EXEEXT"; then + am__EXEEXT_TRUE= + am__EXEEXT_FALSE='#' +else + am__EXEEXT_TRUE='#' + am__EXEEXT_FALSE= +fi + if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18588,6 +18871,22 @@ if test -z "${HAVE_GLIB_TRUE}" && test -z "${HAVE_GLIB_FALSE}"; then as_fn_error $? "conditional \"HAVE_GLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${HAVE_SEM_TIMEDWAIT_TRUE}" && test -z "${HAVE_SEM_TIMEDWAIT_FALSE}"; then + as_fn_error $? "conditional \"HAVE_SEM_TIMEDWAIT\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_EPOLL_TRUE}" && test -z "${HAVE_EPOLL_FALSE}"; then + as_fn_error $? "conditional \"HAVE_EPOLL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_POLL_TRUE}" && test -z "${HAVE_POLL_FALSE}"; then + as_fn_error $? "conditional \"HAVE_POLL\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi +if test -z "${HAVE_KQUEUE_TRUE}" && test -z "${HAVE_KQUEUE_FALSE}"; then + as_fn_error $? "conditional \"HAVE_KQUEUE\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS_TRUE}" && test -z "${HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS_FALSE}"; then as_fn_error $? "conditional \"HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -18596,14 +18895,6 @@ if test -z "${HAVE_SLOW_TESTS_TRUE}" && test -z "${HAVE_SLOW_TESTS_FALSE}"; then as_fn_error $? "conditional \"HAVE_SLOW_TESTS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${HAVE_SYSV_MQ_TRUE}" && test -z "${HAVE_SYSV_MQ_FALSE}"; then - as_fn_error $? "conditional \"HAVE_SYSV_MQ\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${HAVE_POSIX_MQ_TRUE}" && test -z "${HAVE_POSIX_MQ_FALSE}"; then - as_fn_error $? "conditional \"HAVE_POSIX_MQ\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${HAVE_DICT_WORDS_TRUE}" && test -z "${HAVE_DICT_WORDS_FALSE}"; then as_fn_error $? "conditional \"HAVE_DICT_WORDS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -19017,7 +19308,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by libqb $as_me 0.11.1, which was +This file was extended by libqb $as_me 0.14.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -19083,7 +19374,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -libqb config.status 0.11.1 +libqb config.status 0.14.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" @@ -19596,6 +19887,7 @@ do "include/qb/Makefile") CONFIG_FILES="$CONFIG_FILES include/qb/Makefile" ;; "lib/Makefile") CONFIG_FILES="$CONFIG_FILES lib/Makefile" ;; "lib/libqb.pc") CONFIG_FILES="$CONFIG_FILES lib/libqb.pc" ;; + "tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; diff --git a/configure.ac b/configure.ac index 2ff9fb8..af19e22 100644 --- a/configure.ac +++ b/configure.ac @@ -6,11 +6,14 @@ AC_PREREQ([2.61]) AC_INIT([libqb], m4_esyscmd([build-aux/git-version-gen .tarball-version]), [quarterback-devel@fedorahosted.org]) +AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_SRCDIR([lib/ringbuffer.c]) AC_CONFIG_HEADERS([include/config.h include/qb/qbconfig.h]) -AM_INIT_AUTOMAKE([-Wno-portability dist-xz color-tests parallel-tests]) +AC_USE_SYSTEM_EXTENSIONS + +AM_INIT_AUTOMAKE([-Wno-portability dist-xz]) dnl automake >= 1.11 offers --enable-silent-rules for suppressing the output from -dnl normal compilation. When a failure occurs, it will then display the full +dnl normal compilation. When a failure occurs, it will then display the full dnl command line dnl Wrap in m4_ifdef to avoid breaking on older platforms m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) @@ -18,6 +21,7 @@ LT_PREREQ([2.2.6]) LT_INIT AC_CONFIG_MACRO_DIR([m4]) + AC_CANONICAL_HOST AC_PROG_LIBTOOL AC_LANG([C]) @@ -73,11 +77,13 @@ AM_CONDITIONAL(HAVE_SPLINT, test -n "${SPLINT}") # this function checks if CC support options passed as # args. Global CFLAGS are ignored during this test. cc_supports_flag() { - local CPPFLAGS="$CPPFLAGS $@" + BACKUP="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $@" AC_MSG_CHECKING([whether $CC supports "$@"]) AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])], [RC=0; AC_MSG_RESULT([yes])], [RC=1; AC_MSG_RESULT([no])]) + CPPFLAGS="$BACKUP" return $RC } @@ -94,10 +100,15 @@ case $exec_prefix in esac # Checks for libraries. -AC_CHECK_LIB([rt], [mq_open]) -AC_CHECK_LIB([dl], [dlopen]) -AC_CHECK_LIB([pthread], [pthread_create]) -AC_CHECK_LIB([socket], [socket]) +dnl librt from glibc NEEDs libpthread +dnl so. if test for libpthread after librt +dnl it will always be "none needed", but it is not true +dnl when linking libraries. Looks like a bug. +AC_SEARCH_LIBS([pthread_create], [pthread]) +AC_SEARCH_LIBS([mq_open], [rt]) +AC_SEARCH_LIBS([dlopen], [dl]) +AC_SEARCH_LIBS([socket], [socket]) +AC_SEARCH_LIBS([gethostbyname], [nsl]) # look for testing harness "check" PKG_CHECK_MODULES([CHECK], [check >= 0.9.4],[with_check=yes],[with_check=no]) @@ -116,11 +127,13 @@ fi AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h stdint.h \ - dlfcn.h time.h sys/time.h stdlib.h string.h strings.h sys/types.h sys/stat.h \ - sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h sys/uio.h \ - sys/sockio.h sys/un.h sys/resource.h syslog.h errno.h unistd.h sys/mman.h \ - sys/sem.h sys/ipc.h sys/msg.h mqueue.h]) +AC_CHECK_HEADERS([arpa/inet.h link.h fcntl.h inttypes.h limits.h netinet/in.h \ + stdint.h stddef.h stdlib.h string.h strings.h \ + dlfcn.h time.h sys/time.h sys/types.h sys/stat.h \ + sys/param.h sys/socket.h sys/time.h sys/poll.h sys/epoll.h \ + sys/uio.h sys/event.h sys/sockio.h sys/un.h sys/resource.h \ + syslog.h errno.h unistd.h sys/mman.h \ + sys/sem.h sys/ipc.h sys/msg.h netdb.h]) # Checks for typedefs, structures, and compiler characteristics. AC_TYPE_UID_T @@ -132,19 +145,59 @@ AC_TYPE_MODE_T AC_TYPE_PID_T AC_TYPE_SIZE_T AC_TYPE_SSIZE_T -AC_TYPE_UINT32_T AC_TYPE_UINT64_T +AC_TYPE_UINT32_T +AC_TYPE_UINT16_T AC_TYPE_UINT8_T +AC_CHECK_MEMBER([struct sockaddr_un.sun_len], + [AC_DEFINE([HAVE_STRUCT_SOCKADDR_UN_SUN_LEN], + 1, + [Define to 1 if struct sockaddr_un has a member sun_len])], + [], + [#include ]) + +AC_MSG_CHECKING(looking for union semun in sys/sem.h) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM( +[[#include + #include + #include ]], +[[union semun arg; semctl(0, 0, 0, arg);]])], + [ + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED([HAVE_SEMUN], 1, [Define to 1 if you have union semun.]) + ], + [ + AC_MSG_RESULT([no]) + ] + ) + + # Checks for library functions. AC_FUNC_CHOWN AC_FUNC_FORK AC_FUNC_MMAP -AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday localtime localtime_r \ - memset munmap socket strchr strrchr strdup strerror strstr \ - poll epoll_create epoll_create1 random rand getrlimit sysconf \ +AC_FUNC_STRERROR_R +AC_CHECK_FUNCS([alarm clock_gettime ftruncate gettimeofday \ + localtime localtime_r memset munmap socket \ + strchr strrchr strdup strstr strcasecmp \ + poll epoll_create epoll_create1 kqueue \ + random rand getrlimit sysconf \ pthread_spin_lock pthread_setschedparam \ - sched_get_priority_max sched_setscheduler]) + pthread_mutexattr_setpshared \ + pthread_condattr_setpshared \ + sem_timedwait semtimedop \ + sched_get_priority_max sched_setscheduler \ + getpeerucred getpeereid]) + +AM_CONDITIONAL(HAVE_SEM_TIMEDWAIT, + [test "x$ac_cv_func_sem_timedwait" = xyes]) +AM_CONDITIONAL(HAVE_EPOLL, + [test "x$ac_cv_func_epoll_create" = xyes]) +AM_CONDITIONAL(HAVE_POLL, + [test "x$ac_cv_func_poll" = xyes]) +AM_CONDITIONAL(HAVE_KQUEUE, + [test "x$ac_cv_func_kqueue" = xyes]) AC_CONFIG_LIBOBJ_DIR(lib) AC_REPLACE_FUNCS(strlcpy strlcat strchrnul) @@ -152,9 +205,6 @@ AC_REPLACE_FUNCS(strlcpy strlcat strchrnul) ## local defines PACKAGE_FEATURES="" -if test x$ac_cv_func_timerfd_create = xyes; then - PACKAGE_FEATURES="$PACKAGE_FEATURES timerfd" -fi if test x$ac_cv_func_epoll_create = xyes; then PACKAGE_FEATURES="$PACKAGE_FEATURES epoll" fi @@ -209,9 +259,6 @@ fi # OS detection # THIS SECTION MUST DIE! CP=cp -LIB_RT=-lrt -supports_sysv_mq="yes" -supports_posix_mq="yes" AC_MSG_CHECKING([for os in ${host_os}]) case "$host_os" in *linux*) @@ -219,22 +266,24 @@ case "$host_os" in [Compiling for Linux platform]) AC_MSG_RESULT([Linux]) ;; + *cygwin*) + AC_DEFINE_UNQUOTED([QB_CYGWIN], [1], + [Compiling for Cygwin platform]) + ac_cv_link_attribute_section=no + nongcc_memory_barrier_needed=yes + gcc_has_builtin_atomic_operations=no + AC_MSG_RESULT([Cygwin]) + ;; darwin*) AC_DEFINE_UNQUOTED([QB_DARWIN], [1], [Compiling for Darwin platform]) CP=rsync - LIB_RT= - supports_sysv_mq="no" - supports_posix_mq="no" ac_cv_link_attribute_section=no dnl Attribute section appears to work here but fails later with: - dnl cc1: error in backend: Global variable 'descriptor.4902' has an invalid section specifier '__verbose': mach-o section specifier requires a segment and section separated by a comma - AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON], - [Shared memory define for Darwin platform]) - AC_DEFINE_UNQUOTED([PATH_MAX], [4096], - [Number of chars in a path name including nul]) - AC_DEFINE_UNQUOTED([NAME_MAX], [255], - [Number of chars in a file name]) + dnl cc1: error in backend: Global variable 'descriptor.4902' + dnl has an invalid section specifier '__verbose': mach-o + dnl section specifier requires a segment and section + dnl separated by a comma AC_DEFINE_UNQUOTED([DISABLE_POSIX_THREAD_PROCESS_SHARED], [1], [Disable _POSIX_THREAD_PROCESS_SHARED]) AC_MSG_RESULT([Dawin]) @@ -242,8 +291,6 @@ case "$host_os" in *bsd*) AC_DEFINE_UNQUOTED([QB_BSD], [1], [Compiling for BSD platform]) - AC_DEFINE_UNQUOTED([MAP_ANONYMOUS], [MAP_ANON], - [Shared memory define for Darwin platform]) case "$host_os" in *freebsd[[234567]]*) ;; @@ -251,16 +298,26 @@ case "$host_os" in AC_DEFINE_UNQUOTED([QB_FREEBSD_GE_8], [1], [Compiling for FreeBSD >= 8 platform]) ;; + *netbsd*) + # this is because dlopen within a dl_iterate_phdr + # callback locks up. + ac_cv_link_attribute_section=no + AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], [103], + [Unix path length]) + ;; + *openbsd*) + AC_DEFINE_UNQUOTED([UNIX_PATH_MAX], [104], + [Unix path length]) + ;; esac AC_MSG_RESULT([BSD]) ;; *solaris*) + ac_cv_link_attribute_section=no + AC_DEFINE_UNQUOTED(DISABLE_IPC_SHM, 1, + [Disable shared mem ipc]) AC_DEFINE_UNQUOTED([QB_SOLARIS], [1], [Compiling for Solaris platform]) - AC_DEFINE_UNQUOTED([TS_CLASS], [1], - [Prevent being scheduled RR]) - AC_DEFINE_UNQUOTED([_SEM_SEMUN_UNDEFINED], [1], - [The semun structure is undefined]) CP=rsync AC_MSG_RESULT([Solaris]) ;; @@ -345,7 +402,6 @@ AC_ARG_WITH([socket-dir], [ SOCKETDIR="$localstatedir/run" ]) AC_SUBST(CP) -AC_SUBST(LIB_RT) # *FLAGS handling goes here ENV_CFLAGS="$CFLAGS" @@ -414,28 +470,6 @@ if test "x${enable_slow_tests}" = xyes ; then fi AM_CONDITIONAL(HAVE_SLOW_TESTS, [test "x${enable_slow_tests}" = xyes]) -if test -n "$ac_cv_supports_sysv_mq"; then - supports_sysv_mq=$ac_cv_supports_sysv_mq -fi -if test "x${supports_sysv_mq}" = xyes ; then - AC_DEFINE([HAVE_SYSV_MQ], [1], - [have sysv message queues]) - PACKAGE_FEATURES="$PACKAGE_FEATURES sysv_mq" - AC_MSG_NOTICE([Enabling SYSV Message Queues]) -fi -AM_CONDITIONAL(HAVE_SYSV_MQ, [test "x${supports_sysv_mq}" = xyes]) - -if test -n "$ac_cv_supports_posix_mq"; then - supports_posix_mq=$ac_cv_supports_posix_mq -fi -if test "x${supports_posix_mq}" = xyes ; then - AC_DEFINE([HAVE_POSIX_MQ], [1], - [have posix message queues]) - PACKAGE_FEATURES="$PACKAGE_FEATURES posix_mq" - AC_MSG_NOTICE([Enabling POSIX Message Queues]) -fi -AM_CONDITIONAL(HAVE_POSIX_MQ, [test "x${supports_posix_mq}" = xyes]) - # --- callsite sections --- if test "x${GCC}" = xyes; then AC_MSG_CHECKING([whether GCC supports __attribute__((section())]) @@ -504,6 +538,7 @@ AC_CONFIG_FILES([Makefile include/qb/Makefile lib/Makefile lib/libqb.pc + tools/Makefile tests/Makefile examples/Makefile docs/Makefile diff --git a/docs/Makefile.am b/docs/Makefile.am index 257ddd4..9e5439c 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -27,7 +27,7 @@ dependant_headers = $(wildcard $(inc_dir)/qb*.h) dist_man_MANS = man3/qbipcc.h.3 man3/qbipcs.h.3 man3/qbatomic.h.3 \ man3/qbhdb.h.3 man3/qbipc_common.h.3 man3/qblist.h.3 \ man3/qbloop.h.3 man3/qbutil.h.3 man3/qbarray.h.3 \ - man3/qblog.h.3 man3/qbmap.h.3 + man3/qblog.h.3 man3/qbmap.h.3 man8/qb-blackbox.8 $(dist_man_MANS): man.dox $(dependant_headers) diff --git a/docs/Makefile.in b/docs/Makefile.in index cdc5eb3..93b4b8e 100644 --- a/docs/Makefile.in +++ b/docs/Makefile.in @@ -105,7 +105,8 @@ am__uninstall_files_from_dir = { \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man3dir = $(mandir)/man3 -am__installdirs = "$(DESTDIR)$(man3dir)" +am__installdirs = "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)" +man8dir = $(mandir)/man8 NROFF = nroff MANS = $(dist_man_MANS) HEADERS = $(noinst_HEADERS) @@ -158,7 +159,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -253,7 +253,7 @@ noinst_HEADERS = mainpage.h @HAVE_DOXYGEN_TRUE@dist_man_MANS = man3/qbipcc.h.3 man3/qbipcs.h.3 man3/qbatomic.h.3 \ @HAVE_DOXYGEN_TRUE@ man3/qbhdb.h.3 man3/qbipc_common.h.3 man3/qblist.h.3 \ @HAVE_DOXYGEN_TRUE@ man3/qbloop.h.3 man3/qbutil.h.3 man3/qbarray.h.3 \ -@HAVE_DOXYGEN_TRUE@ man3/qblog.h.3 man3/qbmap.h.3 +@HAVE_DOXYGEN_TRUE@ man3/qblog.h.3 man3/qbmap.h.3 man8/qb-blackbox.8 all: all-am @@ -334,6 +334,42 @@ uninstall-man3: } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +install-man8: $(dist_man_MANS) + @$(NORMAL_INSTALL) + test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)" + @list=''; test -n "$(man8dir)" || exit 0; \ + { for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \ + done; } + +uninstall-man8: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man8dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.8[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir) ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ @@ -434,7 +470,7 @@ check-am: all-am check: check-am all-am: Makefile $(MANS) $(HEADERS) installdirs: - for dir in "$(DESTDIR)$(man3dir)"; do \ + for dir in "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -502,7 +538,7 @@ install-info: install-info-am install-info-am: -install-man: install-man3 +install-man: install-man3 install-man8 install-pdf: install-pdf-am @@ -532,7 +568,7 @@ ps-am: uninstall-am: uninstall-man -uninstall-man: uninstall-man3 +uninstall-man: uninstall-man3 uninstall-man8 .MAKE: install-am install-strip @@ -542,12 +578,13 @@ uninstall-man: uninstall-man3 html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-man3 install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ - uninstall-am uninstall-man uninstall-man3 + install-info-am install-man install-man3 install-man8 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-man uninstall-man3 \ + uninstall-man8 @HAVE_DOXYGEN_TRUE@$(dist_man_MANS): man.dox $(dependant_headers) diff --git a/docs/html.dox b/docs/html.dox index 3b349d6..fe29a4a 100644 --- a/docs/html.dox +++ b/docs/html.dox @@ -1,6 +1,6 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = libqb -PROJECT_NUMBER = 0.11.1 +PROJECT_NUMBER = 0.14.2 OUTPUT_DIRECTORY = . CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English @@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = diff --git a/docs/html.dox.in b/docs/html.dox.in index dbad148..abeef17 100644 --- a/docs/html.dox.in +++ b/docs/html.dox.in @@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = diff --git a/docs/mainpage.h b/docs/mainpage.h index 761b383..6a6761d 100644 --- a/docs/mainpage.h +++ b/docs/mainpage.h @@ -3,11 +3,13 @@ * * @section overview Overview * - * libqb is a thread-safe library with the primary purpose of providing high performance client server reusable features. + * libqb is a thread-safe library with the primary purpose of providing high + * performance client server reusable features. * * It provides high performance ipc, and poll. * - * We don't intend be an all encompassing library, but instead provide very specially focused APIs that are highly + * We don't intend be an all encompassing library, but instead provide very + * specially focused APIs that are highly * * tuned for maximum performance for client/server applications. * @@ -74,8 +76,6 @@ * and service applications. It supports many features including: * - Multiple transport implementations * -# Shared memory implementation for very high performance. - * -# Posix Message queues - * -# SysV Message queues * -# Unix sockets * - A synchronous request/response channel and asynchronous response channel per ipc connection. * - User defined private data per IPC connection. diff --git a/docs/man.dox b/docs/man.dox index a5e3331..cdd001b 100644 --- a/docs/man.dox +++ b/docs/man.dox @@ -1,6 +1,6 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = libqb -PROJECT_NUMBER = 0.11.1 +PROJECT_NUMBER = 0.14.2 OUTPUT_DIRECTORY = . CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English @@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = diff --git a/docs/man.dox.in b/docs/man.dox.in index b169adc..f88e216 100644 --- a/docs/man.dox.in +++ b/docs/man.dox.in @@ -60,7 +60,6 @@ GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = diff --git a/docs/man3/qbarray.h.3 b/docs/man3/qbarray.h.3 index 52fa873..faa09f4 100644 --- a/docs/man3/qbarray.h.3 +++ b/docs/man3/qbarray.h.3 @@ -1,4 +1,4 @@ -.TH "qbarray.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbarray.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -62,13 +62,13 @@ This is a dynamic array (it can grow, but without moving memory)\&. .PP .nf - arr = qb_array_create_2(64, sizeof(struct my_struct), 256); - \&.\&.\&. - res = qb_array_index(arr, idx, (void**)&my_ptr); - if (res < 0) { + arr = qb_array_create_2(64, sizeof(struct my_struct), 256); + \&.\&.\&. + res = qb_array_index(arr, idx, (void**)&my_ptr); + if (res < 0) { return res; - } - // use my_ptr, now even if there is a grow, this pointer will be valid\&. + } + // use my_ptr, now even if there is a grow, this pointer will be valid\&. .fi .PP @@ -80,7 +80,7 @@ This is a dynamic array (it can grow, but without moving memory)\&. This is an opaque data type representing an instance of an array\&. .SH "Function Documentation" .PP -.SS "\fBqb_array_t\fP* \fBqb_array_create\fP (size_tmax_elements, size_telement_size)" +.SS "\fBqb_array_t\fP* qb_array_create (size_tmax_elements, size_telement_size)" .PP Create an array with fixed sized elements\&. \fBParameters:\fP @@ -96,7 +96,7 @@ array instance\&. .RE .PP -.SS "\fBqb_array_t\fP* \fBqb_array_create_2\fP (size_tmax_elements, size_telement_size, size_tautogrow_elements)" +.SS "\fBqb_array_t\fP* qb_array_create_2 (size_tmax_elements, size_telement_size, size_tautogrow_elements)" .PP Create an array with fixed sized elements\&. \fBParameters:\fP @@ -114,11 +114,11 @@ array instance\&. .RE .PP -.SS "size_t \fBqb_array_elems_per_bin_get\fP (\fBqb_array_t\fP *a)" +.SS "size_t qb_array_elems_per_bin_get (\fBqb_array_t\fP *a)" .PP Get the number of elements per bin\&. -.SS "void \fBqb_array_free\fP (\fBqb_array_t\fP *a)" +.SS "void qb_array_free (\fBqb_array_t\fP *a)" .PP Free all the memory used by the array\&. \fBParameters:\fP @@ -127,7 +127,7 @@ Free all the memory used by the array\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_array_grow\fP (\fBqb_array_t\fP *a, size_tmax_elements)" +.SS "int32_t qb_array_grow (\fBqb_array_t\fP *a, size_tmax_elements)" .PP Grow the array\&. \fBParameters:\fP @@ -143,7 +143,7 @@ Grow the array\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_array_index\fP (\fBqb_array_t\fP *a, int32_tidx, void **element_out)" +.SS "int32_t qb_array_index (\fBqb_array_t\fP *a, int32_tidx, void **element_out)" .PP Get an element at a particular index\&. \fBParameters:\fP @@ -161,7 +161,7 @@ Get an element at a particular index\&. \fBParameters:\fP .RE .PP -.SS "size_t \fBqb_array_num_bins_get\fP (\fBqb_array_t\fP *a)" +.SS "size_t qb_array_num_bins_get (\fBqb_array_t\fP *a)" .PP Get the number of bins used or the array\&. diff --git a/docs/man3/qbatomic.h.3 b/docs/man3/qbatomic.h.3 index d89e232..162605c 100644 --- a/docs/man3/qbatomic.h.3 +++ b/docs/man3/qbatomic.h.3 @@ -1,4 +1,4 @@ -.TH "qbatomic.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbatomic.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -16,7 +16,7 @@ Basic atomic integer and pointer operations\&. \fC#include \fP .br -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -92,9 +92,9 @@ You must not directly read integers or pointers concurrently accessed by multipl If you are using those functions for anything apart from simple reference counting, you should really be aware of the implications of doing that\&. There are literally thousands of ways to shoot yourself in the foot\&. So if in doubt, use a pthread_mutex\&. If you don't know, what memory barriers are, do not use anything but \fBqb_atomic_int_inc()\fP and \fBqb_atomic_int_dec_and_test()\fP\&. .PP It is not safe to set an integer or pointer just by assigning to it, when it is concurrently accessed by other threads with the following functions\&. Use \fBqb_atomic_int_compare_and_exchange()\fP or \fBqb_atomic_pointer_compare_and_exchange()\fP respectively\&. -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBqb_atomic_int_dec_and_test\fP(atomic) (\fBqb_atomic_int_exchange_and_add\fP ((atomic), -1) == 1)" +.SS "#define qb_atomic_int_dec_and_test(atomic) (\fBqb_atomic_int_exchange_and_add\fP ((atomic), -1) == 1)" .PP Atomically decrements the integer pointed to by atomic by 1\&. \fBParameters:\fP @@ -108,14 +108,14 @@ QB_TRUE if the integer pointed to by atomic is 0 after decrementing it .RE .PP -.SS "#define \fBqb_atomic_int_get\fP(atomic)" +.SS "#define qb_atomic_int_get(atomic)" \fBValue:\fP .PP .nf ((void) sizeof (char* [sizeof (*(atomic)) == sizeof (int32_t) ? 1 : -1]), \ (qb_atomic_int_get) ((volatile int32_t QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic))) .fi -.SS "#define \fBqb_atomic_int_inc\fP(atomic) (\fBqb_atomic_int_add\fP ((atomic), 1))" +.SS "#define qb_atomic_int_inc(atomic) (\fBqb_atomic_int_add\fP ((atomic), 1))" .PP Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP @@ -124,21 +124,21 @@ Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_atomic_int_set\fP(atomic, newval)" +.SS "#define qb_atomic_int_set(atomic, newval)" \fBValue:\fP .PP .nf ((void) sizeof (char* [sizeof (*(atomic)) == sizeof (int32_t) ? 1 : -1]), \ (qb_atomic_int_set) ((volatile int32_t QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval))) .fi -.SS "#define \fBqb_atomic_pointer_get\fP(atomic)" +.SS "#define qb_atomic_pointer_get(atomic)" \fBValue:\fP .PP .nf ((void) sizeof (char* [sizeof (*(atomic)) == sizeof (void*) ? 1 : -1]), \ (qb_atomic_pointer_get) ((volatile void* QB_GNUC_MAY_ALIAS *) (volatile void *) (atomic))) .fi -.SS "#define \fBqb_atomic_pointer_set\fP(atomic, newval)" +.SS "#define qb_atomic_pointer_set(atomic, newval)" \fBValue:\fP .PP .nf @@ -147,9 +147,9 @@ Atomically increments the integer pointed to by atomic by 1\&. \fBParameters:\fP .fi .SH "Function Documentation" .PP -.SS "void \fBqb_atomic_init\fP (void)" +.SS "void qb_atomic_init (void)" -.SS "void \fBqb_atomic_int_add\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)" +.SS "void qb_atomic_int_add (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)" .PP Atomically adds val to the integer pointed to by atomic\&. Also acts as a memory barrier\&. @@ -162,7 +162,7 @@ Atomically adds val to the integer pointed to by atomic\&. Also acts as a memory .RE .PP -.SS "int32_t \fBqb_atomic_int_compare_and_exchange\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_toldval, int32_tnewval)" +.SS "int32_t qb_atomic_int_compare_and_exchange (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_toldval, int32_tnewval)" .PP Compares oldval with the integer pointed to by atomic and if they are equal, atomically exchanges *atomic with newval\&. Also acts as a memory barrier\&. @@ -182,7 +182,7 @@ QB_TRUE, if *atomic was equal oldval\&. QB_FALSE otherwise\&. .RE .PP -.SS "int32_t \fBqb_atomic_int_exchange_and_add\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)" +.SS "int32_t qb_atomic_int_exchange_and_add (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tval)" .PP Atomically adds val to the integer pointed to by atomic\&. It returns the value of *atomic just before the addition took place\&. Also acts as a memory barrier\&. @@ -200,7 +200,7 @@ the value of *atomic before the addition\&. .RE .PP -.SS "int32_t \fBqb_atomic_int_get\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic)" +.SS "int32_t qb_atomic_int_get (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic)" .PP Reads the value of the integer pointed to by atomic\&. Also acts as a memory barrier\&. @@ -216,7 +216,7 @@ the value of atomic .RE .PP -.SS "void \fBqb_atomic_int_set\fP (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tnewval)" +.SS "void qb_atomic_int_set (volatile int32_t \fBQB_GNUC_MAY_ALIAS\fP *atomic, int32_tnewval)" .PP Sets the value of the integer pointed to by atomic\&. Also acts as a memory barrier\&. @@ -229,7 +229,7 @@ Sets the value of the integer pointed to by atomic\&. Also acts as a memory barr .RE .PP -.SS "int32_t \fBqb_atomic_pointer_compare_and_exchange\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *oldval, void *newval)" +.SS "int32_t qb_atomic_pointer_compare_and_exchange (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *oldval, void *newval)" .PP Compares oldval with the pointer pointed to by atomic and if they are equal, atomically exchanges *atomic with newval\&. Also acts as a memory barrier\&. @@ -249,7 +249,7 @@ QB_TRUE if atomic was equal oldval, else QB_FALSE\&. .RE .PP -.SS "void* \fBqb_atomic_pointer_get\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic)" +.SS "void* qb_atomic_pointer_get (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic)" .PP Reads the value of the pointer pointed to by atomic\&. Also acts as a memory barrier\&. @@ -265,7 +265,7 @@ the value to add to atomic\&. .RE .PP -.SS "void \fBqb_atomic_pointer_set\fP (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *newval)" +.SS "void qb_atomic_pointer_set (volatile void *\fBQB_GNUC_MAY_ALIAS\fP *atomic, void *newval)" .PP Sets the value of the pointer pointed to by atomic\&. Also acts as a memory barrier\&. diff --git a/docs/man3/qbhdb.h.3 b/docs/man3/qbhdb.h.3 index 9a4c527..a5a8024 100644 --- a/docs/man3/qbhdb.h.3 +++ b/docs/man3/qbhdb.h.3 @@ -1,4 +1,4 @@ -.TH "qbhdb.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbhdb.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -28,7 +28,7 @@ The handle database is for reference counting objects\&. .RI "struct \fBqb_hdb\fP" .br .in -1c -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -108,13 +108,13 @@ The handle database is for reference counting objects\&. The handle database is for reference counting objects\&. -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fB_GNU_SOURCE\fP" +.SS "#define _GNU_SOURCE" -.SS "#define \fBQB_HDB_D_FORMAT\fP '%'PRIu64" +.SS "#define QB_HDB_D_FORMAT '%'PRIu64" -.SS "#define \fBQB_HDB_DECLARE\fP(database_name, destructor_function)" +.SS "#define QB_HDB_DECLARE(database_name, destructor_function)" \fBValue:\fP .PP .nf @@ -129,11 +129,11 @@ static struct qb_hdb (database_name) = { \ .PP Convience macro for declaring a file scoped handle database\&. .PP .nf - QB_HDB_DECLARE(my_handle_database, NULL); + QB_HDB_DECLARE(my_handle_database, NULL); .fi .PP -.SS "#define \fBQB_HDB_X_FORMAT\fP '%'PRIx64" +.SS "#define QB_HDB_X_FORMAT '%'PRIx64" .SH "Typedef Documentation" .PP @@ -143,9 +143,9 @@ Convience macro for declaring a file scoped handle database\&. .PP Generic handle type is 64 bits\&. .SH "Function Documentation" .PP -.SS "uint32_t \fBqb_hdb_base_convert\fP (\fBqb_handle_t\fPhandle)" +.SS "uint32_t qb_hdb_base_convert (\fBqb_handle_t\fPhandle)" -.SS "void \fBqb_hdb_create\fP (struct \fBqb_hdb\fP *hdb)" +.SS "void qb_hdb_create (struct \fBqb_hdb\fP *hdb)" .PP Create a new database\&. \fBParameters:\fP @@ -154,7 +154,7 @@ Create a new database\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_hdb_destroy\fP (struct \fBqb_hdb\fP *hdb)" +.SS "void qb_hdb_destroy (struct \fBqb_hdb\fP *hdb)" .PP Destroy a handle database\&. \fBParameters:\fP @@ -163,7 +163,7 @@ Destroy a handle database\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_hdb_handle_create\fP (struct \fBqb_hdb\fP *hdb, int32_tinstance_size, \fBqb_handle_t\fP *handle_id_out)" +.SS "int32_t qb_hdb_handle_create (struct \fBqb_hdb\fP *hdb, int32_tinstance_size, \fBqb_handle_t\fP *handle_id_out)" .PP Create a new handle\&. \fBParameters:\fP @@ -181,7 +181,7 @@ Create a new handle\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_hdb_handle_destroy\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" +.SS "int32_t qb_hdb_handle_destroy (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" .PP Request the destruction of the object\&. When the refcount is 0, it will be destroyed\&. @@ -199,7 +199,7 @@ Request the destruction of the object\&. When the refcount is 0, it will be dest .RE .PP -.SS "int32_t \fBqb_hdb_handle_get\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)" +.SS "int32_t qb_hdb_handle_get (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)" .PP Get the instance associated with this handle and increase it's refcount\&. \fBParameters:\fP @@ -217,7 +217,7 @@ Get the instance associated with this handle and increase it's refcount\&. \fBPa .RE .PP -.SS "int32_t \fBqb_hdb_handle_get_always\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)" +.SS "int32_t qb_hdb_handle_get_always (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in, void **instance)" .PP Get the instance associated with this handle and increase it's refcount\&. \fBParameters:\fP @@ -235,7 +235,7 @@ Get the instance associated with this handle and increase it's refcount\&. \fBPa .RE .PP -.SS "int32_t \fBqb_hdb_handle_put\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" +.SS "int32_t qb_hdb_handle_put (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" .PP Put the instance associated with this handle and decrease it's refcount\&. \fBParameters:\fP @@ -251,7 +251,7 @@ Put the instance associated with this handle and decrease it's refcount\&. \fBPa .RE .PP -.SS "int32_t \fBqb_hdb_handle_refcount_get\fP (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" +.SS "int32_t qb_hdb_handle_refcount_get (struct \fBqb_hdb\fP *hdb, \fBqb_handle_t\fPhandle_in)" .PP Get the current refcount\&. \fBParameters:\fP @@ -267,7 +267,7 @@ Get the current refcount\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_hdb_iterator_next\fP (struct \fBqb_hdb\fP *hdb, void **instance, \fBqb_handle_t\fP *handle)" +.SS "int32_t qb_hdb_iterator_next (struct \fBqb_hdb\fP *hdb, void **instance, \fBqb_handle_t\fP *handle)" .PP Get the next object and increament it's refcount\&. Remember to call \fBqb_hdb_handle_put()\fP @@ -287,7 +287,7 @@ Get the next object and increament it's refcount\&. Remember to call \fBqb_hdb_h .RE .PP -.SS "void \fBqb_hdb_iterator_reset\fP (struct \fBqb_hdb\fP *hdb)" +.SS "void qb_hdb_iterator_reset (struct \fBqb_hdb\fP *hdb)" .PP Reset the iterator\&. \fBParameters:\fP @@ -296,7 +296,7 @@ Reset the iterator\&. \fBParameters:\fP .RE .PP -.SS "uint64_t \fBqb_hdb_nocheck_convert\fP (uint32_thandle)" +.SS "uint64_t qb_hdb_nocheck_convert (uint32_thandle)" .SH "Author" .PP diff --git a/docs/man3/qbipc_common.h.3 b/docs/man3/qbipc_common.h.3 index b7f5644..f116b88 100644 --- a/docs/man3/qbipc_common.h.3 +++ b/docs/man3/qbipc_common.h.3 @@ -1,4 +1,4 @@ -.TH "qbipc_common.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbipc_common.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -19,7 +19,7 @@ qbipc_common.h \- .RI "struct \fBqb_ipc_response_header\fP" .br .in -1c -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -42,7 +42,7 @@ qbipc_common.h \- .in +1c .ti -1c -.RI "enum \fBqb_ipc_type\fP { \fBQB_IPC_SOCKET\fP, \fBQB_IPC_SHM\fP, \fBQB_IPC_POSIX_MQ\fP, \fBQB_IPC_SYSV_MQ\fP }" +.RI "enum \fBqb_ipc_type\fP { \fBQB_IPC_SOCKET\fP, \fBQB_IPC_SHM\fP, \fBQB_IPC_POSIX_MQ\fP, \fBQB_IPC_SYSV_MQ\fP, \fBQB_IPC_NATIVE\fP }" .br .in -1c .SS "Functions" @@ -59,17 +59,17 @@ qbipc_common.h \- .RI "enum \fBqb_ipc_type\fP \fB__attribute__\fP" .br .in -1c -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBQB_IPC_MSG_AUTHENTICATE\fP -1" +.SS "#define QB_IPC_MSG_AUTHENTICATE -1" -.SS "#define \fBQB_IPC_MSG_DISCONNECT\fP -3" +.SS "#define QB_IPC_MSG_DISCONNECT -3" -.SS "#define \fBQB_IPC_MSG_NEW_EVENT_SOCK\fP -2" +.SS "#define QB_IPC_MSG_NEW_EVENT_SOCK -2" -.SS "#define \fBQB_IPC_MSG_NEW_MESSAGE\fP 0" +.SS "#define QB_IPC_MSG_NEW_MESSAGE 0" -.SS "#define \fBQB_IPC_MSG_USER_START\fP \fBQB_IPC_MSG_NEW_MESSAGE\fP" +.SS "#define QB_IPC_MSG_USER_START \fBQB_IPC_MSG_NEW_MESSAGE\fP" .SH "Enumeration Type Documentation" .PP @@ -86,14 +86,16 @@ qbipc_common.h \- \fB\fIQB_IPC_POSIX_MQ \fP\fP .TP \fB\fIQB_IPC_SYSV_MQ \fP\fP +.TP +\fB\fIQB_IPC_NATIVE \fP\fP .SH "Function Documentation" .PP -.SS "struct \fBqb_ipc_request_header\fP \fB__attribute__\fP ((aligned(8)))" +.SS "struct \fBqb_ipc_request_header\fP __attribute__ ((aligned(8)))" .SH "Variable Documentation" .PP -.SS "int32_t error \fB__attribute__\fP" +.SS "int32_t error __attribute__" .SH "Author" .PP diff --git a/docs/man3/qbipcc.h.3 b/docs/man3/qbipcc.h.3 index cff243b..92a34d0 100644 --- a/docs/man3/qbipcc.h.3 +++ b/docs/man3/qbipcc.h.3 @@ -1,4 +1,4 @@ -.TH "qbipcc.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbipcc.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -76,6 +76,10 @@ Client IPC API\&. .RI "void * \fBqb_ipcc_context_get\fP (\fBqb_ipcc_connection_t\fP *c)" .br .RI "\fIGet the context (set previously) \fP" +.ti -1c +.RI "int32_t \fBqb_ipcc_is_connected\fP (\fBqb_ipcc_connection_t\fP *c)" +.br +.RI "\fIIs the connection connected? \fP" .in -1c .SH "Detailed Description" .PP @@ -108,7 +112,7 @@ The \fBqb_ipcc_event_recv()\fP function receives an out-of-band asyncronous mess .SH "Function Documentation" .PP -.SS "\fBqb_ipcc_connection_t\fP* \fBqb_ipcc_connect\fP (const char *name, size_tmax_msg_size)" +.SS "\fBqb_ipcc_connection_t\fP* qb_ipcc_connect (const char *name, size_tmax_msg_size)" .PP Create a connection to an IPC service\&. \fBParameters:\fP @@ -124,7 +128,7 @@ NULL (error: see errno) or a connection object\&. .RE .PP -.SS "void* \fBqb_ipcc_context_get\fP (\fBqb_ipcc_connection_t\fP *c)" +.SS "void* qb_ipcc_context_get (\fBqb_ipcc_connection_t\fP *c)" .PP Get the context (set previously) \fBParameters:\fP @@ -143,7 +147,7 @@ the context .RE .PP -.SS "void \fBqb_ipcc_context_set\fP (\fBqb_ipcc_connection_t\fP *c, void *context)" +.SS "void qb_ipcc_context_set (\fBqb_ipcc_connection_t\fP *c, void *context)" .PP Associate a 'user' pointer with this connection\&. \fBParameters:\fP @@ -159,7 +163,7 @@ Associate a 'user' pointer with this connection\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcc_disconnect\fP (\fBqb_ipcc_connection_t\fP *c)" +.SS "void qb_ipcc_disconnect (\fBqb_ipcc_connection_t\fP *c)" .PP Disconnect an IPC connection\&. \fBParameters:\fP @@ -168,7 +172,7 @@ Disconnect an IPC connection\&. \fBParameters:\fP .RE .PP -.SS "ssize_t \fBqb_ipcc_event_recv\fP (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" +.SS "ssize_t qb_ipcc_event_recv (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" .PP Receive an event\&. \fBParameters:\fP @@ -186,11 +190,16 @@ Receive an event\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -size of the message or error (-errno) +size of the message or error (-errno) +.RE +.PP +\fBNote:\fP +.RS 4 +that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&. .RE .PP -.SS "int32_t \fBqb_ipcc_fc_enable_max_set\fP (\fBqb_ipcc_connection_t\fP *c, uint32_tmax)" +.SS "int32_t qb_ipcc_fc_enable_max_set (\fBqb_ipcc_connection_t\fP *c, uint32_tmax)" .PP Set the maximum allowable flowcontrol value\&. \fBNote:\fP @@ -206,7 +215,7 @@ the default is 1 .RE .PP -.SS "int32_t \fBqb_ipcc_fd_get\fP (\fBqb_ipcc_connection_t\fP *c, int32_t *fd)" +.SS "int32_t qb_ipcc_fd_get (\fBqb_ipcc_connection_t\fP *c, int32_t *fd)" .PP Get the file descriptor to poll\&. \fBParameters:\fP @@ -217,7 +226,23 @@ Get the file descriptor to poll\&. \fBParameters:\fP .RE .PP -.SS "ssize_t \fBqb_ipcc_recv\fP (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" +.SS "int32_t qb_ipcc_is_connected (\fBqb_ipcc_connection_t\fP *c)" + +.PP +Is the connection connected? \fBParameters:\fP +.RS 4 +\fIc\fP connection instance +.RE +.PP +\fBReturn values:\fP +.RS 4 +\fIQB_TRUE\fP when connected +.br +\fIQB_FALSE\fP when not connected +.RE +.PP + +.SS "ssize_t qb_ipcc_recv (\fBqb_ipcc_connection_t\fP *c, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" .PP Receive a response\&. \fBParameters:\fP @@ -233,11 +258,16 @@ Receive a response\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -(size recv'ed, -errno == error) +(size recv'ed, -errno == error) +.RE +.PP +\fBNote:\fP +.RS 4 +that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&. .RE .PP -.SS "ssize_t \fBqb_ipcc_send\fP (\fBqb_ipcc_connection_t\fP *c, const void *msg_ptr, size_tmsg_len)" +.SS "ssize_t qb_ipcc_send (\fBqb_ipcc_connection_t\fP *c, const void *msg_ptr, size_tmsg_len)" .PP Send a message\&. \fBParameters:\fP @@ -251,11 +281,16 @@ Send a message\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -(size sent, -errno == error) +(size sent, -errno == error) +.RE +.PP +\fBNote:\fP +.RS 4 +the msg_ptr must include a \fBqb_ipc_request_header\fP at the top of the message\&. The server will read the size field to determine how much to recv\&. .RE .PP -.SS "ssize_t \fBqb_ipcc_sendv\fP (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" +.SS "ssize_t qb_ipcc_sendv (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" .PP Send a message (iovec)\&. \fBParameters:\fP @@ -269,11 +304,16 @@ Send a message (iovec)\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -(size sent, -errno == error) +(size sent, -errno == error) +.RE +.PP +\fBNote:\fP +.RS 4 +the iov[0] must be a \fBqb_ipc_request_header\fP\&. The server will read the size field to determine how much to recv\&. .RE .PP -.SS "ssize_t \fBqb_ipcc_sendv_recv\fP (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, uint32_tiov_len, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" +.SS "ssize_t qb_ipcc_sendv_recv (\fBqb_ipcc_connection_t\fP *c, const struct iovec *iov, uint32_tiov_len, void *msg_ptr, size_tmsg_len, int32_tms_timeout)" .PP This is a convenience function that simply sends and then recvs\&. \fBParameters:\fP @@ -291,6 +331,13 @@ This is a convenience function that simply sends and then recvs\&. \fBParameters \fIms_timeout\fP max time to wait for a response .RE .PP +\fBNote:\fP +.RS 4 +the iov[0] must include a \fBqb_ipc_request_header\fP at the top of the message\&. The server will read the size field to determine how much to recv\&. +.PP +that msg_ptr will include a \fBqb_ipc_response_header\fP at the top of the message\&. +.RE +.PP \fBSee also:\fP .RS 4 \fBqb_ipcc_sendv()\fP \fBqb_ipcc_recv()\fP diff --git a/docs/man3/qbipcs.h.3 b/docs/man3/qbipcs.h.3 index 99a7dc1..a5f8c59 100644 --- a/docs/man3/qbipcs.h.3 +++ b/docs/man3/qbipcs.h.3 @@ -1,4 +1,4 @@ -.TH "qbipcs.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbipcs.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -30,6 +30,9 @@ Server IPC API\&. .RI "struct \fBqb_ipcs_connection_stats\fP" .br .ti -1c +.RI "struct \fBqb_ipcs_connection_stats_2\fP" +.br +.ti -1c .RI "struct \fBqb_ipcs_poll_handlers\fP" .br .ti -1c @@ -164,6 +167,10 @@ Server IPC API\&. .br .RI "\fIGet the connection statistics\&. \fP" .ti -1c +.RI "struct \fBqb_ipcs_connection_stats_2\fP * \fBqb_ipcs_connection_stats_get_2\fP (\fBqb_ipcs_connection_t\fP *c, int32_t clear_after_read)" +.br +.RI "\fIGet (and allocate) the connection statistics\&. \fP" +.ti -1c .RI "int32_t \fBqb_ipcs_stats_get\fP (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_t clear_after_read)" .br .RI "\fIGet the service statistics\&. \fP" @@ -175,6 +182,10 @@ Server IPC API\&. .RI "\fBqb_ipcs_connection_t\fP * \fBqb_ipcs_connection_next_get\fP (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)" .br .RI "\fIGet the next connection\&. \fP" +.ti -1c +.RI "void \fBqb_ipcs_connection_auth_set\fP (\fBqb_ipcs_connection_t\fP *conn, uid_t uid, gid_t gid, mode_t mode)" +.br +.RI "\fISet the permissions on and shared memory files so that both processes can read and write to them\&. \fP" .in -1c .SH "Detailed Description" .PP @@ -183,18 +194,23 @@ Server IPC API\&. .SH "Typedef Documentation" .PP -.SS "typedef int32_t(* \fBqb_ipcs_connection_accept_fn\fP)(\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)" +.SS "typedef int32_t(* qb_ipcs_connection_accept_fn)(\fBqb_ipcs_connection_t\fP *c, uid_t uid, gid_t gid)" .PP This callback is to check wether you want to accept a new connection\&. The type of checks you should do are authentication, service availabilty or process resource constraints\&. .PP \fBReturns:\fP .RS 4 -0 to accept or -errno to indicate a failure (sent back to the client) +0 to accept or -errno to indicate a failure (sent back to the client) +.RE +.PP +\fBNote:\fP +.RS 4 +you can call \fBqb_ipcs_connection_auth_set()\fP within this function\&. .RE .PP -.SS "typedef int32_t(* \fBqb_ipcs_connection_closed_fn\fP)(\fBqb_ipcs_connection_t\fP *c)" +.SS "typedef int32_t(* qb_ipcs_connection_closed_fn)(\fBqb_ipcs_connection_t\fP *c)" .PP This is called after a connection has been disconnected\&. \fBNote:\fP @@ -203,27 +219,27 @@ if you return anything but 0 this function will be repeativily called (until 0 i .RE .PP -.SS "typedef void(* \fBqb_ipcs_connection_created_fn\fP)(\fBqb_ipcs_connection_t\fP *c)" +.SS "typedef void(* qb_ipcs_connection_created_fn)(\fBqb_ipcs_connection_t\fP *c)" .PP This is called after a new connection has been created\&. -.SS "typedef void(* \fBqb_ipcs_connection_destroyed_fn\fP)(\fBqb_ipcs_connection_t\fP *c)" +.SS "typedef void(* qb_ipcs_connection_destroyed_fn)(\fBqb_ipcs_connection_t\fP *c)" .PP This is called just before a connection is freed\&. .SS "typedef struct qb_ipcs_connection \fBqb_ipcs_connection_t\fP" -.SS "typedef int32_t(* \fBqb_ipcs_dispatch_add_fn\fP)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" +.SS "typedef int32_t(* qb_ipcs_dispatch_add_fn)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" -.SS "typedef int32_t(* \fBqb_ipcs_dispatch_del_fn\fP)(int32_t fd)" +.SS "typedef int32_t(* qb_ipcs_dispatch_del_fn)(int32_t fd)" -.SS "typedef int32_t(* \fBqb_ipcs_dispatch_fn_t\fP)(int32_t fd, int32_t revents, void *data)" +.SS "typedef int32_t(* qb_ipcs_dispatch_fn_t)(int32_t fd, int32_t revents, void *data)" -.SS "typedef int32_t(* \fBqb_ipcs_dispatch_mod_fn\fP)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" +.SS "typedef int32_t(* qb_ipcs_dispatch_mod_fn)(enum \fBqb_loop_priority\fP p, int32_t fd, int32_t events, void *data, \fBqb_ipcs_dispatch_fn_t\fP fn)" -.SS "typedef int32_t(* \fBqb_ipcs_job_add_fn\fP)(enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)" +.SS "typedef int32_t(* qb_ipcs_job_add_fn)(enum \fBqb_loop_priority\fP p, void *data, \fBqb_loop_job_dispatch_fn\fP dispatch_fn)" -.SS "typedef int32_t(* \fBqb_ipcs_msg_process_fn\fP)(\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)" +.SS "typedef int32_t(* qb_ipcs_msg_process_fn)(\fBqb_ipcs_connection_t\fP *c, void *data, size_t size)" .PP This is the message processing calback\&. It is called with the message data\&. @@ -249,7 +265,32 @@ This is the message processing calback\&. It is called with the message data\&. .SH "Function Documentation" .PP -.SS "\fBqb_ipcs_connection_t\fP* \fBqb_ipcs_connection_first_get\fP (\fBqb_ipcs_service_t\fP *pt)" +.SS "void qb_ipcs_connection_auth_set (\fBqb_ipcs_connection_t\fP *conn, uid_tuid, gid_tgid, mode_tmode)" + +.PP +Set the permissions on and shared memory files so that both processes can read and write to them\&. \fBParameters:\fP +.RS 4 +\fIconn\fP connection instance +.br +\fIuid\fP the user id to set\&. +.br +\fIgid\fP the group id to set\&. +.br +\fImode\fP the mode to set\&. +.RE +.PP +\fBSee also:\fP +.RS 4 +chmod() chown() +.RE +.PP +\fBNote:\fP +.RS 4 +this must be called within the \fBqb_ipcs_connection_accept_fn()\fP callback\&. +.RE +.PP + +.SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_first_get (\fBqb_ipcs_service_t\fP *pt)" .PP Get the first connection\&. \fBNote:\fP @@ -268,7 +309,7 @@ first connection .RE .PP -.SS "\fBqb_ipcs_connection_t\fP* \fBqb_ipcs_connection_next_get\fP (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)" +.SS "\fBqb_ipcs_connection_t\fP* qb_ipcs_connection_next_get (\fBqb_ipcs_service_t\fP *pt, \fBqb_ipcs_connection_t\fP *current)" .PP Get the next connection\&. \fBNote:\fP @@ -289,7 +330,7 @@ next connection .RE .PP -.SS "void \fBqb_ipcs_connection_ref\fP (\fBqb_ipcs_connection_t\fP *c)" +.SS "void qb_ipcs_connection_ref (\fBqb_ipcs_connection_t\fP *c)" .PP Increment the connection's reference counter\&. \fBParameters:\fP @@ -298,10 +339,15 @@ Increment the connection's reference counter\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_ipcs_connection_stats_get\fP (\fBqb_ipcs_connection_t\fP *c, struct \fBqb_ipcs_connection_stats\fP *stats, int32_tclear_after_read)" +.SS "int32_t qb_ipcs_connection_stats_get (\fBqb_ipcs_connection_t\fP *c, struct \fBqb_ipcs_connection_stats\fP *stats, int32_tclear_after_read)" .PP -Get the connection statistics\&. \fBParameters:\fP +Get the connection statistics\&. \fBDeprecated\fP +.RS 4 +from v0\&.13\&.0 onwards, use qb_ipcs_connection_stats_get_2 +.RE +.PP +\fBParameters:\fP .RS 4 \fIstats\fP (out) the statistics structure .br @@ -316,7 +362,25 @@ Get the connection statistics\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcs_connection_unref\fP (\fBqb_ipcs_connection_t\fP *c)" +.SS "struct \fBqb_ipcs_connection_stats_2\fP* qb_ipcs_connection_stats_get_2 (\fBqb_ipcs_connection_t\fP *c, int32_tclear_after_read)\fC [read]\fP" + +.PP +Get (and allocate) the connection statistics\&. \fBParameters:\fP +.RS 4 +\fIclear_after_read\fP clear stats after copying them into stats +.br +\fIc\fP connection instance +.RE +.PP +\fBReturn values:\fP +.RS 4 +\fINULL\fP if no memory or invalid connection +.br +\fIallocated\fP statistics structure (user must free it)\&. +.RE +.PP + +.SS "void qb_ipcs_connection_unref (\fBqb_ipcs_connection_t\fP *c)" .PP Decrement the connection's reference counter\&. \fBParameters:\fP @@ -325,7 +389,7 @@ Decrement the connection's reference counter\&. \fBParameters:\fP .RE .PP -.SS "void* \fBqb_ipcs_context_get\fP (\fBqb_ipcs_connection_t\fP *c)" +.SS "void* qb_ipcs_context_get (\fBqb_ipcs_connection_t\fP *c)" .PP Get the context (set previously) \fBParameters:\fP @@ -344,7 +408,7 @@ the context .RE .PP -.SS "void \fBqb_ipcs_context_set\fP (\fBqb_ipcs_connection_t\fP *c, void *context)" +.SS "void qb_ipcs_context_set (\fBqb_ipcs_connection_t\fP *c, void *context)" .PP Associate a 'user' pointer with this connection\&. \fBParameters:\fP @@ -360,7 +424,7 @@ Associate a 'user' pointer with this connection\&. \fBParameters:\fP .RE .PP -.SS "\fBqb_ipcs_service_t\fP* \fBqb_ipcs_create\fP (const char *name, int32_tservice_id, enum \fBqb_ipc_type\fPtype, struct \fBqb_ipcs_service_handlers\fP *handlers)" +.SS "\fBqb_ipcs_service_t\fP* qb_ipcs_create (const char *name, int32_tservice_id, enum \fBqb_ipc_type\fPtype, struct \fBqb_ipcs_service_handlers\fP *handlers)" .PP Create a new IPC server\&. \fBParameters:\fP @@ -380,7 +444,7 @@ the new service instance\&. .RE .PP -.SS "void \fBqb_ipcs_destroy\fP (\fBqb_ipcs_service_t\fP *s)" +.SS "void qb_ipcs_destroy (\fBqb_ipcs_service_t\fP *s)" .PP Destroy the IPC server\&. \fBParameters:\fP @@ -389,7 +453,7 @@ Destroy the IPC server\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcs_disconnect\fP (\fBqb_ipcs_connection_t\fP *c)" +.SS "void qb_ipcs_disconnect (\fBqb_ipcs_connection_t\fP *c)" .PP Disconnect from this client\&. \fBParameters:\fP @@ -398,7 +462,7 @@ Disconnect from this client\&. \fBParameters:\fP .RE .PP -.SS "ssize_t \fBqb_ipcs_event_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)" +.SS "ssize_t qb_ipcs_event_send (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)" .PP Send an asyncronous event message to the client\&. \fBParameters:\fP @@ -412,11 +476,16 @@ Send an asyncronous event message to the client\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -size sent or -errno for errors +size sent or -errno for errors +.RE +.PP +\fBNote:\fP +.RS 4 +the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&. .RE .PP -.SS "ssize_t \fBqb_ipcs_event_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" +.SS "ssize_t qb_ipcs_event_sendv (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" .PP Send an asyncronous event message to the client\&. \fBParameters:\fP @@ -430,11 +499,16 @@ Send an asyncronous event message to the client\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -size sent or -errno for errors +size sent or -errno for errors +.RE +.PP +\fBNote:\fP +.RS 4 +the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&. .RE .PP -.SS "void \fBqb_ipcs_poll_handlers_set\fP (\fBqb_ipcs_service_t\fP *s, struct \fBqb_ipcs_poll_handlers\fP *handlers)" +.SS "void qb_ipcs_poll_handlers_set (\fBqb_ipcs_service_t\fP *s, struct \fBqb_ipcs_poll_handlers\fP *handlers)" .PP Set your poll callbacks\&. \fBParameters:\fP @@ -445,7 +519,7 @@ Set your poll callbacks\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcs_ref\fP (\fBqb_ipcs_service_t\fP *s)" +.SS "void qb_ipcs_ref (\fBqb_ipcs_service_t\fP *s)" .PP Increase the reference counter on the service object\&. \fBParameters:\fP @@ -454,7 +528,7 @@ Increase the reference counter on the service object\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcs_request_rate_limit\fP (\fBqb_ipcs_service_t\fP *s, enum \fBqb_ipcs_rate_limit\fPrl)" +.SS "void qb_ipcs_request_rate_limit (\fBqb_ipcs_service_t\fP *s, enum \fBqb_ipcs_rate_limit\fPrl)" .PP Limit the incomming request rate\&. \fBParameters:\fP @@ -465,7 +539,7 @@ Limit the incomming request rate\&. \fBParameters:\fP .RE .PP -.SS "ssize_t \fBqb_ipcs_response_send\fP (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)" +.SS "ssize_t qb_ipcs_response_send (\fBqb_ipcs_connection_t\fP *c, const void *data, size_tsize)" .PP Send a response to a incomming request\&. \fBParameters:\fP @@ -479,11 +553,16 @@ Send a response to a incomming request\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -size sent or -errno for errors +size sent or -errno for errors +.RE +.PP +\fBNote:\fP +.RS 4 +the data must include a \fBqb_ipc_response_header\fP at the top of the message\&. The client will read the size field to determine how much to recv\&. .RE .PP -.SS "ssize_t \fBqb_ipcs_response_sendv\fP (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" +.SS "ssize_t qb_ipcs_response_sendv (\fBqb_ipcs_connection_t\fP *c, const struct iovec *iov, size_tiov_len)" .PP Send a response to a incomming request\&. \fBParameters:\fP @@ -497,11 +576,16 @@ Send a response to a incomming request\&. \fBParameters:\fP .PP \fBReturns:\fP .RS 4 -size sent or -errno for errors +size sent or -errno for errors +.RE +.PP +\fBNote:\fP +.RS 4 +the iov[0] must be a \fBqb_ipc_response_header\fP\&. The client will read the size field to determine how much to recv\&. .RE .PP -.SS "int32_t \fBqb_ipcs_run\fP (\fBqb_ipcs_service_t\fP *s)" +.SS "int32_t qb_ipcs_run (\fBqb_ipcs_service_t\fP *s)" .PP run the new IPC server\&. \fBParameters:\fP @@ -515,7 +599,7 @@ run the new IPC server\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_ipcs_service_id_get\fP (\fBqb_ipcs_connection_t\fP *c)" +.SS "int32_t qb_ipcs_service_id_get (\fBqb_ipcs_connection_t\fP *c)" .PP Get the service id related to this connection's service\&. (as passed into \fBqb_ipcs_create()\fP @@ -526,7 +610,7 @@ service id\&. .RE .PP -.SS "int32_t \fBqb_ipcs_stats_get\fP (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_tclear_after_read)" +.SS "int32_t qb_ipcs_stats_get (\fBqb_ipcs_service_t\fP *pt, struct \fBqb_ipcs_stats\fP *stats, int32_tclear_after_read)" .PP Get the service statistics\&. \fBParameters:\fP @@ -544,7 +628,7 @@ Get the service statistics\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_ipcs_unref\fP (\fBqb_ipcs_service_t\fP *s)" +.SS "void qb_ipcs_unref (\fBqb_ipcs_service_t\fP *s)" .PP Decrease the reference counter on the service object\&. \fBParameters:\fP diff --git a/docs/man3/qblist.h.3 b/docs/man3/qblist.h.3 index db1d17d..a19ae6c 100644 --- a/docs/man3/qblist.h.3 +++ b/docs/man3/qblist.h.3 @@ -1,4 +1,4 @@ -.TH "qblist.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qblist.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -21,7 +21,7 @@ This is a kernel style list implementation\&. .RI "struct \fBqb_list_head\fP" .br .in -1c -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -106,9 +106,9 @@ Steven Dake sdake@redhat.com .RE .PP -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBQB_INIT_LIST_HEAD\fP(ptr)" +.SS "#define QB_INIT_LIST_HEAD(ptr)" \fBValue:\fP .PP .nf @@ -116,11 +116,11 @@ do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \ } while (0) .fi -.SS "#define \fBQB_LIST_DECLARE\fP(name) struct \fBqb_list_head\fP name = { &(name), &(name) }" +.SS "#define QB_LIST_DECLARE(name) struct \fBqb_list_head\fP name = { &(name), &(name) }" .PP Declare and initialize a list head\&. -.SS "#define \fBqb_list_entry\fP(ptr, type, member) ((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))" +.SS "#define qb_list_entry(ptr, type, member) ((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))" .PP Get the struct for this entry\&. \fBParameters:\fP @@ -133,7 +133,7 @@ Get the struct for this entry\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_list_for_each\fP(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)" +.SS "#define qb_list_for_each(pos, head) for (pos = (head)->next; pos != (head); pos = pos->next)" .PP Iterate over a list\&. \fBParameters:\fP @@ -146,7 +146,7 @@ Iterate over a list\&. \fBParameters:\fP .PP Referenced by qb_list_length()\&. -.SS "#define \fBqb_list_for_each_entry\fP(pos, head, member)" +.SS "#define qb_list_for_each_entry(pos, head, member)" \fBValue:\fP .PP .nf @@ -165,7 +165,7 @@ Iterate over list of given type\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_list_for_each_entry_reverse\fP(pos, head, member)" +.SS "#define qb_list_for_each_entry_reverse(pos, head, member)" \fBValue:\fP .PP .nf @@ -184,7 +184,7 @@ Iterate backwards over list of given type\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_list_for_each_entry_safe\fP(pos, n, head, member)" +.SS "#define qb_list_for_each_entry_safe(pos, n, head, member)" \fBValue:\fP .PP .nf @@ -206,7 +206,7 @@ Iterate over list of given type safe against removal of list entry\&. \fBParamet .RE .PP -.SS "#define \fBqb_list_for_each_entry_safe_reverse\fP(pos, n, head, member)" +.SS "#define qb_list_for_each_entry_safe_reverse(pos, n, head, member)" \fBValue:\fP .PP .nf @@ -228,7 +228,7 @@ Iterate backwards over list safe against removal\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_list_for_each_reverse\fP(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)" +.SS "#define qb_list_for_each_reverse(pos, head) for (pos = (head)->prev; pos != (head); pos = pos->prev)" .PP Iterate over a list backwards\&. \fBParameters:\fP @@ -239,7 +239,7 @@ Iterate over a list backwards\&. \fBParameters:\fP .RE .PP -.SS "#define \fBqb_list_for_each_safe\fP(pos, n, head)" +.SS "#define qb_list_for_each_safe(pos, n, head)" \fBValue:\fP .PP .nf @@ -259,7 +259,7 @@ Iterate over a list safe against removal of list entry\&. \fBParameters:\fP .SH "Function Documentation" .PP -.SS "static void \fBqb_list_add\fP (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static void qb_list_add (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP Add this element to the list\&. \fBParameters:\fP @@ -272,7 +272,7 @@ Add this element to the list\&. \fBParameters:\fP .PP References qb_list_head::next, and qb_list_head::prev\&. -.SS "static void \fBqb_list_add_tail\fP (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static void qb_list_add_tail (struct \fBqb_list_head\fP *element, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP Add to the list (but at the end of the list)\&. \fBParameters:\fP @@ -290,7 +290,7 @@ Add to the list (but at the end of the list)\&. \fBParameters:\fP .PP References qb_list_head::next, and qb_list_head::prev\&. -.SS "static void \fBqb_list_del\fP (struct \fBqb_list_head\fP *_remove)\fC [inline, static]\fP" +.SS "static void qb_list_del (struct \fBqb_list_head\fP *_remove)\fC [inline]\fP, \fC [static]\fP" .PP Delete an entry from the list\&. \fBParameters:\fP @@ -301,7 +301,7 @@ Delete an entry from the list\&. \fBParameters:\fP .PP References qb_list_head::next, and qb_list_head::prev\&. -.SS "static int32_t \fBqb_list_empty\fP (const struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static int32_t qb_list_empty (const struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP A quick test to see if the list is empty (pointing to it's self)\&. \fBParameters:\fP @@ -317,7 +317,7 @@ boolean true/false .PP References qb_list_head::next\&. -.SS "static void \fBqb_list_init\fP (struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static void qb_list_init (struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP Initialize the list entry\&. Points next and prev pointers to head\&. @@ -330,7 +330,7 @@ Initialize the list entry\&. Points next and prev pointers to head\&. .PP References qb_list_head::next, and qb_list_head::prev\&. -.SS "static int32_t \fBqb_list_length\fP (struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static int32_t qb_list_length (struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP Count the number of items in the list\&. \fBParameters:\fP @@ -346,7 +346,7 @@ length of the list\&. .PP References qb_list_for_each\&. -.SS "static void \fBqb_list_splice\fP (struct \fBqb_list_head\fP *list, struct \fBqb_list_head\fP *head)\fC [inline, static]\fP" +.SS "static void qb_list_splice (struct \fBqb_list_head\fP *list, struct \fBqb_list_head\fP *head)\fC [inline]\fP, \fC [static]\fP" .PP Join two lists\&. \fBParameters:\fP diff --git a/docs/man3/qblog.h.3 b/docs/man3/qblog.h.3 index 86e9773..c945f8d 100644 --- a/docs/man3/qblog.h.3 +++ b/docs/man3/qblog.h.3 @@ -1,4 +1,4 @@ -.TH "qblog.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qblog.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -36,7 +36,7 @@ The logging API provides four main parts (basics, filtering, threading & blackbo .br .RI "\fIAn instance of this structure is created in a special ELF section at every dynamic debug callsite\&. \fP" .in -1c -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -120,7 +120,7 @@ The logging API provides four main parts (basics, filtering, threading & blackbo .RI "enum \fBqb_log_target_state\fP { \fBQB_LOG_STATE_UNUSED\fP = 1, \fBQB_LOG_STATE_DISABLED\fP = 2, \fBQB_LOG_STATE_ENABLED\fP = 3 }" .br .ti -1c -.RI "enum \fBqb_log_conf\fP { \fBQB_LOG_CONF_ENABLED\fP, \fBQB_LOG_CONF_FACILITY\fP, \fBQB_LOG_CONF_DEBUG\fP, \fBQB_LOG_CONF_SIZE\fP, \fBQB_LOG_CONF_THREADED\fP, \fBQB_LOG_CONF_PRIORITY_BUMP\fP, \fBQB_LOG_CONF_STATE_GET\fP }" +.RI "enum \fBqb_log_conf\fP { \fBQB_LOG_CONF_ENABLED\fP, \fBQB_LOG_CONF_FACILITY\fP, \fBQB_LOG_CONF_DEBUG\fP, \fBQB_LOG_CONF_SIZE\fP, \fBQB_LOG_CONF_THREADED\fP, \fBQB_LOG_CONF_PRIORITY_BUMP\fP, \fBQB_LOG_CONF_STATE_GET\fP, \fBQB_LOG_CONF_FILE_SYNC\fP }" .br .ti -1c .RI "enum \fBqb_log_filter_type\fP { \fBQB_LOG_FILTER_FILE\fP, \fBQB_LOG_FILTER_FUNCTION\fP, \fBQB_LOG_FILTER_FORMAT\fP }" @@ -294,13 +294,13 @@ Call \fBqb_log()\fP to generate a log message\&. Then to write the message somew Simplist possible use: .PP .nf - main() { + main() { qb_log_init('simple-log', LOG_DAEMON, LOG_INFO); // \&.\&.\&. qb_log(LOG_WARNING, 'watch out'); // \&.\&.\&. qb_log_fini(); - } + } .fi .PP @@ -349,6 +349,14 @@ To workaround your syslog daemon filtering all messages > LOG_INFO qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP, LOG_INFO - LOG_DEBUG); +.fi +.PP +.PP +To ensure all logs to file targets are fsync'ed (default QB_FALSE) +.PP +.nf + qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE); + .fi .PP .PP @@ -399,7 +407,7 @@ To achieve non-blocking logging you can use threaded logging\&. So any calls to Threaded logging use: .PP .nf - main() { + main() { qb_log_init('simple-log', LOG_DAEMON, LOG_INFO); qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE); // \&.\&.\&. @@ -410,7 +418,7 @@ Threaded logging use: qb_log(LOG_WARNING, 'watch out'); // \&.\&.\&. qb_log_fini(); - } + } .fi .PP @@ -428,18 +436,18 @@ the blackbox is not enabled by default\&. Blackbox usage: .PP .nf - static void sigsegv_handler(int sig) - { + static void sigsegv_handler(int sig) + { (void)signal (SIGSEGV, SIG_DFL); qb_log_blackbox_write_to_file('simple-log\&.fdata'); qb_log_fini(); raise(SIGSEGV); - } - - main() { - + } + + main() { + signal(SIGSEGV, sigsegv_handler); - + qb_log_init('simple-log', LOG_DAEMON, LOG_INFO); qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, '*', LOG_DEBUG); @@ -449,7 +457,7 @@ Blackbox usage: qb_log(LOG_WARNING, 'watch out'); // \&.\&.\&. qb_log_fini(); - } + } .fi .PP @@ -461,7 +469,7 @@ You can tag messages using the second argument to \fBqb_logt()\fP or by using \f .PP .PP .nf - const char* my_tags_stringify(uint32_t tags) { + const char* my_tags_stringify(uint32_t tags) { if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT) { return 'libqb'; } else if (tags == 3) { @@ -469,36 +477,36 @@ You can tag messages using the second argument to \fBqb_logt()\fP or by using \f } else { return 'MAIN'; } - } - main() { + } + main() { // \&.\&.\&. qb_log_tags_stringify_fn_set(my_tags_stringify); qb_log_format_set(QB_LOG_STDERR, '[%5g] %p %b'); // \&.\&.\&. qb_logt(LOG_INFO, 3, 'hello'); qb_logt(LOG_INFO, 0, 'hello'); - } + } .fi .PP The code above will produce: .PP .nf - [libqb] some message - [three] info hello - [MAIN ] info hello + [libqb] some message + [three] info hello + [MAIN ] info hello .fi .PP -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBLOG_TRACE\fP (LOG_DEBUG + 1)" +.SS "#define LOG_TRACE (LOG_DEBUG + 1)" -.SS "#define \fBqb_enter\fP() \fBqb_log\fP(\fBLOG_TRACE\fP, 'ENTERING %s()', __func__)" +.SS "#define qb_enter() \fBqb_log\fP(\fBLOG_TRACE\fP, 'ENTERING %s()', __func__)" -.SS "#define \fBqb_leave\fP() \fBqb_log\fP(\fBLOG_TRACE\fP, 'LEAVING %s()', __func__)" +.SS "#define qb_leave() \fBqb_log\fP(\fBLOG_TRACE\fP, 'LEAVING %s()', __func__)" -.SS "#define \fBqb_log\fP(\fBpriority\fP, fmt, args\&.\&.\&.) \fBqb_logt\fP(\fBpriority\fP, 0, fmt, ##args)" +.SS "#define qb_log(\fBpriority\fP, fmt, args\&.\&.\&.) \fBqb_logt\fP(\fBpriority\fP, 0, fmt, ##args)" .PP This is the main function to generate a log message\&. \fBParameters:\fP @@ -511,9 +519,9 @@ This is the main function to generate a log message\&. \fBParameters:\fP .RE .PP -.SS "#define \fBQB_LOG_BLACKBOX\fP 2" +.SS "#define QB_LOG_BLACKBOX 2" -.SS "#define \fBQB_LOG_INIT_DATA\fP(name)" +.SS "#define QB_LOG_INIT_DATA(name)" \fBValue:\fP .PP .nf @@ -521,23 +529,23 @@ void name(void); \ void name(void) { if (__start___verbose != __stop___verbose) {assert(1);} } \ void __attribute__ ((constructor)) name(void); .fi -.SS "#define \fBQB_LOG_MAX_LEN\fP 512" +.SS "#define QB_LOG_MAX_LEN 512" -.SS "#define \fBQB_LOG_STDERR\fP 1" +.SS "#define QB_LOG_STDERR 1" -.SS "#define \fBQB_LOG_STDOUT\fP 3" +.SS "#define QB_LOG_STDOUT 3" -.SS "#define \fBQB_LOG_STRERROR_MAX_LEN\fP 128" +.SS "#define QB_LOG_STRERROR_MAX_LEN 128" -.SS "#define \fBQB_LOG_SYSLOG\fP 0" +.SS "#define QB_LOG_SYSLOG 0" -.SS "#define \fBQB_LOG_TAG_LIBQB_MSG\fP (1 << \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP)" +.SS "#define QB_LOG_TAG_LIBQB_MSG (1 << \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP)" -.SS "#define \fBQB_LOG_TAG_LIBQB_MSG_BIT\fP 31" +.SS "#define QB_LOG_TAG_LIBQB_MSG_BIT 31" -.SS "#define \fBQB_LOG_TARGET_MAX\fP 32" +.SS "#define QB_LOG_TARGET_MAX 32" -.SS "#define \fBqb_logt\fP(\fBpriority\fP, \fBtags\fP, fmt, args\&.\&.\&.)" +.SS "#define qb_logt(\fBpriority\fP, \fBtags\fP, fmt, args\&.\&.\&.)" \fBValue:\fP .PP .nf @@ -561,7 +569,7 @@ This is the function to generate a log message if you want to manually add tags\ .RE .PP -.SS "#define \fBqb_perror\fP(\fBpriority\fP, fmt, args\&.\&.\&.)" +.SS "#define qb_perror(\fBpriority\fP, fmt, args\&.\&.\&.)" \fBValue:\fP .PP .nf @@ -584,17 +592,17 @@ This is similar to perror except it goes into the logging system\&. \fBParameter .SH "Typedef Documentation" .PP -.SS "typedef void(* \fBqb_log_close_fn\fP)(int32_t t)" +.SS "typedef void(* qb_log_close_fn)(int32_t t)" -.SS "typedef void(* \fBqb_log_filter_fn\fP)(struct \fBqb_log_callsite\fP *cs)" +.SS "typedef void(* qb_log_filter_fn)(struct \fBqb_log_callsite\fP *cs)" -.SS "typedef void(* \fBqb_log_logger_fn\fP)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, const char *msg)" +.SS "typedef void(* qb_log_logger_fn)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, const char *msg)" -.SS "typedef void(* \fBqb_log_reload_fn\fP)(int32_t t)" +.SS "typedef void(* qb_log_reload_fn)(int32_t t)" -.SS "typedef const char*(* \fBqb_log_tags_stringify_fn\fP)(uint32_t \fBtags\fP)" +.SS "typedef const char*(* qb_log_tags_stringify_fn)(uint32_t \fBtags\fP)" -.SS "typedef void(* \fBqb_log_vlogger_fn\fP)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, va_list ap)" +.SS "typedef void(* qb_log_vlogger_fn)(int32_t t, struct \fBqb_log_callsite\fP *cs, time_t timestamp, va_list ap)" .SH "Enumeration Type Documentation" .PP @@ -617,6 +625,8 @@ This is similar to perror except it goes into the logging system\&. \fBParameter \fB\fIQB_LOG_CONF_PRIORITY_BUMP \fP\fP .TP \fB\fIQB_LOG_CONF_STATE_GET \fP\fP +.TP +\fB\fIQB_LOG_CONF_FILE_SYNC \fP\fP .SS "enum \fBqb_log_filter_conf\fP" @@ -662,17 +672,17 @@ This is similar to perror except it goes into the logging system\&. \fBParameter .SH "Function Documentation" .PP -.SS "struct \fBqb_log_callsite\fP \fB__attribute__\fP ((aligned(8)))" +.SS "struct \fBqb_log_callsite\fP __attribute__ ((aligned(8)))" -.SS "void \fBqb_log_blackbox_print_from_file\fP (const char *filename)" +.SS "void qb_log_blackbox_print_from_file (const char *filename)" .PP Read the blackbox for file and print it out\&. -.SS "ssize_t \fBqb_log_blackbox_write_to_file\fP (const char *filename)" +.SS "ssize_t qb_log_blackbox_write_to_file (const char *filename)" .PP Write the blackbox to file\&. -.SS "struct \fBqb_log_callsite\fP* \fBqb_log_callsite_get\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags)\fC [read]\fP" +.SS "struct \fBqb_log_callsite\fP* qb_log_callsite_get (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags)\fC [read]\fP" .PP Get or create a callsite at the give position\&. The result can then be passed into \fBqb_log_real_()\fP @@ -693,11 +703,11 @@ Get or create a callsite at the give position\&. The result can then be passed i .RE .PP -.SS "void \fBqb_log_callsites_dump\fP (void)" +.SS "void qb_log_callsites_dump (void)" .PP Dump the callsite info to stdout\&. -.SS "int32_t \fBqb_log_callsites_register\fP (struct \fBqb_log_callsite\fP *_start, struct \fBqb_log_callsite\fP *_stop)" +.SS "int32_t qb_log_callsites_register (struct \fBqb_log_callsite\fP *_start, struct \fBqb_log_callsite\fP *_stop)" .PP If you are using dynamically loadable modules via dlopen() and you load them after \fBqb_log_init()\fP then after you load the module you will need to do the following to get the filters to work in that module\&. .PP @@ -708,7 +718,7 @@ If you are using dynamically loadable modules via dlopen() and you load them aft .fi .PP -.SS "int32_t \fBqb_log_ctl\fP (int32_ttarget, enum \fBqb_log_conf\fPconf_type, int32_targ)" +.SS "int32_t qb_log_ctl (int32_ttarget, enum \fBqb_log_conf\fPconf_type, int32_targ)" .PP Main logging control function\&. \fBParameters:\fP @@ -735,11 +745,11 @@ Main logging control function\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_log_custom_close\fP (int32_tt)" +.SS "void qb_log_custom_close (int32_tt)" .PP Close a custom log target and release is resources\&. -.SS "int32_t \fBqb_log_custom_open\fP (\fBqb_log_logger_fn\fPlog_fn, \fBqb_log_close_fn\fPclose_fn, \fBqb_log_reload_fn\fPreload_fn, void *user_data)" +.SS "int32_t qb_log_custom_open (\fBqb_log_logger_fn\fPlog_fn, \fBqb_log_close_fn\fPclose_fn, \fBqb_log_reload_fn\fPreload_fn, void *user_data)" .PP Open a custom log target\&. \fBReturn values:\fP @@ -750,19 +760,19 @@ Open a custom log target\&. \fBReturn values:\fP .RE .PP -.SS "int32_t \fBqb_log_facility2int\fP (const char *fname)" +.SS "int32_t qb_log_facility2int (const char *fname)" .PP Convert string 'auth' to equivalent number 'LOG_AUTH' etc\&. -.SS "const char* \fBqb_log_facility2str\fP (int32_tfnum)" +.SS "const char* qb_log_facility2str (int32_tfnum)" .PP Convert number 'LOG_AUTH' to equivalent string 'auth' etc\&. -.SS "void \fBqb_log_file_close\fP (int32_tt)" +.SS "void qb_log_file_close (int32_tt)" .PP Close a log file and release is resources\&. -.SS "int32_t \fBqb_log_file_open\fP (const char *filename)" +.SS "int32_t qb_log_file_open (const char *filename)" .PP Open a log file\&. \fBReturn values:\fP @@ -773,22 +783,22 @@ Open a log file\&. \fBReturn values:\fP .RE .PP -.SS "int32_t \fBqb_log_filter_ctl\fP (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_tlow_priority)" +.SS "int32_t qb_log_filter_ctl (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_tlow_priority)" .PP This allows you modify the 'tags' and 'targets' callsite fields at runtime\&. -.SS "int32_t \fBqb_log_filter_ctl2\fP (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_thigh_priority, uint8_tlow_priority)" +.SS "int32_t qb_log_filter_ctl2 (int32_tvalue, enum \fBqb_log_filter_conf\fPc, enum \fBqb_log_filter_type\fPtype, const char *text, uint8_thigh_priority, uint8_tlow_priority)" .PP This extends \fBqb_log_filter_ctl()\fP by been able to provide a high_priority\&. -.SS "int32_t \fBqb_log_filter_fn_set\fP (\fBqb_log_filter_fn\fPfn)" +.SS "int32_t qb_log_filter_fn_set (\fBqb_log_filter_fn\fPfn)" .PP Instead of using the \fBqb_log_filter_ctl()\fP functions you can apply the filters manually by defining a callback and setting the targets field using \fBqb_bit_set()\fP and \fBqb_bit_clear()\fP like the following below\&. .PP .nf - static void - m_filter(struct qb_log_callsite *cs) - { + static void + m_filter(struct qb_log_callsite *cs) + { if ((cs->priority >= LOG_ALERT && cs->priority <= LOG_DEBUG) && strcmp(cs->filename, 'my_c_file\&.c') == 0) { @@ -796,21 +806,21 @@ Instead of using the \fBqb_log_filter_ctl()\fP functions you can apply the filte } else { qb_bit_clear(cs->targets, QB_LOG_SYSLOG); } - } + } .fi .PP -.SS "void \fBqb_log_fini\fP (void)" +.SS "void qb_log_fini (void)" .PP Logging system finalization function\&. It releases any shared memory\&. Stops the logging thread if running\&. Flushes the last message to their destinations\&. -.SS "void \fBqb_log_format_set\fP (int32_tt, const char *format)" +.SS "void qb_log_format_set (int32_tt, const char *format)" .PP Set the format specifiers\&. n FUNCTION NAME f FILENAME l FILELINE p PRIORITY t TIMESTAMP b BUFFER g TAGS N name (passed into qb_log_init) P PID H hostname .PP any number between % and character specify field length to pad or chop -.SS "void \fBqb_log_from_external_source\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, \&.\&.\&.)" +.SS "void qb_log_from_external_source (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, \&.\&.\&.)" .PP This function is to import logs from other code (like libraries) that provide a callback with their logs\&. \fBNote:\fP @@ -834,9 +844,9 @@ the performance of this will not impress you, as the filtering is done on each l .RE .PP -.SS "void \fBqb_log_from_external_source_va\fP (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, va_listap)" +.SS "void qb_log_from_external_source_va (const char *function, const char *filename, const char *format, uint8_tpriority, uint32_tlineno, uint32_ttags, va_listap)" -.SS "void \fBqb_log_init\fP (const char *name, int32_tfacility, uint8_tpriority)" +.SS "void qb_log_init (const char *name, int32_tfacility, uint8_tpriority)" .PP Init the logging system\&. \fBParameters:\fP @@ -849,25 +859,25 @@ Init the logging system\&. \fBParameters:\fP .RE .PP -.SS "void \fBqb_log_real_\fP (struct \fBqb_log_callsite\fP *cs, \&.\&.\&.)" +.SS "void qb_log_real_ (struct \fBqb_log_callsite\fP *cs, \&.\&.\&.)" .PP Internal function: use \fBqb_log()\fP or \fBqb_logt()\fP -.SS "void \fBqb_log_real_va_\fP (struct \fBqb_log_callsite\fP *cs, va_listap)" +.SS "void qb_log_real_va_ (struct \fBqb_log_callsite\fP *cs, va_listap)" -.SS "void \fBqb_log_tags_stringify_fn_set\fP (\fBqb_log_tags_stringify_fn\fPfn)" +.SS "void qb_log_tags_stringify_fn_set (\fBqb_log_tags_stringify_fn\fPfn)" .PP Set the callback to map the 'tags' bit map to a string\&. -.SS "void \fBqb_log_target_format\fP (int32_ttarget, struct \fBqb_log_callsite\fP *cs, time_ttimestamp, const char *formatted_message, char *output_buffer)" +.SS "void qb_log_target_format (int32_ttarget, struct \fBqb_log_callsite\fP *cs, time_ttimestamp, const char *formatted_message, char *output_buffer)" .PP format the callsite and timestamp info according to the format set using \fBqb_log_format_set()\fP It is intended to be used from your custom logger function\&. -.SS "void* \fBqb_log_target_user_data_get\fP (int32_tt)" +.SS "void* qb_log_target_user_data_get (int32_tt)" .PP Retrieve the user data set by either qb_log_custom_open or qb_log_target_user_data_set\&. -.SS "int32_t \fBqb_log_target_user_data_set\fP (int32_tt, void *user_data)" +.SS "int32_t qb_log_target_user_data_set (int32_tt, void *user_data)" .PP Associate user data with this log target\&. \fBNote:\fP @@ -876,7 +886,7 @@ only use this with custom targets .RE .PP -.SS "int32_t \fBqb_log_thread_priority_set\fP (int32_tpolicy, int32_tpriority)" +.SS "int32_t qb_log_thread_priority_set (int32_tpolicy, int32_tpriority)" .PP When using threaded logging set the pthread policy and priority\&. \fBReturn values:\fP @@ -887,31 +897,31 @@ When using threaded logging set the pthread policy and priority\&. \fBReturn val .RE .PP -.SS "int32_t \fBqb_log_thread_start\fP (void)" +.SS "int32_t qb_log_thread_start (void)" .PP Start the logging pthread\&. .SH "Variable Documentation" .PP -.SS "enum \fBqb_log_target_state\fP \fB__attribute__\fP" +.SS "enum \fBqb_log_target_state\fP __attribute__" -.SS "struct \fBqb_log_callsite\fP \fB__start___verbose\fP[]" +.SS "struct \fBqb_log_callsite\fP __start___verbose[]" -.SS "struct \fBqb_log_callsite\fP \fB__stop___verbose\fP[]" +.SS "struct \fBqb_log_callsite\fP __stop___verbose[]" -.SS "const char* \fBfilename\fP" +.SS "const char* filename" -.SS "const char* \fBformat\fP" +.SS "const char* format" -.SS "const char* \fBfunction\fP" +.SS "const char* function" -.SS "uint32_t \fBlineno\fP" +.SS "uint32_t lineno" -.SS "uint8_t \fBpriority\fP" +.SS "uint8_t priority" -.SS "uint32_t \fBtags\fP" +.SS "uint32_t tags" -.SS "uint32_t \fBtargets\fP" +.SS "uint32_t targets" .SH "Author" .PP diff --git a/docs/man3/qbloop.h.3 b/docs/man3/qbloop.h.3 index a8a097d..7935efb 100644 --- a/docs/man3/qbloop.h.3 +++ b/docs/man3/qbloop.h.3 @@ -1,4 +1,4 @@ -.TH "qbloop.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbloop.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -110,11 +110,11 @@ Main loop manages timers, jobs and polling sockets\&. .br .RI "\fIDelete a poll job\&. \fP" .ti -1c -.RI "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t signal, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP *handle)" +.RI "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t sig, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP *handle)" .br .RI "\fIAdd a signal job\&. \fP" .ti -1c -.RI "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t signal, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP handle)" +.RI "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fP p, int32_t sig, void *data, \fBqb_loop_signal_dispatch_fn\fP dispatch_fn, \fBqb_loop_signal_handle\fP handle)" .br .RI "\fIModify the signal job\&. \fP" .ti -1c @@ -129,13 +129,13 @@ Main loop manages timers, jobs and polling sockets\&. .SH "Typedef Documentation" .PP -.SS "typedef void(* \fBqb_loop_job_dispatch_fn\fP)(void *data)" +.SS "typedef void(* qb_loop_job_dispatch_fn)(void *data)" -.SS "typedef int32_t(* \fBqb_loop_poll_dispatch_fn\fP)(int32_t fd, int32_t revents, void *data)" +.SS "typedef int32_t(* qb_loop_poll_dispatch_fn)(int32_t fd, int32_t revents, void *data)" -.SS "typedef void(* \fBqb_loop_poll_low_fds_event_fn\fP)(int32_t not_enough, int32_t fds_available)" +.SS "typedef void(* qb_loop_poll_low_fds_event_fn)(int32_t not_enough, int32_t fds_available)" -.SS "typedef int32_t(* \fBqb_loop_signal_dispatch_fn\fP)(int32_t rsignal, void *data)" +.SS "typedef int32_t(* qb_loop_signal_dispatch_fn)(int32_t rsignal, void *data)" .SS "typedef void* \fBqb_loop_signal_handle\fP" @@ -143,7 +143,7 @@ Main loop manages timers, jobs and polling sockets\&. .PP An opaque data type representing the main loop\&. -.SS "typedef void(* \fBqb_loop_timer_dispatch_fn\fP)(void *data)" +.SS "typedef void(* qb_loop_timer_dispatch_fn)(void *data)" .SS "typedef uint64_t \fBqb_loop_timer_handle\fP" @@ -165,7 +165,7 @@ Priorites for jobs, timers & poll\&. .SH "Function Documentation" .PP -.SS "\fBqb_loop_t\fP* \fBqb_loop_create\fP (void)" +.SS "\fBqb_loop_t\fP* qb_loop_create (void)" .PP Create a new main loop\&. \fBReturns:\fP @@ -174,9 +174,9 @@ loop instance\&. .RE .PP -.SS "void \fBqb_loop_destroy\fP (struct qb_loop *l)" +.SS "void qb_loop_destroy (struct qb_loop *l)" -.SS "int32_t \fBqb_loop_job_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)" +.SS "int32_t qb_loop_job_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)" .PP Add a job to the mainloop\&. This is run in the next cycle of the loop\&. @@ -203,7 +203,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_job_del\fP (struct qb_loop *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)" +.SS "int32_t qb_loop_job_del (struct qb_loop *l, enum \fBqb_loop_priority\fPp, void *data, \fBqb_loop_job_dispatch_fn\fPdispatch_fn)" .PP Delete a job from the mainloop\&. This will try to delete the job if it hasn't run yet\&. @@ -230,7 +230,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_poll_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)" +.SS "int32_t qb_loop_poll_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)" .PP Add a poll job to the mainloop\&. \fBNote:\fP @@ -259,7 +259,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_poll_del\fP (\fBqb_loop_t\fP *l, int32_tfd)" +.SS "int32_t qb_loop_poll_del (\fBqb_loop_t\fP *l, int32_tfd)" .PP Delete a poll job\&. \fBParameters:\fP @@ -275,7 +275,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_poll_low_fds_event_set\fP (\fBqb_loop_t\fP *l, \fBqb_loop_poll_low_fds_event_fn\fPfn)" +.SS "int32_t qb_loop_poll_low_fds_event_set (\fBqb_loop_t\fP *l, \fBqb_loop_poll_low_fds_event_fn\fPfn)" .PP Set a callback to receive events on file descriptors getting low\&. \fBParameters:\fP @@ -291,7 +291,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_poll_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)" +.SS "int32_t qb_loop_poll_mod (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tfd, int32_tevents, void *data, \fBqb_loop_poll_dispatch_fn\fPdispatch_fn)" .PP Modify a poll job\&. \fBParameters:\fP @@ -315,7 +315,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "void \fBqb_loop_run\fP (\fBqb_loop_t\fP *l)" +.SS "void qb_loop_run (\fBqb_loop_t\fP *l)" .PP Run the main loop\&. \fBParameters:\fP @@ -324,7 +324,7 @@ Run the main loop\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_loop_signal_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsignal, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fP *handle)" +.SS "int32_t qb_loop_signal_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsig, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fP *handle)" .PP Add a signal job\&. Get a callback on this signal (not in the context of the signal)\&. @@ -335,7 +335,7 @@ Add a signal job\&. Get a callback on this signal (not in the context of the sig .br \fIp\fP the priority .br -\fIsignal\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&. +\fIsig\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&. .br \fIdata\fP user data passed into the dispatch function .br @@ -350,7 +350,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_signal_del\fP (\fBqb_loop_t\fP *l, \fBqb_loop_signal_handle\fPhandle)" +.SS "int32_t qb_loop_signal_del (\fBqb_loop_t\fP *l, \fBqb_loop_signal_handle\fPhandle)" .PP Delete the signal job\&. \fBParameters:\fP @@ -366,7 +366,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_signal_mod\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsignal, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fPhandle)" +.SS "int32_t qb_loop_signal_mod (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, int32_tsig, void *data, \fBqb_loop_signal_dispatch_fn\fPdispatch_fn, \fBqb_loop_signal_handle\fPhandle)" .PP Modify the signal job\&. \fBParameters:\fP @@ -375,7 +375,7 @@ Modify the signal job\&. \fBParameters:\fP .br \fIp\fP the priority .br -\fIsignal\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&. +\fIsig\fP (SIGHUP or SIGINT) etc \&.\&.\&.\&. .br \fIdata\fP user data passed into the dispatch function .br @@ -390,7 +390,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "void \fBqb_loop_stop\fP (\fBqb_loop_t\fP *l)" +.SS "void qb_loop_stop (\fBqb_loop_t\fP *l)" .PP Stop the main loop\&. \fBParameters:\fP @@ -399,7 +399,7 @@ Stop the main loop\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_loop_timer_add\fP (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, uint64_tnsec_duration, void *data, \fBqb_loop_timer_dispatch_fn\fPdispatch_fn, \fBqb_loop_timer_handle\fP *timer_handle_out)" +.SS "int32_t qb_loop_timer_add (\fBqb_loop_t\fP *l, enum \fBqb_loop_priority\fPp, uint64_tnsec_duration, void *data, \fBqb_loop_timer_dispatch_fn\fPdispatch_fn, \fBqb_loop_timer_handle\fP *timer_handle_out)" .PP Add a timer to the mainloop\&. \fBNote:\fP @@ -428,7 +428,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "int32_t \fBqb_loop_timer_del\fP (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)" +.SS "int32_t qb_loop_timer_del (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)" .PP Delete a timer that is still outstanding\&. \fBParameters:\fP @@ -444,7 +444,7 @@ status (0 == ok, -errno == failure) .RE .PP -.SS "uint64_t \fBqb_loop_timer_expire_time_get\fP (struct qb_loop *l, \fBqb_loop_timer_handle\fPth)" +.SS "uint64_t qb_loop_timer_expire_time_get (struct qb_loop *l, \fBqb_loop_timer_handle\fPth)" .PP Get the time remaining before it expires\&. \fBNote:\fP @@ -465,7 +465,7 @@ nano seconds left .RE .PP -.SS "int32_t \fBqb_loop_timer_is_running\fP (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)" +.SS "int32_t qb_loop_timer_is_running (\fBqb_loop_t\fP *l, \fBqb_loop_timer_handle\fPth)" .PP Check to see if a timer that is still outstanding\&. \fBParameters:\fP diff --git a/docs/man3/qbmap.h.3 b/docs/man3/qbmap.h.3 index 06fffb6..28806b3 100644 --- a/docs/man3/qbmap.h.3 +++ b/docs/man3/qbmap.h.3 @@ -1,4 +1,4 @@ -.TH "qbmap.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbmap.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -14,7 +14,7 @@ This provides a map interface to a Patricia trie, hashtable or skiplist\&. \fC#include \fP .br -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -137,13 +137,13 @@ The hashtable is NOT ordered, but ptrie and skiplist are\&. Below is a simple example of how to iterate over a map\&. .PP .nf - const char *p; - void *data; - qb_map_iter_t *it = qb_map_iter_create(m); - for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) { - printf('%s > %s\n', p, (char*) data); - } - qb_map_iter_free(it); + const char *p; + void *data; + qb_map_iter_t *it = qb_map_iter_create(m); + for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) { + printf('%s > %s\n', p, (char*) data); + } + qb_map_iter_free(it); .fi .PP @@ -152,7 +152,7 @@ Below is a simple example of how to iterate over a map\&. Deletion of items within the iterator is supported\&. But note do not free the item memory in the iterator\&. If you need to free the data items then register for a notifier and free the memory there\&. This is required as the items are reference counted\&. .PP .nf - qb_map_notify_add(m, NULL, my_map_free_handler, + qb_map_notify_add(m, NULL, my_map_free_handler, QB_MAP_NOTIFY_FREE, NULL); .fi @@ -180,18 +180,18 @@ The ptrie supports prefixes in the iterator: .PP .PP .nf - it = qb_map_pref_iter_create(m, 'aa'); - while ((p = qb_map_iter_next(it, &data)) != NULL) { - printf('%s > %s\n', p, (char*)data); - } - qb_map_iter_free(it); + it = qb_map_pref_iter_create(m, 'aa'); + while ((p = qb_map_iter_next(it, &data)) != NULL) { + printf('%s > %s\n', p, (char*)data); + } + qb_map_iter_free(it); .fi .PP .PP The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTIFY_RECURSIVE into the notify_add\&. .PP .nf - qb_map_notify_add(m, 'root', my_map_notification, + qb_map_notify_add(m, 'root', my_map_notification, (QB_MAP_NOTIFY_INSERTED| QB_MAP_NOTIFY_DELETED| QB_MAP_NOTIFY_REPLACED| @@ -201,17 +201,17 @@ The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTI .fi .PP -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBQB_MAP_NOTIFY_DELETED\fP 1" +.SS "#define QB_MAP_NOTIFY_DELETED 1" -.SS "#define \fBQB_MAP_NOTIFY_FREE\fP 16" +.SS "#define QB_MAP_NOTIFY_FREE 16" -.SS "#define \fBQB_MAP_NOTIFY_INSERTED\fP 4" +.SS "#define QB_MAP_NOTIFY_INSERTED 4" -.SS "#define \fBQB_MAP_NOTIFY_RECURSIVE\fP 8" +.SS "#define QB_MAP_NOTIFY_RECURSIVE 8" -.SS "#define \fBQB_MAP_NOTIFY_REPLACED\fP 2" +.SS "#define QB_MAP_NOTIFY_REPLACED 2" .SH "Typedef Documentation" .PP @@ -219,17 +219,17 @@ The ptrie also supports prefixes in notifications: (remember to pass QB_MAP_NOTI .PP This is an opaque data type representing an iterator instance\&. -.SS "typedef void(* \fBqb_map_notify_fn\fP)(uint32_t event, char *key, void *old_value, void *value, void *user_data)" +.SS "typedef void(* qb_map_notify_fn)(uint32_t event, char *key, void *old_value, void *value, void *user_data)" .SS "typedef struct qb_map \fBqb_map_t\fP" .PP This is an opaque data type representing an instance of a map\&. -.SS "typedef int32_t(* \fBqb_map_transverse_fn\fP)(const char *key, void *value, void *user_data)" +.SS "typedef int32_t(* qb_map_transverse_fn)(const char *key, void *value, void *user_data)" .SH "Function Documentation" .PP -.SS "\fBqb_map_t\fP* \fBqb_hashtable_create\fP (size_tmax_size)" +.SS "\fBqb_map_t\fP* qb_hashtable_create (size_tmax_size)" .PP Create an unsorted map based on a hashtable\&. \fBParameters:\fP @@ -243,19 +243,19 @@ the map instance .RE .PP -.SS "size_t \fBqb_map_count_get\fP (\fBqb_map_t\fP *map)" +.SS "size_t qb_map_count_get (\fBqb_map_t\fP *map)" .PP Get the number of items in the map\&. -.SS "void \fBqb_map_destroy\fP (\fBqb_map_t\fP *map)" +.SS "void qb_map_destroy (\fBqb_map_t\fP *map)" .PP Destroy the map, removes all the items from the map\&. -.SS "void \fBqb_map_foreach\fP (\fBqb_map_t\fP *map, \fBqb_map_transverse_fn\fPfunc, void *user_data)" +.SS "void qb_map_foreach (\fBqb_map_t\fP *map, \fBqb_map_transverse_fn\fPfunc, void *user_data)" .PP Calls the given function for each of the key/value pairs in the map\&. The function is passed the key and value of each pair, and the given data parameter\&. The map is traversed in sorted order\&. -.SS "void* \fBqb_map_get\fP (\fBqb_map_t\fP *map, const char *key)" +.SS "void* qb_map_get (\fBqb_map_t\fP *map, const char *key)" .PP Gets the value corresponding to the given key\&. \fBReturn values:\fP @@ -266,11 +266,11 @@ Gets the value corresponding to the given key\&. \fBReturn values:\fP .RE .PP -.SS "\fBqb_map_iter_t\fP* \fBqb_map_iter_create\fP (\fBqb_map_t\fP *map)" +.SS "\fBqb_map_iter_t\fP* qb_map_iter_create (\fBqb_map_t\fP *map)" .PP Create an iterator\&. -.SS "void \fBqb_map_iter_free\fP (\fBqb_map_iter_t\fP *i)" +.SS "void qb_map_iter_free (\fBqb_map_iter_t\fP *i)" .PP free the iterator \fBParameters:\fP @@ -279,7 +279,7 @@ free the iterator \fBParameters:\fP .RE .PP -.SS "const char* \fBqb_map_iter_next\fP (\fBqb_map_iter_t\fP *i, void **value)" +.SS "const char* qb_map_iter_next (\fBqb_map_iter_t\fP *i, void **value)" .PP Get the next item\&. \fBParameters:\fP @@ -297,7 +297,7 @@ Get the next item\&. \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_map_notify_add\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)" +.SS "int32_t qb_map_notify_add (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)" .PP Add a notifier to the map\&. \fBParameters:\fP @@ -328,7 +328,7 @@ you can use key prefixes with trie maps\&. .RE .PP -.SS "int32_t \fBqb_map_notify_del\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents)" +.SS "int32_t qb_map_notify_del (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents)" .PP Delete a notifier from the map\&. \fBNote:\fP @@ -355,7 +355,7 @@ the key,fn and events must match those you added\&. .RE .PP -.SS "int32_t \fBqb_map_notify_del_2\fP (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)" +.SS "int32_t qb_map_notify_del_2 (\fBqb_map_t\fP *m, const char *key, \fBqb_map_notify_fn\fPfn, int32_tevents, void *user_data)" .PP Delete a notifier from the map (including the userdata)\&. \fBNote:\fP @@ -384,7 +384,7 @@ the key, fn, events and userdata must match those you added\&. .RE .PP -.SS "\fBqb_map_iter_t\fP* \fBqb_map_pref_iter_create\fP (\fBqb_map_t\fP *map, const char *prefix)" +.SS "\fBqb_map_iter_t\fP* qb_map_pref_iter_create (\fBqb_map_t\fP *map, const char *prefix)" .PP Create a prefix iterator\&. This will iterate over all items with the given prefix\&. @@ -395,15 +395,15 @@ this is only supported by the trie\&. .RE .PP -.SS "void \fBqb_map_put\fP (\fBqb_map_t\fP *map, const char *key, const void *value)" +.SS "void qb_map_put (\fBqb_map_t\fP *map, const char *key, const void *value)" .PP Inserts a new key and value into a qb_map_t\&. If the key already exists in the qb_map_t, it gets replaced by the new key\&. -.SS "int32_t \fBqb_map_rm\fP (\fBqb_map_t\fP *map, const char *key)" +.SS "int32_t qb_map_rm (\fBqb_map_t\fP *map, const char *key)" .PP Removes a key/value pair from a map\&. -.SS "\fBqb_map_t\fP* \fBqb_skiplist_create\fP (void)" +.SS "\fBqb_map_t\fP* qb_skiplist_create (void)" .PP Create a sorted map using a skiplist\&. \fBReturns:\fP @@ -412,11 +412,11 @@ the map instance .RE .PP -.SS "\fBqb_map_t\fP* \fBqb_trie_create\fP (void)" +.SS "\fBqb_map_t\fP* qb_trie_create (void)" .PP Create a sorted map using a Patricia trie or 'Radix tree'\&. -.SS "void \fBqb_trie_dump\fP (\fBqb_map_t\fP *m)" +.SS "void qb_trie_dump (\fBqb_map_t\fP *m)" .PP print out the nodes in the trie (for debug purposes) diff --git a/docs/man3/qbutil.h.3 b/docs/man3/qbutil.h.3 index 929f516..1fd5b25 100644 --- a/docs/man3/qbutil.h.3 +++ b/docs/man3/qbutil.h.3 @@ -1,4 +1,4 @@ -.TH "qbutil.h" 3 "Sun Mar 11 2012" "Version 0.11.1" "libqb" \" -*- nroff -*- +.TH "qbutil.h" 3 "Mon Sep 10 2012" "Version 0.14.2" "libqb" \" -*- nroff -*- .ad l .nh .SH NAME @@ -15,7 +15,7 @@ qbutil.h \- \fC#include \fP .br -.SS "Defines" +.SS "Macros" .in +1c .ti -1c @@ -180,21 +180,21 @@ These are some convience functions used throughout libqb\&. .PP .nf - uint64_t elapsed1; - uint64_t elapsed2; - qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); - - qb_util_stopwatch_start(sw); - - usleep(sometime); - qb_util_stopwatch_stop(sw); - elapsed1 = qb_util_stopwatch_us_elapsed_get(sw); - - usleep(somemoretime); - qb_util_stopwatch_stop(sw); - elapsed2 = qb_util_stopwatch_us_elapsed_get(sw); - - qb_util_stopwatch_free(sw); + uint64_t elapsed1; + uint64_t elapsed2; + qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); + + qb_util_stopwatch_start(sw); + + usleep(sometime); + qb_util_stopwatch_stop(sw); + elapsed1 = qb_util_stopwatch_us_elapsed_get(sw); + + usleep(somemoretime); + qb_util_stopwatch_stop(sw); + elapsed2 = qb_util_stopwatch_us_elapsed_get(sw); + + qb_util_stopwatch_free(sw); .fi .PP @@ -207,44 +207,44 @@ Setup a stopwatch with space for 3 splits\&. .PP .PP .nf - uint64_t split; - qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); - - qb_util_stopwatch_split_ctl(sw, 3, 0); - qb_util_stopwatch_start(sw); - - usleep(sometime); - qb_util_stopwatch_split(sw); - - usleep(somemoretime); - qb_util_stopwatch_split(sw); - - usleep(somemoretime); - qb_util_stopwatch_split(sw); - - idx = qb_util_stopwatch_split_last(sw); - do { - split = qb_util_stopwatch_time_split_get(sw, idx, idx); - qb_log(LOG_INFO, 'split %d is %'PRIu64'', last, split); - idx--; - } while (split > 0); - - split = qb_util_stopwatch_time_split_get(sw, 2, 1); - qb_log(LOG_INFO, 'time between second and third split is %'PRIu64'', split); - - qb_util_stopwatch_free(sw); + uint64_t split; + qb_util_stopwatch_t *sw = qb_util_stopwatch_create(); + + qb_util_stopwatch_split_ctl(sw, 3, 0); + qb_util_stopwatch_start(sw); + + usleep(sometime); + qb_util_stopwatch_split(sw); + + usleep(somemoretime); + qb_util_stopwatch_split(sw); + + usleep(somemoretime); + qb_util_stopwatch_split(sw); + + idx = qb_util_stopwatch_split_last(sw); + do { + split = qb_util_stopwatch_time_split_get(sw, idx, idx); + qb_log(LOG_INFO, 'split %d is %'PRIu64'', last, split); + idx--; + } while (split > 0); + + split = qb_util_stopwatch_time_split_get(sw, 2, 1); + qb_log(LOG_INFO, 'time between second and third split is %'PRIu64'', split); + + qb_util_stopwatch_free(sw); .fi .PP -.SH "Define Documentation" +.SH "Macro Definition Documentation" .PP -.SS "#define \fBQB_UTIL_SW_OVERWRITE\fP 0x01" +.SS "#define QB_UTIL_SW_OVERWRITE 0x01" .SH "Typedef Documentation" .PP .SS "typedef struct qb_thread_lock_s \fBqb_thread_lock_t\fP" -.SS "typedef void(* \fBqb_util_log_fn_t\fP)(const char *file_name, int32_t file_line, int32_t severity, const char *msg)" +.SS "typedef void(* qb_util_log_fn_t)(const char *file_name, int32_t file_line, int32_t severity, const char *msg)" .SS "typedef struct qb_util_stopwatch \fBqb_util_stopwatch_t\fP" @@ -264,15 +264,15 @@ QB_THREAD_LOCK_SHORT is a short term lock (spinlock if available on your system) .SH "Function Documentation" .PP -.SS "char* \fBqb_strerror_r\fP (interrnum, char *buf, size_tbuflen)" +.SS "char* qb_strerror_r (interrnum, char *buf, size_tbuflen)" .PP strerror_r replacement\&. -.SS "int32_t \fBqb_thread_lock\fP (\fBqb_thread_lock_t\fP *tl)" +.SS "int32_t qb_thread_lock (\fBqb_thread_lock_t\fP *tl)" .PP Calls either pthread_mutex_lock() or pthread_spin_lock()\&. -.SS "\fBqb_thread_lock_t\fP* \fBqb_thread_lock_create\fP (\fBqb_thread_lock_type_t\fPtype)" +.SS "\fBqb_thread_lock_t\fP* qb_thread_lock_create (\fBqb_thread_lock_type_t\fPtype)" .PP Create a new lock of the given type\&. \fBParameters:\fP @@ -286,19 +286,19 @@ pointer to qb_thread_lock_type_t or NULL on error\&. .RE .PP -.SS "int32_t \fBqb_thread_lock_destroy\fP (\fBqb_thread_lock_t\fP *tl)" +.SS "int32_t qb_thread_lock_destroy (\fBqb_thread_lock_t\fP *tl)" .PP Calls either pthread_mutex_destro() or pthread_spin_destroy()\&. -.SS "int32_t \fBqb_thread_trylock\fP (\fBqb_thread_lock_t\fP *tl)" +.SS "int32_t qb_thread_trylock (\fBqb_thread_lock_t\fP *tl)" .PP Calls either pthread_mutex_trylock() or pthread_spin_trylock()\&. -.SS "int32_t \fBqb_thread_unlock\fP (\fBqb_thread_lock_t\fP *tl)" +.SS "int32_t qb_thread_unlock (\fBqb_thread_lock_t\fP *tl)" .PP Calls either pthread_mutex_unlock() or pthread_spin_unlock\&. -.SS "void \fBqb_timespec_add_ms\fP (struct timespec *ts, int32_tms)" +.SS "void qb_timespec_add_ms (struct timespec *ts, int32_tms)" .PP Add milliseconds onto the timespec\&. \fBParameters:\fP @@ -309,35 +309,35 @@ Add milliseconds onto the timespec\&. \fBParameters:\fP .RE .PP -.SS "uint64_t \fBqb_util_nano_current_get\fP (void)" +.SS "uint64_t qb_util_nano_current_get (void)" .PP Get the current number of nano secounds produced by the systems incrementing clock (CLOCK_MONOTOMIC if available)\&. -.SS "uint64_t \fBqb_util_nano_from_epoch_get\fP (void)" +.SS "uint64_t qb_util_nano_from_epoch_get (void)" .PP Get the time in nano seconds since epoch\&. -.SS "uint64_t \fBqb_util_nano_monotonic_hz\fP (void)" +.SS "uint64_t qb_util_nano_monotonic_hz (void)" .PP Get the frequence of the clock used in \fBqb_util_nano_current_get()\fP\&. -.SS "void \fBqb_util_set_log_function\fP (\fBqb_util_log_fn_t\fPfn)" +.SS "void qb_util_set_log_function (\fBqb_util_log_fn_t\fPfn)" .PP Use this function to output libqb internal log message as you wish\&. -.SS "\fBqb_util_stopwatch_t\fP* \fBqb_util_stopwatch_create\fP (void)" +.SS "\fBqb_util_stopwatch_t\fP* qb_util_stopwatch_create (void)" .PP Create a Stopwatch (to time operations) -.SS "void \fBqb_util_stopwatch_free\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "void qb_util_stopwatch_free (\fBqb_util_stopwatch_t\fP *sw)" .PP Free the stopwatch\&. -.SS "float \fBqb_util_stopwatch_sec_elapsed_get\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "float qb_util_stopwatch_sec_elapsed_get (\fBqb_util_stopwatch_t\fP *sw)" .PP Get the elapsed time in seconds\&. (it must have been started and stopped)\&. -.SS "uint64_t \fBqb_util_stopwatch_split\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "uint64_t qb_util_stopwatch_split (\fBqb_util_stopwatch_t\fP *sw)" .PP Create a new time split (or lap time) \fBParameters:\fP @@ -353,7 +353,7 @@ Create a new time split (or lap time) \fBParameters:\fP .RE .PP -.SS "int32_t \fBqb_util_stopwatch_split_ctl\fP (\fBqb_util_stopwatch_t\fP *sw, uint32_tmax_splits, uint32_toptions)" +.SS "int32_t qb_util_stopwatch_split_ctl (\fBqb_util_stopwatch_t\fP *sw, uint32_tmax_splits, uint32_toptions)" \fBParameters:\fP .RS 4 \fIsw\fP the stopwatch @@ -371,7 +371,7 @@ Create a new time split (or lap time) \fBParameters:\fP .RE .PP -.SS "uint32_t \fBqb_util_stopwatch_split_last\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "uint32_t qb_util_stopwatch_split_last (\fBqb_util_stopwatch_t\fP *sw)" .PP Get the last split index to be used by \fBqb_util_stopwatch_time_split_get()\fP \fBNote:\fP @@ -390,15 +390,15 @@ the last entry index .RE .PP -.SS "void \fBqb_util_stopwatch_start\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "void qb_util_stopwatch_start (\fBqb_util_stopwatch_t\fP *sw)" .PP Start the stopwatch\&. This also acts as a reset\&. Essentially it sets the starting time and clears the splits\&. -.SS "void \fBqb_util_stopwatch_stop\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "void qb_util_stopwatch_stop (\fBqb_util_stopwatch_t\fP *sw)" .PP Stop the stopwatch\&. This just allows you to get the elapsed time\&. So you can call this multiple times\&. Do not call \fBqb_util_stopwatch_start()\fP unless you want to reset the stopwatch\&. -.SS "uint64_t \fBqb_util_stopwatch_time_split_get\fP (\fBqb_util_stopwatch_t\fP *sw, uint32_treceint, uint32_tolder)" +.SS "uint64_t qb_util_stopwatch_time_split_get (\fBqb_util_stopwatch_t\fP *sw, uint32_treceint, uint32_tolder)" .PP Read the time split (in us) from 'receint' to 'older'\&. If older == receint then the cumulated split will be returned (from the stopwatch start)\&. @@ -420,11 +420,11 @@ Read the time split (in us) from 'receint' to 'older'\&. If older == receint the .RE .PP -.SS "uint64_t \fBqb_util_stopwatch_us_elapsed_get\fP (\fBqb_util_stopwatch_t\fP *sw)" +.SS "uint64_t qb_util_stopwatch_us_elapsed_get (\fBqb_util_stopwatch_t\fP *sw)" .PP Get the elapsed time in micro seconds\&. (it must have been started and stopped)\&. -.SS "void \fBqb_util_timespec_from_epoch_get\fP (struct timespec *ts)" +.SS "void qb_util_timespec_from_epoch_get (struct timespec *ts)" .PP Get the time in timespec since epoch\&. \fBParameters:\fP diff --git a/docs/man8/qb-blackbox.8 b/docs/man8/qb-blackbox.8 new file mode 100644 index 0000000..976848c --- /dev/null +++ b/docs/man8/qb-blackbox.8 @@ -0,0 +1,59 @@ +.\"/* +.\" * Copyright (C) 2012 Red Hat, Inc. +.\" * +.\" * Author: Angus Salkeld +.\" * +.\" * This file is part of libqb. +.\" * +.\" * libqb is free software: you can redistribute it and/or modify +.\" * it under the terms of the GNU Lesser General Public License as published by +.\" * the Free Software Foundation, either version 2.1 of the License, or +.\" * (at your option) any later version. +.\" * +.\" * libqb 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 Lesser General Public License for more details. +.\" * +.\" * You should have received a copy of the GNU Lesser General Public License +.\" * along with libqb. If not, see . +.\" */ +.TH QB-BLACKBOX 8 2012-05-28 +.SH NAME +qb-blackbox \- Display "flight data" from the "blackbox". +.SH SYNOPSIS +.B "qb-blackbox ..." +.SH DESCRIPTION +.B qb-blackbox +Print out the logs (including debug logs) that were recorded using libqb's blackbox. +.SH EXAMPLES +.TP +Get info to help developers diagnose a crash. +.br +$ qb-blackbox /var/lib/corosync/fdata +.br +Dumping the contents of /var/lib/corosync/fdata +.br +Mar 23 20:58:57 message_handler_orf_token():3677 install seq 0 aru 0 high seq received 0 +.br +Mar 23 20:58:57 message_handler_orf_token():3696 retrans flag count 4 token aru 0 install seq 0 aru 0 0 +.br +Mar 23 20:58:57 old_ring_state_reset():1487 Resetting old ring state +.br +Mar 23 20:58:57 deliver_messages_from_recovery_to_regular():1693 recovery to regular 1-0 +.br +Mar 23 20:58:57 memb_state_operational_enter():1779 Delivering to app 1 to 0 +.br +Mar 23 20:58:57 sync_abort():594 ENTERING sync_abort() +.br +Mar 23 20:58:57 sync_save_transitional():586 ENTERING sync_save_transitional() +.br +Mar 23 20:58:57 member_object_joined():301 Member joined: r(0) ip(192.168.122.1) +.br +Mar 23 20:58:57 sync_abort():594 ENTERING sync_abort() +.br +.SH SEE ALSO +.BR qblog.h (3), +.SH AUTHOR +Angus Salkeld +.PP diff --git a/examples/Makefile.am b/examples/Makefile.am index 58646e3..d546fca 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with libqb. If not, see . # -MAINTAINERCLEANFILES = Makefiles.in +MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = CLEANFILES = @@ -25,27 +25,27 @@ noinst_PROGRAMS = mapnotify simplelog tcpclient tcpserver ipcclient ipcserver mapnotify_SOURCES = mapnotify.c $(top_builddir)/include/qb/qbmap.h mapnotify_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -mapnotify_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +mapnotify_LDADD = $(top_builddir)/lib/libqb.la simplelog_SOURCES = simplelog.c $(top_builddir)/include/qb/qblog.h simplelog_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -simplelog_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +simplelog_LDADD = $(top_builddir)/lib/libqb.la tcpclient_SOURCES = tcpclient.c $(top_builddir)/include/qb/qbloop.h tcpclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -tcpclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +tcpclient_LDADD = $(top_builddir)/lib/libqb.la tcpserver_SOURCES = tcpserver.c $(top_builddir)/include/qb/qbloop.h tcpserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -tcpserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +tcpserver_LDADD = $(top_builddir)/lib/libqb.la ipcclient_SOURCES = ipcclient.c $(top_builddir)/include/qb/qbloop.h \ $(top_builddir)/include/qb/qbipcc.h ipcclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -ipcclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +ipcclient_LDADD = $(top_builddir)/lib/libqb.la ipcserver_SOURCES = ipcserver.c $(top_builddir)/include/qb/qbloop.h \ $(top_builddir)/include/qb/qbipcs.h ipcserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(GLIB_CFLAGS) -ipcserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS) +ipcserver_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS) diff --git a/examples/Makefile.in b/examples/Makefile.in index e3a6082..37184ed 100644 --- a/examples/Makefile.in +++ b/examples/Makefile.in @@ -54,34 +54,29 @@ CONFIG_CLEAN_VPATH_FILES = PROGRAMS = $(noinst_PROGRAMS) am_ipcclient_OBJECTS = ipcclient-ipcclient.$(OBJEXT) ipcclient_OBJECTS = $(am_ipcclient_OBJECTS) -am__DEPENDENCIES_1 = -ipcclient_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +ipcclient_DEPENDENCIES = $(top_builddir)/lib/libqb.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am_ipcserver_OBJECTS = ipcserver-ipcserver.$(OBJEXT) ipcserver_OBJECTS = $(am_ipcserver_OBJECTS) -ipcserver_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la $(am__DEPENDENCIES_1) +am__DEPENDENCIES_1 = +ipcserver_DEPENDENCIES = $(top_builddir)/lib/libqb.la \ + $(am__DEPENDENCIES_1) am_mapnotify_OBJECTS = mapnotify-mapnotify.$(OBJEXT) mapnotify_OBJECTS = $(am_mapnotify_OBJECTS) -mapnotify_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +mapnotify_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_simplelog_OBJECTS = simplelog-simplelog.$(OBJEXT) simplelog_OBJECTS = $(am_simplelog_OBJECTS) -simplelog_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +simplelog_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_tcpclient_OBJECTS = tcpclient-tcpclient.$(OBJEXT) tcpclient_OBJECTS = $(am_tcpclient_OBJECTS) -tcpclient_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +tcpclient_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_tcpserver_OBJECTS = tcpserver-tcpserver.$(OBJEXT) tcpserver_OBJECTS = $(am_tcpserver_OBJECTS) -tcpserver_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +tcpserver_DEPENDENCIES = $(top_builddir)/lib/libqb.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -161,7 +156,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -268,33 +262,33 @@ top_srcdir = @top_srcdir@ # You should have received a copy of the GNU Lesser General Public License # along with libqb. If not, see . # -MAINTAINERCLEANFILES = Makefiles.in +MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = CLEANFILES = mapnotify_SOURCES = mapnotify.c $(top_builddir)/include/qb/qbmap.h mapnotify_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -mapnotify_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +mapnotify_LDADD = $(top_builddir)/lib/libqb.la simplelog_SOURCES = simplelog.c $(top_builddir)/include/qb/qblog.h simplelog_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -simplelog_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +simplelog_LDADD = $(top_builddir)/lib/libqb.la tcpclient_SOURCES = tcpclient.c $(top_builddir)/include/qb/qbloop.h tcpclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -tcpclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +tcpclient_LDADD = $(top_builddir)/lib/libqb.la tcpserver_SOURCES = tcpserver.c $(top_builddir)/include/qb/qbloop.h tcpserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -tcpserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +tcpserver_LDADD = $(top_builddir)/lib/libqb.la ipcclient_SOURCES = ipcclient.c $(top_builddir)/include/qb/qbloop.h \ $(top_builddir)/include/qb/qbipcc.h ipcclient_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -ipcclient_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +ipcclient_LDADD = $(top_builddir)/lib/libqb.la ipcserver_SOURCES = ipcserver.c $(top_builddir)/include/qb/qbloop.h \ $(top_builddir)/include/qb/qbipcs.h ipcserver_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include \ $(GLIB_CFLAGS) -ipcserver_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS) +ipcserver_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS) all: all-am .SUFFIXES: diff --git a/examples/ipcclient.c b/examples/ipcclient.c index 31e85aa..a949e4b 100644 --- a/examples/ipcclient.c +++ b/examples/ipcclient.c @@ -24,8 +24,15 @@ #include #include #include +#include -#define MAX_MSG_SIZE (8192) +static int32_t do_benchmark = QB_FALSE; +static int32_t use_events = QB_FALSE; +static int alarm_notice; +static qb_util_stopwatch_t *sw; +#define ONE_MEG 1048576 +#define MAX_MSG_SIZE ONE_MEG +static char data[ONE_MEG]; struct my_req { struct qb_ipc_request_header hdr; @@ -37,22 +44,84 @@ struct my_res { char message[256]; }; -int -main(int argc, char *argv[]) +static void sigalrm_handler (int num) +{ + alarm_notice = 1; +} + +static void +_benchmark(qb_ipcc_connection_t *conn, int write_size) +{ + struct iovec iov[2]; + unsigned int res; + struct qb_ipc_request_header hdr; + int write_count = 0; + float secs; + + alarm_notice = 0; + hdr.size = write_size; + hdr.id = QB_IPC_MSG_USER_START + 1; + + iov[0].iov_base = &hdr; + iov[0].iov_len = sizeof(struct qb_ipc_request_header); + + iov[1].iov_base = data; + iov[1].iov_len = write_size - sizeof(struct qb_ipc_request_header); + + alarm (10); + + qb_util_stopwatch_start(sw); + do { + res = qb_ipcc_sendv(conn, iov, 2); + if (res == write_size) { + write_count++; + } + } while (alarm_notice == 0 && (res == write_size || res == -EAGAIN)); + if (res < 0) { + perror("qb_ipcc_sendv"); + } + qb_util_stopwatch_stop(sw); + secs = qb_util_stopwatch_sec_elapsed_get(sw); + + printf ("%5d messages sent ", write_count); + printf ("%5d bytes per write ", write_size); + printf ("%7.3f Seconds runtime ", secs); + printf ("%9.3f TP/s ", + ((float)write_count) / secs); + printf ("%7.3f MB/s.\n", + ((float)write_count) * ((float)write_size) / secs); +} + + +static void +do_throughput_benchmark(qb_ipcc_connection_t *conn) +{ + ssize_t size = 64; + int i; + + signal (SIGALRM, sigalrm_handler); + sw = qb_util_stopwatch_create(); + + for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */ + _benchmark (conn, size); + signal (SIGALRM, sigalrm_handler); + size *= 5; + if (size >= (ONE_MEG - 100)) { + break; + } + } +} + +static void +do_echo(qb_ipcc_connection_t *conn) { - qb_ipcc_connection_t *conn; - int32_t rc; struct my_req req; struct my_res res; char *newline; + int32_t rc; + int32_t send_ten_events; - conn = qb_ipcc_connect("ipcserver", MAX_MSG_SIZE); - if (conn == NULL) { - perror("qb_ipcc_connect"); - exit(1); - } - - while(1) { + while (1) { printf("SEND (q or Q to quit) : "); if (fgets(req.message, 256, stdin) == NULL) { continue; @@ -70,21 +139,99 @@ main(int argc, char *argv[]) rc = qb_ipcc_send(conn, &req, req.hdr.size); if (rc < 0) { perror("qb_ipcc_send"); + exit(0); } } + send_ten_events = (strcasecmp(req.message, "events") == 0); + if (rc > 0) { - rc = qb_ipcc_recv(conn, - &res, - sizeof(res), -1); + if (use_events && !send_ten_events) { + printf("waiting for event recv\n"); + rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1); + } else { + printf("waiting for recv\n"); + rc = qb_ipcc_recv(conn, &res, sizeof(res), -1); + } + printf("recv %d\n", rc); if (rc < 0) { perror("qb_ipcc_recv"); + exit(0); + } + if (send_ten_events) { + int32_t i; + printf("waiting for 10 events\n"); + for (i = 0; i < 10; i++) { + rc = qb_ipcc_event_recv(conn, &res, sizeof(res), -1); + if (rc < 0) { + perror("qb_ipcc_event_recv"); + } else { + printf("got event %d rc:%d\n", i, rc); + } + } } printf("Response[%d]: %s \n", res.hdr.id, res.message); } } +} + +static void +show_usage(const char *name) +{ + printf("usage: \n"); + printf("%s \n", name); + printf("\n"); + printf(" options:\n"); + printf("\n"); + printf(" -h show this help text\n"); + printf(" -b benchmark\n"); + printf(" -e use events instead of responses\n"); + printf("\n"); +} + +int +main(int argc, char *argv[]) +{ + qb_ipcc_connection_t *conn; + const char *options = "eb"; + int32_t opt; + + while ((opt = getopt(argc, argv, options)) != -1) { + switch (opt) { + case 'b': + do_benchmark = QB_TRUE; + break; + case 'e': + use_events = QB_TRUE; + break; + case 'h': + default: + show_usage(argv[0]); + exit(0); + break; + } + } + + + qb_log_init("ipcclient", LOG_USER, LOG_TRACE); + qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); + qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, + QB_LOG_FILTER_FILE, "*", LOG_TRACE); + qb_log_format_set(QB_LOG_STDERR, "%f:%l [%p] %b"); + qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); + + conn = qb_ipcc_connect("ipcserver", MAX_MSG_SIZE); + if (conn == NULL) { + perror("qb_ipcc_connect"); + exit(1); + } + + if (do_benchmark) { + do_throughput_benchmark(conn); + } else { + do_echo(conn); + } qb_ipcc_disconnect(conn); return EXIT_SUCCESS; } - diff --git a/examples/ipcserver.c b/examples/ipcserver.c index 6e2fc6a..20fbb7d 100644 --- a/examples/ipcserver.c +++ b/examples/ipcserver.c @@ -34,11 +34,12 @@ static qb_array_t *gio_map; #endif /* HAVE_GLIB */ static int32_t use_glib = QB_FALSE; +static int32_t use_events = QB_FALSE; static qb_loop_t *bms_loop; -static qb_ipcs_service_t* s1; +static qb_ipcs_service_t *s1; static int32_t -s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) +s1_connection_accept_fn(qb_ipcs_connection_t * c, uid_t uid, gid_t gid) { #if 0 if (uid == 0 && gid == 0) { @@ -52,34 +53,33 @@ s1_connection_accept_fn(qb_ipcs_connection_t *c, uid_t uid, gid_t gid) #endif } -static void -s1_connection_created_fn(qb_ipcs_connection_t *c) +static void +s1_connection_created_fn(qb_ipcs_connection_t * c) { struct qb_ipcs_stats srv_stats; qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE); qb_log(LOG_INFO, "Connection created (active:%d, closed:%d)", - srv_stats.active_connections, - srv_stats.closed_connections); + srv_stats.active_connections, srv_stats.closed_connections); } -static void -s1_connection_destroyed_fn(qb_ipcs_connection_t *c) +static void +s1_connection_destroyed_fn(qb_ipcs_connection_t * c) { qb_log(LOG_INFO, "Connection about to be freed"); } -static int32_t -s1_connection_closed_fn(qb_ipcs_connection_t *c) +static int32_t +s1_connection_closed_fn(qb_ipcs_connection_t * c) { struct qb_ipcs_connection_stats stats; struct qb_ipcs_stats srv_stats; qb_ipcs_stats_get(s1, &srv_stats, QB_FALSE); qb_ipcs_connection_stats_get(c, &stats, QB_FALSE); - qb_log(LOG_INFO, "Connection to pid:%d destroyed (active:%d, closed:%d)", - stats.client_pid, - srv_stats.active_connections, + qb_log(LOG_INFO, + "Connection to pid:%d destroyed (active:%d, closed:%d)", + stats.client_pid, srv_stats.active_connections, srv_stats.closed_connections); qb_log(LOG_DEBUG, " Requests %"PRIu64"", stats.requests); @@ -92,36 +92,69 @@ s1_connection_closed_fn(qb_ipcs_connection_t *c) return 0; } -static int32_t -s1_msg_process_fn(qb_ipcs_connection_t *c, - void *data, size_t size) +struct my_req { + struct qb_ipc_request_header hdr; + char message[256]; +}; + +static int32_t +s1_msg_process_fn(qb_ipcs_connection_t * c, void *data, size_t size) { - struct qb_ipc_request_header *req_pt = (struct qb_ipc_request_header *)data; + struct qb_ipc_request_header *hdr; + struct my_req *req_pt; struct qb_ipc_response_header response; ssize_t res; struct iovec iov[2]; char resp[100]; + int32_t sl; + int32_t send_ten_events = QB_FALSE; - qb_log(LOG_DEBUG, "msg received (id:%d, size:%d)", - req_pt->id, req_pt->size); + hdr = (struct qb_ipc_request_header *)data; + if (hdr->id == (QB_IPC_MSG_USER_START + 1)) { + return 0; + } + + req_pt = (struct my_req *)data; + qb_log(LOG_DEBUG, "msg received (id:%d, size:%d, data:%s)", + req_pt->hdr.id, req_pt->hdr.size, req_pt->message); + + if (strcmp(req_pt->message, "kill") == 0) { + exit(0); + } response.size = sizeof(struct qb_ipc_response_header); response.id = 13; response.error = 0; - snprintf(resp, 100, "ACK %zd bytes", size); + sl = snprintf(resp, 100, "ACK %zd bytes", size) + 1; iov[0].iov_len = sizeof(response); iov[0].iov_base = &response; - iov[1].iov_len = strlen(resp) + 1; + iov[1].iov_len = sl; iov[1].iov_base = resp; + response.size += sl; - res = qb_ipcs_response_sendv(c, iov, 2); + send_ten_events = (strcmp(req_pt->message, "events") == 0); + + if (use_events && !send_ten_events) { + res = qb_ipcs_event_sendv(c, iov, 2); + } else { + res = qb_ipcs_response_sendv(c, iov, 2); + } if (res < 0) { + errno = - res; qb_perror(LOG_ERR, "qb_ipcs_response_send"); } + if (send_ten_events) { + int32_t i; + qb_log(LOG_INFO, "request to send 10 events"); + for (i = 0; i < 10; i++) { + res = qb_ipcs_event_sendv(c, iov, 2); + qb_log(LOG_INFO, "sent event %d res:%d", i, res); + } + } return 0; } -static void +static void sigusr1_handler(int32_t num) { qb_log(LOG_DEBUG, "(%d)", num); @@ -129,7 +162,7 @@ sigusr1_handler(int32_t num) exit(0); } -static void +static void show_usage(const char *name) { printf("usage: \n"); @@ -139,10 +172,9 @@ show_usage(const char *name) printf("\n"); printf(" -h show this help text\n"); printf(" -m use shared memory\n"); - printf(" -p use posix message queues\n"); - printf(" -s use sysv message queues\n"); printf(" -u use unix sockets\n"); printf(" -g use glib mainloop\n"); + printf(" -e use events\n"); printf("\n"); } @@ -151,13 +183,13 @@ struct gio_to_qb_poll { gboolean is_used; GIOChannel *channel; int32_t events; - void * data; + void *data; qb_ipcs_dispatch_fn_t fn; enum qb_loop_priority p; }; static gboolean -gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data) +gio_read_socket(GIOChannel * gio, GIOCondition condition, gpointer data) { struct gio_to_qb_poll *adaptor = (struct gio_to_qb_poll *)data; gint fd = g_io_channel_unix_get_fd(gio); @@ -165,15 +197,15 @@ gio_read_socket (GIOChannel *gio, GIOCondition condition, gpointer data) return (adaptor->fn(fd, condition, adaptor->data) == 0); } -static int32_t +static int32_t my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts, - void *data, qb_ipcs_dispatch_fn_t fn) + void *data, qb_ipcs_dispatch_fn_t fn) { struct gio_to_qb_poll *adaptor; GIOChannel *channel; int32_t res = 0; - res = qb_array_index(gio_map, fd, (void**)&adaptor); + res = qb_array_index(gio_map, fd, (void **)&adaptor); if (res < 0) { return res; } @@ -199,7 +231,7 @@ my_g_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts, static int32_t my_g_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts, - void *data, qb_ipcs_dispatch_fn_t fn) + void *data, qb_ipcs_dispatch_fn_t fn) { return 0; } @@ -208,7 +240,7 @@ static int32_t my_g_dispatch_del(int32_t fd) { struct gio_to_qb_poll *adaptor; - if (qb_array_index(gio_map, fd, (void**)&adaptor) == 0) { + if (qb_array_index(gio_map, fd, (void **)&adaptor) == 0) { g_io_channel_unref(adaptor->channel); adaptor->is_used = FALSE; } @@ -216,7 +248,7 @@ my_g_dispatch_del(int32_t fd) } #endif /* HAVE_GLIB */ -static int32_t +static int32_t my_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn) { return qb_loop_job_add(bms_loop, p, data, fn); @@ -224,14 +256,14 @@ my_job_add(enum qb_loop_priority p, void *data, qb_loop_job_dispatch_fn fn) static int32_t my_dispatch_add(enum qb_loop_priority p, int32_t fd, int32_t evts, - void *data, qb_ipcs_dispatch_fn_t fn) + void *data, qb_ipcs_dispatch_fn_t fn) { return qb_loop_poll_add(bms_loop, p, fd, evts, data, fn); } -static int32_t +static int32_t my_dispatch_mod(enum qb_loop_priority p, int32_t fd, int32_t evts, - void *data, qb_ipcs_dispatch_fn_t fn) + void *data, qb_ipcs_dispatch_fn_t fn) { return qb_loop_poll_mod(bms_loop, p, fd, evts, data, fn); } @@ -245,9 +277,9 @@ my_dispatch_del(int32_t fd) int32_t main(int32_t argc, char *argv[]) { - const char *options = "mpsugh"; + const char *options = "mpseugh"; int32_t opt; - enum qb_ipc_type ipc_type = QB_IPC_SHM; + enum qb_ipc_type ipc_type = QB_IPC_NATIVE; struct qb_ipcs_service_handlers sh = { .connection_accept = s1_connection_accept_fn, .connection_created = s1_connection_created_fn, @@ -275,18 +307,15 @@ main(int32_t argc, char *argv[]) case 'm': ipc_type = QB_IPC_SHM; break; - case 's': - ipc_type = QB_IPC_SYSV_MQ; - break; case 'u': ipc_type = QB_IPC_SOCKET; break; - case 'p': - ipc_type = QB_IPC_POSIX_MQ; - break; case 'g': use_glib = QB_TRUE; break; + case 'e': + use_events = QB_TRUE; + break; case 'h': default: show_usage(argv[0]); @@ -296,10 +325,9 @@ main(int32_t argc, char *argv[]) } signal(SIGINT, sigusr1_handler); - qb_log_init("ipcserver", LOG_USER, LOG_WARNING); + qb_log_init("ipcserver", LOG_USER, LOG_TRACE); qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, - QB_LOG_FILTER_FILE, __FILE__, - LOG_DEBUG); + QB_LOG_FILTER_FILE, "*", LOG_TRACE); qb_log_format_set(QB_LOG_STDERR, "%f:%l [%p] %b"); qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); @@ -321,7 +349,8 @@ main(int32_t argc, char *argv[]) qb_ipcs_run(s1); g_main_loop_run(glib_loop); #else - qb_log(LOG_ERR, "You don't seem to have glib-devel installed.\n"); + qb_log(LOG_ERR, + "You don't seem to have glib-devel installed.\n"); #endif } return EXIT_SUCCESS; diff --git a/examples/mapnotify.c b/examples/mapnotify.c index e883852..daf5164 100644 --- a/examples/mapnotify.c +++ b/examples/mapnotify.c @@ -26,7 +26,8 @@ #include static void -notify_fn(uint32_t event, char* key, void* old_value, void* value, void* user_data) +notify_fn(uint32_t event, char *key, void *old_value, void *value, + void *user_data) { if (event == QB_MAP_NOTIFY_FREE) { fprintf(stderr, "Notify[FREE] %s [%d]\n", @@ -44,13 +45,14 @@ notify_fn(uint32_t event, char* key, void* old_value, void* value, void* user_da fprintf(stderr, " value = [%d]\n", *(int *)value); } if (old_value != NULL) { - fprintf(stderr, " old value = [%d]\n", *(int *)old_value); + fprintf(stderr, " old value = [%d]\n", + *(int *)old_value); } } } static void -add_cs_keys(qb_map_t *m) +add_cs_keys(qb_map_t * m) { qb_map_put(m, "compatibility", strdup("none")); qb_map_put(m, "totem.version", strdup("2")); @@ -197,7 +199,7 @@ main(void) iter = qb_map_pref_iter_create(trie, "test."); while ((key = qb_map_iter_next(iter, &val)) != NULL) { - fprintf(stderr,"Iter %s [%d]\n", key, *(int*)val); + fprintf(stderr, "Iter %s [%d]\n", key, *(int *)val); qb_map_rm(trie, key); } qb_map_iter_free(iter); diff --git a/examples/simplelog.c b/examples/simplelog.c index d5fbc0a..727dbe2 100644 --- a/examples/simplelog.c +++ b/examples/simplelog.c @@ -29,18 +29,19 @@ #define MY_TAG_TWO (1 << 1) #define MY_TAG_THREE (1 << 2) -static int32_t _log_priority = LOG_WARNING; +static uint8_t _log_priority = LOG_WARNING; -static void func_one(void) +static void +func_one(void) { - FILE* fd; + FILE *fd; qb_enter(); qb_logt(LOG_DEBUG, MY_TAG_TWO, "arf arf?"); - qb_logt(LOG_CRIT, MY_TAG_THREE, "arrrg!"); - qb_logt(134, MY_TAG_THREE, "big priority"); - qb_logt(LOG_ERR, MY_TAG_THREE, "oops, I did it again"); - qb_log(LOG_INFO, "are you aware ..."); + qb_logt(LOG_CRIT, MY_TAG_THREE, "arrrg!"); + qb_logt(134, MY_TAG_THREE, "big priority"); + qb_logt(LOG_ERR, MY_TAG_THREE, "oops, I did it again"); + qb_log(LOG_INFO, "are you aware ..."); fd = fopen("/nothing.txt", "r+"); if (fd == NULL) { @@ -51,17 +52,19 @@ static void func_one(void) qb_leave(); } -static void func_two(void) +static void +func_two(void) { qb_enter(); qb_logt(LOG_DEBUG, 0, "arf arf?"); - qb_logt(LOG_CRIT, MY_TAG_ONE, "arrrg!"); - qb_log(LOG_ERR, "oops, I did it again"); - qb_logt(LOG_INFO, MY_TAG_THREE, "are you aware ..."); + qb_logt(LOG_CRIT, MY_TAG_ONE, "arrrg!"); + qb_log(LOG_ERR, "oops, I did it again"); + qb_logt(LOG_INFO, MY_TAG_THREE, "are you aware ..."); qb_leave(); } -static void show_usage(const char *name) +static void +show_usage(const char *name) { printf("usage: \n"); printf("%s \n", name); @@ -80,9 +83,10 @@ static void show_usage(const char *name) static int32_t do_blackbox = QB_FALSE; static int32_t do_threaded = QB_FALSE; -static void sigsegv_handler(int sig) +static void +sigsegv_handler(int sig) { - (void)signal (SIGSEGV, SIG_DFL); + (void)signal(SIGSEGV, SIG_DFL); qb_log_fini(); if (do_blackbox) { qb_log_blackbox_write_to_file("simple-log.fdata"); @@ -90,7 +94,8 @@ static void sigsegv_handler(int sig) raise(SIGSEGV); } -static const char *my_tags_stringify(uint32_t tags) +static const char * +my_tags_stringify(uint32_t tags) { if (qb_bit_is_set(tags, QB_LOG_TAG_LIBQB_MSG_BIT)) { return "libqb"; @@ -107,9 +112,7 @@ static const char *my_tags_stringify(uint32_t tags) static void trace_logger(int32_t t, - struct qb_log_callsite *cs, - time_t timestamp, - const char *msg) + struct qb_log_callsite *cs, time_t timestamp, const char *msg) { char output_buffer[QB_LOG_MAX_LEN]; output_buffer[0] = '\0'; @@ -122,14 +125,15 @@ m_filter(struct qb_log_callsite *cs) { if ((cs->priority >= LOG_ALERT && cs->priority <= _log_priority) && - strcmp(cs->filename, __FILE__) == 0) { + strcmp(cs->filename, __FILE__) == 0) { qb_bit_set(cs->targets, QB_LOG_STDERR); } else { qb_bit_clear(cs->targets, QB_LOG_STDERR); } } -int32_t main(int32_t argc, char *argv[]) +int32_t +main(int32_t argc, char *argv[]) { const char *options = "vhteobdf:"; int32_t opt; @@ -182,7 +186,6 @@ int32_t main(int32_t argc, char *argv[]) qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, do_threaded); qb_log_tags_stringify_fn_set(my_tags_stringify); - if (do_stderr) { qb_log_filter_fn_set(m_filter); qb_log_format_set(QB_LOG_STDERR, "[%p] %4g: %f:%l %b"); @@ -223,13 +226,25 @@ int32_t main(int32_t argc, char *argv[]) qb_log(LOG_DEBUG, "hello"); qb_log(LOG_INFO, "this is an info"); qb_log(LOG_NOTICE, "hello - notice?"); + { + char * str = NULL; + qb_log(LOG_ERR, + "%s-%d-%s-%u", + NULL, 952, str, 56); + } func_one(); func_two(); - qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); + if (!do_threaded) { + /* Disabling syslog here will prevent the logs from + * getting flushed in qb_log_fini() if threaded + * logging is on. + */ + qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); - qb_log(LOG_WARNING, "no syslog"); - qb_log(LOG_ERR, "no syslog"); + qb_log(LOG_WARNING, "no syslog"); + qb_log(LOG_ERR, "no syslog"); + } #if 0 // test blackbox @@ -240,8 +255,8 @@ int32_t main(int32_t argc, char *argv[]) qb_log_blackbox_write_to_file("simple-log.fdata"); qb_log_blackbox_print_from_file("simple-log.fdata"); qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE); + unlink("simple-log.fdata"); } qb_log_fini(); return 0; } - diff --git a/examples/tcpclient.c b/examples/tcpclient.c index 67e2487..db4d8bb 100644 --- a/examples/tcpclient.c +++ b/examples/tcpclient.c @@ -19,8 +19,19 @@ * along with libqb. If not, see . */ #include "os_base.h" -#include +#ifdef HAVE_NETINET_IN_H +#include +#endif /* HAVE_NETINET_IN_H */ +#ifdef HAVE_ARPA_INET_H +#include +#endif /* HAVE_ARPA_INET_H */ +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif /* HAVE_SYS_SOCKET_H */ int main(int argc, char *argv[]) @@ -40,8 +51,9 @@ main(int argc, char *argv[]) server_addr.sin_family = AF_INET; server_addr.sin_port = htons(5000); - memcpy(&server_addr.sin_addr, host->h_addr_list[0], sizeof(server_addr.sin_addr)); - bzero(&(server_addr.sin_zero),8); + memcpy(&server_addr.sin_addr, host->h_addr_list[0], + sizeof(server_addr.sin_addr)); + bzero(&(server_addr.sin_zero), 8); if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1) { @@ -49,7 +61,7 @@ main(int argc, char *argv[]) exit(1); } - while(1) { + while (1) { printf("\nSEND (q or Q to quit) : "); if (fgets(send_data, 1024, stdin) == NULL) { continue; diff --git a/examples/tcpserver.c b/examples/tcpserver.c index fddaa39..4878d55 100644 --- a/examples/tcpserver.c +++ b/examples/tcpserver.c @@ -20,9 +20,21 @@ */ #include "os_base.h" -#include +#ifdef HAVE_NETINET_IN_H +#include +#endif /* HAVE_NETINET_IN_H */ +#ifdef HAVE_ARPA_INET_H #include -#include +#endif /* HAVE_ARPA_INET_H */ +#ifdef HAVE_NETDB_H +#include +#endif /* HAVE_NETDB_H */ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif /* HAVE_SYS_SOCKET_H */ +#ifdef HAVE_SYS_POLL_H +#include +#endif /* HAVE_SYS_POLL_H */ #include #include @@ -47,8 +59,7 @@ sock_read_fn(int32_t fd, int32_t revents, void *data) } recv_data[bytes_recieved] = '\0'; - if (strcmp(recv_data, "q") == 0 || - strcmp(recv_data, "Q") == 0) { + if (strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0) { printf("Quiting connection from socket %d\n", fd); close(fd); return QB_FALSE; @@ -64,7 +75,7 @@ static int32_t sock_accept_fn(int32_t fd, int32_t revents, void *data) { struct sockaddr_in client_addr; - qb_loop_t * ml = (qb_loop_t*)data; + qb_loop_t *ml = (qb_loop_t *) data; socklen_t sin_size = sizeof(struct sockaddr_in); int connected = accept(fd, (struct sockaddr *)&client_addr, &sin_size); @@ -73,12 +84,9 @@ sock_accept_fn(int32_t fd, int32_t revents, void *data) return QB_TRUE; } printf("I got a connection from (%s , %d)\n", - inet_ntoa(client_addr.sin_addr), - ntohs(client_addr.sin_port)); + inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); - qb_loop_poll_add(ml, QB_LOOP_MED, - connected, POLLIN, - ml, sock_read_fn); + qb_loop_poll_add(ml, QB_LOOP_MED, connected, POLLIN, ml, sock_read_fn); return QB_TRUE; } @@ -86,7 +94,7 @@ sock_accept_fn(int32_t fd, int32_t revents, void *data) static int32_t please_exit_fn(int32_t rsignal, void *data) { - qb_loop_t * ml = (qb_loop_t*)data; + qb_loop_t *ml = (qb_loop_t *) data; printf("Shutting down at you request...\n"); qb_loop_stop(ml); @@ -99,20 +107,16 @@ main(int argc, char *argv[]) int sock; int true_opt = 1; struct sockaddr_in server_addr; - qb_loop_t * ml = qb_loop_create(); + qb_loop_t *ml = qb_loop_create(); - if ((sock = socket(AF_INET, - SOCK_STREAM, - 0)) == -1) { + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("Socket"); exit(1); } if (setsockopt(sock, SOL_SOCKET, - SO_REUSEADDR, - &true_opt, - sizeof(int)) == -1) { + SO_REUSEADDR, &true_opt, sizeof(int)) == -1) { perror("Setsockopt"); exit(1); } @@ -120,7 +124,7 @@ main(int argc, char *argv[]) server_addr.sin_family = AF_INET; server_addr.sin_port = htons(5000); server_addr.sin_addr.s_addr = INADDR_ANY; - bzero(&(server_addr.sin_zero),8); + bzero(&(server_addr.sin_zero), 8); printf("TCPServer binding to port 5000\n"); if (bind(sock, @@ -137,14 +141,9 @@ main(int argc, char *argv[]) exit(1); } - qb_loop_poll_add(ml, QB_LOOP_MED, - sock, POLLIN, - ml, sock_accept_fn); + qb_loop_poll_add(ml, QB_LOOP_MED, sock, POLLIN, ml, sock_accept_fn); - qb_loop_signal_add(ml, QB_LOOP_HIGH, - SIGINT, - ml, please_exit_fn, - NULL); + qb_loop_signal_add(ml, QB_LOOP_HIGH, SIGINT, ml, please_exit_fn, NULL); qb_loop_run(ml); close(sock); diff --git a/include/Makefile.in b/include/Makefile.in index 58409b2..74926cd 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -164,7 +164,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ diff --git a/include/config.h.in b/include/config.h.in index d48d320..5cdc7a6 100644 --- a/include/config.h.in +++ b/include/config.h.in @@ -6,6 +6,9 @@ /* Compiling Debugging code */ #undef DEBUG +/* Disable shared mem ipc */ +#undef DISABLE_IPC_SHM + /* Disable _POSIX_THREAD_PROCESS_SHARED */ #undef DISABLE_POSIX_THREAD_PROCESS_SHARED @@ -21,6 +24,10 @@ /* Define to 1 if you have the `clock_gettime' function. */ #undef HAVE_CLOCK_GETTIME +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#undef HAVE_DECL_STRERROR_R + /* "Have /usr/share/dict/words" */ #undef HAVE_DICT_WORDS @@ -51,6 +58,12 @@ /* Define to 1 if you have the `getpagesize' function. */ #undef HAVE_GETPAGESIZE +/* Define to 1 if you have the `getpeereid' function. */ +#undef HAVE_GETPEEREID + +/* Define to 1 if you have the `getpeerucred' function. */ +#undef HAVE_GETPEERUCRED + /* Define to 1 if you have the `getrlimit' function. */ #undef HAVE_GETRLIMIT @@ -63,17 +76,8 @@ /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H -/* Define to 1 if you have the `dl' library (-ldl). */ -#undef HAVE_LIBDL - -/* Define to 1 if you have the `pthread' library (-lpthread). */ -#undef HAVE_LIBPTHREAD - -/* Define to 1 if you have the `rt' library (-lrt). */ -#undef HAVE_LIBRT - -/* Define to 1 if you have the `socket' library (-lsocket). */ -#undef HAVE_LIBSOCKET +/* Define to 1 if you have the `kqueue' function. */ +#undef HAVE_KQUEUE /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H @@ -96,20 +100,23 @@ /* Define to 1 if you have a working `mmap' system call. */ #undef HAVE_MMAP -/* Define to 1 if you have the header file. */ -#undef HAVE_MQUEUE_H - /* Define to 1 if you have the `munmap' function. */ #undef HAVE_MUNMAP +/* Define to 1 if you have the header file. */ +#undef HAVE_NETDB_H + /* Define to 1 if you have the header file. */ #undef HAVE_NETINET_IN_H /* Define to 1 if you have the `poll' function. */ #undef HAVE_POLL -/* have posix message queues */ -#undef HAVE_POSIX_MQ +/* Define to 1 if you have the `pthread_condattr_setpshared' function. */ +#undef HAVE_PTHREAD_CONDATTR_SETPSHARED + +/* Define to 1 if you have the `pthread_mutexattr_setpshared' function. */ +#undef HAVE_PTHREAD_MUTEXATTR_SETPSHARED /* Define to 1 if you have the `pthread_setschedparam' function. */ #undef HAVE_PTHREAD_SETSCHEDPARAM @@ -129,18 +136,33 @@ /* Define to 1 if you have the `sched_setscheduler' function. */ #undef HAVE_SCHED_SETSCHEDULER +/* Define to 1 if you have the `semtimedop' function. */ +#undef HAVE_SEMTIMEDOP + +/* Define to 1 if you have union semun. */ +#undef HAVE_SEMUN + +/* Define to 1 if you have the `sem_timedwait' function. */ +#undef HAVE_SEM_TIMEDWAIT + /* have slow tests */ #undef HAVE_SLOW_TESTS /* Define to 1 if you have the `socket' function. */ #undef HAVE_SOCKET +/* Define to 1 if you have the header file. */ +#undef HAVE_STDDEF_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H +/* Define to 1 if you have the `strcasecmp' function. */ +#undef HAVE_STRCASECMP + /* Define to 1 if you have the `strchr' function. */ #undef HAVE_STRCHR @@ -150,8 +172,8 @@ /* Define to 1 if you have the `strdup' function. */ #undef HAVE_STRDUP -/* Define to 1 if you have the `strerror' function. */ -#undef HAVE_STRERROR +/* Define to 1 if you have the `strerror_r' function. */ +#undef HAVE_STRERROR_R /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H @@ -171,18 +193,21 @@ /* Define to 1 if you have the `strstr' function. */ #undef HAVE_STRSTR +/* Define to 1 if struct sockaddr_un has a member sun_len */ +#undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN + /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the header file. */ #undef HAVE_SYSLOG_H -/* have sysv message queues */ -#undef HAVE_SYSV_MQ - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_EPOLL_H +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_EVENT_H + /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IPC_H @@ -253,12 +278,6 @@ */ #undef LT_OBJDIR -/* Shared memory define for Darwin platform */ -#undef MAP_ANONYMOUS - -/* Number of chars in a file name */ -#undef NAME_MAX - /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #undef NO_MINUS_C_MINUS_O @@ -286,9 +305,6 @@ /* Define to the version of this package. */ #undef PACKAGE_VERSION -/* Number of chars in a path name including nul */ -#undef PATH_MAX - /* alpha */ #undef QB_ARCH_ALPHA @@ -313,6 +329,9 @@ /* Compiling for BSD platform */ #undef QB_BSD +/* Compiling for Cygwin platform */ +#undef QB_CYGWIN + /* Compiling for Darwin platform */ #undef QB_DARWIN @@ -337,14 +356,46 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS -/* Prevent being scheduled RR */ -#undef TS_CLASS +/* Define to 1 if strerror_r returns char *. */ +#undef STRERROR_R_CHAR_P + +/* Unix path length */ +#undef UNIX_PATH_MAX + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# undef _ALL_SOURCE +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# undef _GNU_SOURCE +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# undef _POSIX_PTHREAD_SEMANTICS +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# undef _TANDEM_SOURCE +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# undef __EXTENSIONS__ +#endif + /* Version number of package */ #undef VERSION -/* The semun structure is undefined */ -#undef _SEM_SEMUN_UNDEFINED +/* Define to 1 if on MINIX. */ +#undef _MINIX + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +#undef _POSIX_1_SOURCE + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +#undef _POSIX_SOURCE /* Define for Solaris 2.5.1 so the uint32_t typedef from , , or is not used. If the typedef were allowed, the @@ -397,6 +448,10 @@ /* Define to `int' if doesn't define. */ #undef uid_t +/* Define to the type of an unsigned integer type of width exactly 16 bits if + such a type exists and the standard includes do not define it. */ +#undef uint16_t + /* Define to the type of an unsigned integer type of width exactly 32 bits if such a type exists and the standard includes do not define it. */ #undef uint32_t diff --git a/include/os_base.h b/include/os_base.h index 1420fe5..584f874 100644 --- a/include/os_base.h +++ b/include/os_base.h @@ -25,10 +25,6 @@ #include #endif /* HAVE_CONFIG_H */ -#ifndef _GNU_SOURCE -#define _GNU_SOURCE 1 -#endif /* _GNU_SOURCE */ - #include #include #include @@ -45,6 +41,10 @@ #include #endif /* HAVE_STDINT_H */ +#ifdef HAVE_STDDEF_H +#include +#endif /* HAVE_STDDEF_H */ + #ifdef HAVE_INTTYPES_H #include #endif @@ -107,24 +107,55 @@ #define HAVE_EPOLL 1 #endif /* HAVE_EPOLL_CREATE */ -/* - * Darwin claims to support process shared synchronization - * but it really does not. The unistd.h header file is wrong. +#if defined(__UCLIBC__) + #define DISABLE_POSIX_THREAD_PROCESS_SHARED 1 +#endif + +/* The pshared semaphore madness: + * To have a usable pshared semaphore we need the timed_wait api + * and pshared functionality. + * + * The order of choice is: + * 1) real posix sem -> HAVE_POSIX_PSHARED_SEMAPHORE + * 2) sysv sems (if we have semtimedop) -> HAVE_SYSV_PSHARED_SEMAPHORE + * 3) faked sems using pthread_cond_timedwait -> HAVE_RPL_PSHARED_SEMAPHORE + * 4) ENOTSUP */ -#if defined(DISABLE_POSIX_THREAD_PROCESS_SHARED) || defined(__UCLIBC__) -#undef HAVE_POSIX_SHARED_SEMAPHORE -#undef HAVE_PTHREAD_SHARED_SPIN_LOCK -#else -#if _POSIX_THREAD_PROCESS_SHARED > 0 -#define HAVE_POSIX_SHARED_SEMAPHORE 1 +#undef HAVE_POSIX_PSHARED_SEMAPHORE +#undef HAVE_SYSV_PSHARED_SEMAPHORE +#undef HAVE_RPL_PSHARED_SEMAPHORE -#if defined(HAVE_PTHREAD_SPIN_LOCK) -#define HAVE_PTHREAD_SHARED_SPIN_LOCK 1 -#endif /* HAVE_PTHREAD_SPIN_LOCK */ - -#endif /* _POSIX_THREAD_PROCESS_SHARED */ +#if defined(DISABLE_POSIX_THREAD_PROCESS_SHARED) + #undef HAVE_PTHREAD_SHARED_SPIN_LOCK #endif /* DISABLE_POSIX_THREAD_PROCESS_SHARED */ +#if !defined(DISABLE_POSIX_THREAD_PROCESS_SHARED) && \ + _POSIX_THREAD_PROCESS_SHARED > 0 + + #if defined(HAVE_PTHREAD_SPIN_LOCK) + #define HAVE_PTHREAD_SHARED_SPIN_LOCK 1 + #endif /* HAVE_PTHREAD_SPIN_LOCK */ + + #if defined(HAVE_SEM_TIMEDWAIT) + #define HAVE_POSIX_PSHARED_SEMAPHORE 1 + #else + #if defined(HAVE_PTHREAD_CONDATTR_SETPSHARED) && \ + defined(HAVE_PTHREAD_MUTEXATTR_SETPSHARED) + #define HAVE_RPL_PSHARED_SEMAPHORE 1 + #endif + #endif /* HAVE_SEM_TIMEDWAIT */ +#endif /* posix pshared */ + +#ifdef HAVE_SEMTIMEDOP +#define HAVE_SYSV_PSHARED_SEMAPHORE 1 +#endif /* HAVE_SEM_TIMEDWAIT */ + +#if !defined(HAVE_SYSV_PSHARED_SEMAPHORE) && \ + !defined(HAVE_POSIX_PSHARED_SEMAPHORE) && \ + !defined(HAVE_RPL_PSHARED_SEMAPHORE) +#define DISABLE_IPC_SHM 1 +#endif /* HAVE PSHARED SEMAPHORE */ + #ifndef HAVE_STRCHRNUL char *strchrnul (const char *s, int c_in); #endif @@ -137,4 +168,11 @@ size_t strlcpy(char *dest, const char *src, size_t maxlen); size_t strlcat(char *dest, const char *src, size_t maxlen); #endif +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif +#ifndef NAME_MAX +#define NAME_MAX 255 +#endif + #endif /* QB_OS_BASE_H_DEFINED */ diff --git a/include/qb/Makefile.in b/include/qb/Makefile.in index d771f7a..fe5acbd 100644 --- a/include/qb/Makefile.in +++ b/include/qb/Makefile.in @@ -154,7 +154,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ diff --git a/include/qb/qbipc_common.h b/include/qb/qbipc_common.h index 269de56..0a4118c 100644 --- a/include/qb/qbipc_common.h +++ b/include/qb/qbipc_common.h @@ -47,6 +47,7 @@ enum qb_ipc_type { QB_IPC_SHM, QB_IPC_POSIX_MQ, QB_IPC_SYSV_MQ, + QB_IPC_NATIVE, }; diff --git a/include/qb/qbipcc.h b/include/qb/qbipcc.h index a55848f..98ba456 100644 --- a/include/qb/qbipcc.h +++ b/include/qb/qbipcc.h @@ -106,6 +106,10 @@ int32_t qb_ipcc_fc_enable_max_set(qb_ipcc_connection_t * c, uint32_t max); * @param msg_ptr pointer to a message to send * @param msg_len the size of the message * @return (size sent, -errno == error) + * + * @note the msg_ptr must include a qb_ipc_request_header at + * the top of the message. The server will read the size field + * to determine how much to recv. */ ssize_t qb_ipcc_send(qb_ipcc_connection_t* c, const void *msg_ptr, size_t msg_len); @@ -116,6 +120,9 @@ ssize_t qb_ipcc_send(qb_ipcc_connection_t* c, const void *msg_ptr, * @param iov pointer to an iovec struct to send * @param iov_len the number of iovecs used * @return (size sent, -errno == error) + * + * @note the iov[0] must be a qb_ipc_request_header. The server will + * read the size field to determine how much to recv. */ ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov, size_t iov_len); @@ -127,6 +134,9 @@ ssize_t qb_ipcc_sendv(qb_ipcc_connection_t* c, const struct iovec* iov, * @param msg_len the size of the buffer * @param ms_timeout max time to wait for a response * @return (size recv'ed, -errno == error) + * + * @note that msg_ptr will include a qb_ipc_response_header at + * the top of the message. */ ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr, size_t msg_len, int32_t ms_timeout); @@ -141,6 +151,12 @@ ssize_t qb_ipcc_recv(qb_ipcc_connection_t* c, void *msg_ptr, * @param msg_len the size of the buffer * @param ms_timeout max time to wait for a response * + * @note the iov[0] must include a qb_ipc_request_header at + * the top of the message. The server will read the size field + * to determine how much to recv. + * @note that msg_ptr will include a qb_ipc_response_header at + * the top of the message. + * * @see qb_ipcc_sendv() qb_ipcc_recv() */ ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c, @@ -158,6 +174,9 @@ ssize_t qb_ipcc_sendv_recv(qb_ipcc_connection_t *c, * 0 == no wait, negative == block, positive == wait X ms. * @param ms_timeout max time to wait for a response * @return size of the message or error (-errno) + * + * @note that msg_ptr will include a qb_ipc_response_header at + * the top of the message. */ ssize_t qb_ipcc_event_recv(qb_ipcc_connection_t* c, void *msg_ptr, size_t msg_len, int32_t ms_timeout); @@ -180,6 +199,14 @@ void qb_ipcc_context_set(qb_ipcc_connection_t *c, void *context); */ void *qb_ipcc_context_get(qb_ipcc_connection_t *c); +/** + * Is the connection connected? + * + * @param c connection instance + * @retval QB_TRUE when connected + * @retval QB_FALSE when not connected + */ +int32_t qb_ipcc_is_connected(qb_ipcc_connection_t *c); /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/include/qb/qbipcs.h b/include/qb/qbipcs.h index c1aeffe..798d075 100644 --- a/include/qb/qbipcs.h +++ b/include/qb/qbipcs.h @@ -73,6 +73,18 @@ struct qb_ipcs_connection_stats { uint64_t flow_control_count; }; +struct qb_ipcs_connection_stats_2 { + int32_t client_pid; + uint64_t requests; + uint64_t responses; + uint64_t events; + uint64_t send_retries; + uint64_t recv_retries; + int32_t flow_control_state; + uint64_t flow_control_count; + uint32_t event_q_length; +}; + typedef int32_t (*qb_ipcs_dispatch_fn_t) (int32_t fd, int32_t revents, void *data); @@ -105,8 +117,11 @@ struct qb_ipcs_poll_handlers { * The type of checks you should do are authentication, service availabilty * or process resource constraints. * @return 0 to accept or -errno to indicate a failure (sent back to the client) + * + * @note you can call qb_ipcs_connection_auth_set() within this function. */ -typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, uid_t uid, gid_t gid); +typedef int32_t (*qb_ipcs_connection_accept_fn) (qb_ipcs_connection_t *c, + uid_t uid, gid_t gid); /** * This is called after a new connection has been created. @@ -198,7 +213,8 @@ void qb_ipcs_destroy(qb_ipcs_service_t* s); * @param s service instance * @param rl the new rate */ -void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, enum qb_ipcs_rate_limit rl); +void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, + enum qb_ipcs_rate_limit rl); /** * Send a response to a incomming request. @@ -207,8 +223,13 @@ void qb_ipcs_request_rate_limit(qb_ipcs_service_t* s, enum qb_ipcs_rate_limit rl * @param data the message to send * @param size the size of the message * @return size sent or -errno for errors + * + * @note the data must include a qb_ipc_response_header at + * the top of the message. The client will read the size field + * to determine how much to recv. */ -ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, size_t size); +ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, + size_t size); /** * Send a response to a incomming request. @@ -217,8 +238,12 @@ ssize_t qb_ipcs_response_send(qb_ipcs_connection_t *c, const void *data, size_t * @param iov the iovec struct that points to the message to send * @param iov_len the number of iovecs. * @return size sent or -errno for errors + * + * @note the iov[0] must be a qb_ipc_response_header. The client will + * read the size field to determine how much to recv. */ -ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len); +ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, + const struct iovec * iov, size_t iov_len); /** * Send an asyncronous event message to the client. @@ -227,8 +252,13 @@ ssize_t qb_ipcs_response_sendv(qb_ipcs_connection_t *c, const struct iovec * iov * @param data the message to send * @param size the size of the message * @return size sent or -errno for errors + * + * @note the data must include a qb_ipc_response_header at + * the top of the message. The client will read the size field + * to determine how much to recv. */ -ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, size_t size); +ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, + size_t size); /** * Send an asyncronous event message to the client. @@ -237,8 +267,12 @@ ssize_t qb_ipcs_event_send(qb_ipcs_connection_t *c, const void *data, size_t siz * @param iov the iovec struct that points to the message to send * @param iov_len the number of iovecs. * @return size sent or -errno for errors + * + * @note the iov[0] must be a qb_ipc_response_header. The client will + * read the size field to determine how much to recv. */ -ssize_t qb_ipcs_event_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, size_t iov_len); +ssize_t qb_ipcs_event_sendv(qb_ipcs_connection_t *c, const struct iovec * iov, + size_t iov_len); /** * Increment the connection's reference counter. @@ -290,6 +324,7 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c); /** * Get the connection statistics. * + * @deprecated from v0.13.0 onwards, use qb_ipcs_connection_stats_get_2 * @param stats (out) the statistics structure * @param clear_after_read clear stats after copying them into stats * @param c connection instance @@ -298,6 +333,17 @@ void *qb_ipcs_context_get(qb_ipcs_connection_t *c); int32_t qb_ipcs_connection_stats_get(qb_ipcs_connection_t *c, struct qb_ipcs_connection_stats* stats, int32_t clear_after_read); +/** + * Get (and allocate) the connection statistics. + * + * @param clear_after_read clear stats after copying them into stats + * @param c connection instance + * @retval NULL if no memory or invalid connection + * @retval allocated statistics structure (user must free it). + */ +struct qb_ipcs_connection_stats_2* +qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c, + int32_t clear_after_read); /** * Get the service statistics. @@ -333,6 +379,23 @@ qb_ipcs_connection_t * qb_ipcs_connection_first_get(qb_ipcs_service_t* pt); qb_ipcs_connection_t * qb_ipcs_connection_next_get(qb_ipcs_service_t* pt, qb_ipcs_connection_t *current); +/** + * Set the permissions on and shared memory files so that both processes can + * read and write to them. + * + * @param conn connection instance + * @param uid the user id to set. + * @param gid the group id to set. + * @param mode the mode to set. + * + * @see chmod() chown() + * @note this must be called within the qb_ipcs_connection_accept_fn() + * callback. + */ +void qb_ipcs_connection_auth_set(qb_ipcs_connection_t *conn, uid_t uid, + gid_t gid, mode_t mode); + + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/include/qb/qblog.h b/include/qb/qblog.h index 1b88f18..45f0e03 100644 --- a/include/qb/qblog.h +++ b/include/qb/qblog.h @@ -98,6 +98,12 @@ extern "C" { * LOG_INFO - LOG_DEBUG); * @endcode * + * To ensure all logs to file targets are fsync'ed (default QB_FALSE) + * @code + * qb_log_ctl(mytarget, QB_LOG_CONF_FILE_SYNC, QB_TRUE); + * @endcode + * + * * @par Filtering messages. * To have more power over what log messages go to which target you can apply * filters to the targets. What happens is the desired callsites have the @@ -393,6 +399,7 @@ enum qb_log_conf { QB_LOG_CONF_THREADED, QB_LOG_CONF_PRIORITY_BUMP, QB_LOG_CONF_STATE_GET, + QB_LOG_CONF_FILE_SYNC, }; enum qb_log_filter_type { diff --git a/include/qb/qbloop.h b/include/qb/qbloop.h index 377e638..9f09c7e 100644 --- a/include/qb/qbloop.h +++ b/include/qb/qbloop.h @@ -239,7 +239,7 @@ int32_t qb_loop_poll_del(qb_loop_t *l, int32_t fd); * * @param l pointer to the loop instance * @param p the priority - * @param signal (SIGHUP or SIGINT) etc .... + * @param sig (SIGHUP or SIGINT) etc .... * @param data user data passed into the dispatch function * @param dispatch_fn callback function * @param handle (out) a reference to the signal job @@ -247,7 +247,7 @@ int32_t qb_loop_poll_del(qb_loop_t *l, int32_t fd); */ int32_t qb_loop_signal_add(qb_loop_t *l, enum qb_loop_priority p, - int32_t signal, + int32_t sig, void *data, qb_loop_signal_dispatch_fn dispatch_fn, qb_loop_signal_handle *handle); @@ -257,7 +257,7 @@ int32_t qb_loop_signal_add(qb_loop_t *l, * * @param l pointer to the loop instance * @param p the priority - * @param signal (SIGHUP or SIGINT) etc .... + * @param sig (SIGHUP or SIGINT) etc .... * @param data user data passed into the dispatch function * @param dispatch_fn callback function * @param handle (in) a reference to the signal job @@ -265,7 +265,7 @@ int32_t qb_loop_signal_add(qb_loop_t *l, */ int32_t qb_loop_signal_mod(qb_loop_t *l, enum qb_loop_priority p, - int32_t signal, + int32_t sig, void *data, qb_loop_signal_dispatch_fn dispatch_fn, qb_loop_signal_handle handle); diff --git a/include/qb/qbrb.h b/include/qb/qbrb.h index c3a99ae..fd37626 100644 --- a/include/qb/qbrb.h +++ b/include/qb/qbrb.h @@ -99,6 +99,13 @@ extern "C" { */ #define QB_RB_FLAG_SHARED_PROCESS 0x08 +/** + * Don't use semaphores, only atomic ops. + * This mean that the timeout passed into qb_rb_chunk_read() + * will be ignored. + */ +#define QB_RB_FLAG_NO_SEMAPHORE 0x10 + struct qb_ringbuffer_s; typedef struct qb_ringbuffer_s qb_ringbuffer_t; @@ -278,6 +285,14 @@ qb_ringbuffer_t *qb_rb_create_from_file(int32_t fd, uint32_t flags); */ int32_t qb_rb_chown(qb_ringbuffer_t * rb, uid_t owner, gid_t group); +/** + * Like 'chmod' it changes the mode of the ringbuffers resources. + * @param mode mode to change to + * @param rb ringbuffer instance + * @retval 0 == ok + * @retval -errno for error + */ +int32_t qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode); /* *INDENT-OFF* */ #ifdef __cplusplus diff --git a/include/tlist.h b/include/tlist.h index e9d25c2..18b6f6e 100644 --- a/include/tlist.h +++ b/include/tlist.h @@ -32,7 +32,7 @@ typedef void *timer_handle; #define TIMER_HANDLE #endif -static int64_t timerlist_hertz = HZ; +static int64_t timerlist_hertz; struct timerlist { struct qb_list_head timer_head; diff --git a/lib/Makefile.am b/lib/Makefile.am index 14a00a8..6d1ba43 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -21,26 +21,49 @@ MAINTAINERCLEANFILES = Makefile.in -noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h log_int.h map_int.h +noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \ + log_int.h map_int.h rpl_sem.h loop_poll_int.h -# -# Here are a set of rules to help you update your library version information: -# Start with version information of ‘0:0:0’ for each libtool library. -# Update the version information only immediately before a public release of your software. -# More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster. -# If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’). -# If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. -# If any interfaces have been added since the last public release, then increment age. -# If any interfaces have been removed since the last public release, then set age to 0. -# AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include lib_LTLIBRARIES = libqb.la -libqb_la_LDFLAGS = -version-info 11:1:11 -source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \ - loop.c loop_poll.c loop_job.c loop_timerlist.c \ - ipcc.c ipcs.c ipc_shm.c ipc_us.c \ +# From: http://sourceware.org/autobook/autobook/autobook_91.html +# (for my own sanity). +# +# 1) If you have changed any of the sources for this library, the revision +# number must be incremented. This is a new revision of the current +# interface. +# +# 2) If the interface has changed, then current must be incremented, and +# revision reset to `0'. This is the first revision of a new interface. +# +# 3) If the new interface is a superset of the previous interface +# (that is, if the previous interface has not been broken by the changes +# in this new release), then age must be incremented. This release is +# backwards compatible with the previous release. +# +# 4) If the new interface has removed elements with respect to the previous +# interface, then you have broken backward compatibility and age must be +# reset to `0'. This release has a new, but backwards incompatible +# interface. For example, if the next release of the library included +# some new commands for an existing socket protocol, you would use +# -version-info 1:0:1. This is the first revision of a new interface. +# This release is backwards compatible with the previous release. +# Later, you implement a faster way of handling part of the algorithm +# at the core of the library, and release it with -version-info 1:1:1. +# This is a new revision of the current interface. +# Unfortunately the speed of your new implementation can only be fully +# exploited by changing the API to access the structures at a lower level, +# which breaks compatibility with the previous interface, so you release +# it as -version-info 2:0:0. This release has a new, but backwards +# incompatible interface. +# +libqb_la_LDFLAGS = -version-info 14:2:14 + +source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \ + array.c loop.c loop_poll.c loop_job.c \ + loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c \ log.c log_thread.c log_blackbox.c log_file.c \ log_syslog.c log_dcs.c log_format.c \ map.c skiplist.c hashtable.c trie.c @@ -48,13 +71,21 @@ source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \ libqb_la_SOURCES = $(source_to_lint) unix.c libqb_la_LIBADD = @LTLIBOBJS@ -if HAVE_SYSV_MQ - libqb_la_SOURCES+=ipc_sysv_mq.c +if HAVE_SEM_TIMEDWAIT +else + libqb_la_SOURCES+=rpl_sem.c endif -if HAVE_POSIX_MQ - libqb_la_SOURCES+=ipc_posix_mq.c +if HAVE_EPOLL + libqb_la_SOURCES+=loop_poll_epoll.c +else +if HAVE_KQUEUE + libqb_la_SOURCES+=loop_poll_kqueue.c +else + libqb_la_SOURCES+=loop_poll_poll.c endif +endif + pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libqb.pc @@ -62,8 +93,11 @@ pkgconfig_DATA = libqb.pc if HAVE_SPLINT check_SCRIPTS = run_splint.sh TESTS = $(check_SCRIPTS) +# this is a hack because debian/ubuntu don't set the arch path +# in splint. +DEB_INCLUDES = -I/usr/include/x86_64-linux-gnu -I/usr/include/i386-linux-gnu -ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEB_INCLUDES) \ $(libqb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) \ $(LINT_FLAGS) diff --git a/lib/Makefile.in b/lib/Makefile.in index c02915d..e292f6f 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -56,8 +56,10 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -@HAVE_SYSV_MQ_TRUE@am__append_1 = ipc_sysv_mq.c -@HAVE_POSIX_MQ_TRUE@am__append_2 = ipc_posix_mq.c +@HAVE_SEM_TIMEDWAIT_FALSE@am__append_1 = rpl_sem.c +@HAVE_EPOLL_TRUE@am__append_2 = loop_poll_epoll.c +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@am__append_3 = loop_poll_kqueue.c +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@am__append_4 = loop_poll_poll.c subdir = lib DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/libqb.pc.in strchrnul.c \ @@ -109,16 +111,21 @@ am__libqb_la_SOURCES_DIST = util.c hdb.c ringbuffer.c \ loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c log.c \ log_thread.c log_blackbox.c log_file.c log_syslog.c log_dcs.c \ log_format.c map.c skiplist.c hashtable.c trie.c unix.c \ - ipc_sysv_mq.c ipc_posix_mq.c + rpl_sem.c loop_poll_epoll.c loop_poll_kqueue.c \ + loop_poll_poll.c am__objects_1 = util.lo hdb.lo ringbuffer.lo ringbuffer_helper.lo \ array.lo loop.lo loop_poll.lo loop_job.lo loop_timerlist.lo \ ipcc.lo ipcs.lo ipc_shm.lo ipc_us.lo log.lo log_thread.lo \ log_blackbox.lo log_file.lo log_syslog.lo log_dcs.lo \ log_format.lo map.lo skiplist.lo hashtable.lo trie.lo -@HAVE_SYSV_MQ_TRUE@am__objects_2 = ipc_sysv_mq.lo -@HAVE_POSIX_MQ_TRUE@am__objects_3 = ipc_posix_mq.lo +@HAVE_SEM_TIMEDWAIT_FALSE@am__objects_2 = rpl_sem.lo +@HAVE_EPOLL_TRUE@am__objects_3 = loop_poll_epoll.lo +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@am__objects_4 = \ +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_TRUE@ loop_poll_kqueue.lo +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@am__objects_5 = \ +@HAVE_EPOLL_FALSE@@HAVE_KQUEUE_FALSE@ loop_poll_poll.lo am_libqb_la_OBJECTS = $(am__objects_1) unix.lo $(am__objects_2) \ - $(am__objects_3) + $(am__objects_3) $(am__objects_4) $(am__objects_5) libqb_la_OBJECTS = $(am_libqb_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -127,7 +134,7 @@ libqb_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libqb_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -158,106 +165,8 @@ DATA = $(pkgconfig_DATA) HEADERS = $(noinst_HEADERS) ETAGS = etags CTAGS = ctags -# If stdout is a non-dumb tty, use colors. If test -t is not supported, -# then this fails; a conservative approach. Of course do not redirect -# stdout here, just stderr. am__tty_colors = \ -red=; grn=; lgn=; blu=; std=; \ -test "X$(AM_COLOR_TESTS)" != Xno \ -&& test "X$$TERM" != Xdumb \ -&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \ -&& { \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - std=''; \ -} -# Restructured Text title and section. -am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//' -am__rst_section = sed 'p;s/./=/g;p;g' -# Put stdin (possibly several lines separated by ". ") in a box. -# Prefix each line by 'col' and terminate each with 'std', for coloring. -# Multi line coloring is problematic with "less -R", so we really need -# to color each line individually. -am__text_box = $(AWK) '{ \ - n = split($$0, lines, "\\. "); max = 0; \ - for (i = 1; i <= n; ++i) \ - if (max < length(lines[i])) \ - max = length(lines[i]); \ - for (i = 0; i < max; ++i) \ - line = line "="; \ - print col line std; \ - for (i = 1; i <= n; ++i) \ - if (lines[i]) \ - print col lines[i] std; \ - print col line std; \ -}' -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log, and passes -# TESTS_ENVIRONMENT. Save and restore TERM around use of -# TESTS_ENVIRONMENT, in case that unsets it. -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -srcdir=$(srcdir); export srcdir; \ -rm -f $@-t; \ -am__trap='rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st'; \ -trap "st=129; $$am__trap" 1; trap "st=130; $$am__trap" 2; \ -trap "st=141; $$am__trap" 13; trap "st=143; $$am__trap" 15; \ -am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \ -test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \ -$(TESTS_ENVIRONMENT) -# To be appended to the command running the test. Handle the stdout -# and stderr redirection, and catch the exit status. -am__check_post = \ ->$@-t 2>&1; \ -estatus=$$?; \ -if test -n '$(DISABLE_HARD_ERRORS)' \ - && test $$estatus -eq 99; then \ - estatus=1; \ -fi; \ -TERM=$$__SAVED_TERM; export TERM; \ -$(am__tty_colors); \ -xfailed=PASS; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - xfailed=XFAIL;; \ -esac; \ -case $$estatus.$$xfailed in \ - 0.XFAIL) col=$$red; res=XPASS;; \ - 0.*) col=$$grn; res=PASS ;; \ - 77.*) col=$$blu; res=SKIP ;; \ - 99.*) col=$$red; res=FAIL ;; \ - *.XFAIL) col=$$lgn; res=XFAIL;; \ - *.*) col=$$red; res=FAIL ;; \ -esac; \ -echo "$${col}$$res$${std}: $$f"; \ -echo "$$res: $$f (exit: $$estatus)" | \ - $(am__rst_section) >$@; \ -cat $@-t >>$@; \ -rm -f $@-t -RECHECK_LOGS = $(TEST_LOGS) -AM_RECURSIVE_TARGETS = check recheck check-html recheck-html -TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t) +red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -305,7 +214,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -393,43 +301,69 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ MAINTAINERCLEANFILES = Makefile.in -noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h log_int.h map_int.h +noinst_HEADERS = ipc_int.h util_int.h ringbuffer_int.h loop_int.h \ + log_int.h map_int.h rpl_sem.h loop_poll_int.h -# -# Here are a set of rules to help you update your library version information: -# Start with version information of ‘0:0:0’ for each libtool library. -# Update the version information only immediately before a public release of your software. -# More frequent updates are unnecessary, and only guarantee that the current interface number gets larger faster. -# If the library source code has changed at all since the last update, then increment revision (‘c:r:a’ becomes ‘c:r+1:a’). -# If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0. -# If any interfaces have been added since the last public release, then increment age. -# If any interfaces have been removed since the last public release, then set age to 0. -# AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include lib_LTLIBRARIES = libqb.la -libqb_la_LDFLAGS = -version-info 11:1:11 -source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c array.c \ - loop.c loop_poll.c loop_job.c loop_timerlist.c \ - ipcc.c ipcs.c ipc_shm.c ipc_us.c \ + +# From: http://sourceware.org/autobook/autobook/autobook_91.html +# (for my own sanity). +# +# 1) If you have changed any of the sources for this library, the revision +# number must be incremented. This is a new revision of the current +# interface. +# +# 2) If the interface has changed, then current must be incremented, and +# revision reset to `0'. This is the first revision of a new interface. +# +# 3) If the new interface is a superset of the previous interface +# (that is, if the previous interface has not been broken by the changes +# in this new release), then age must be incremented. This release is +# backwards compatible with the previous release. +# +# 4) If the new interface has removed elements with respect to the previous +# interface, then you have broken backward compatibility and age must be +# reset to `0'. This release has a new, but backwards incompatible +# interface. For example, if the next release of the library included +# some new commands for an existing socket protocol, you would use +# -version-info 1:0:1. This is the first revision of a new interface. +# This release is backwards compatible with the previous release. +# Later, you implement a faster way of handling part of the algorithm +# at the core of the library, and release it with -version-info 1:1:1. +# This is a new revision of the current interface. +# Unfortunately the speed of your new implementation can only be fully +# exploited by changing the API to access the structures at a lower level, +# which breaks compatibility with the previous interface, so you release +# it as -version-info 2:0:0. This release has a new, but backwards +# incompatible interface. +# +libqb_la_LDFLAGS = -version-info 14:2:14 +source_to_lint = util.c hdb.c ringbuffer.c ringbuffer_helper.c \ + array.c loop.c loop_poll.c loop_job.c \ + loop_timerlist.c ipcc.c ipcs.c ipc_shm.c ipc_us.c \ log.c log_thread.c log_blackbox.c log_file.c \ log_syslog.c log_dcs.c log_format.c \ map.c skiplist.c hashtable.c trie.c libqb_la_SOURCES = $(source_to_lint) unix.c $(am__append_1) \ - $(am__append_2) + $(am__append_2) $(am__append_3) $(am__append_4) libqb_la_LIBADD = @LTLIBOBJS@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libqb.pc @HAVE_SPLINT_TRUE@check_SCRIPTS = run_splint.sh @HAVE_SPLINT_TRUE@TESTS = $(check_SCRIPTS) -@HAVE_SPLINT_TRUE@ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ +# this is a hack because debian/ubuntu don't set the arch path +# in splint. +@HAVE_SPLINT_TRUE@DEB_INCLUDES = -I/usr/include/x86_64-linux-gnu -I/usr/include/i386-linux-gnu +@HAVE_SPLINT_TRUE@ALL_LINT_FLAGS = $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(DEB_INCLUDES) \ @HAVE_SPLINT_TRUE@ $(libqb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CPPFLAGS) \ @HAVE_SPLINT_TRUE@ $(LINT_FLAGS) all: all-am .SUFFIXES: -.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT) +.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -508,9 +442,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hashtable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_posix_mq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_shm.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_sysv_mq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipc_us.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipcc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipcs.Plo@am__quote@ @@ -524,10 +456,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_job.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_epoll.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_kqueue.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_poll_poll.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/loop_timerlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ringbuffer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ringbuffer_helper.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rpl_sem.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/skiplist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/trie.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unix.Plo@am__quote@ @@ -630,139 +566,98 @@ GTAGS: distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__sh_e_setup); \ - list='$(TEST_LOGS)'; \ - results=`for f in $$list; do \ - test -r $$f && read line < $$f && echo "$$line" \ - || echo FAIL; \ - done`; \ - all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \ - fail=`echo "$$results" | grep -c '^FAIL'`; \ - pass=`echo "$$results" | grep -c '^PASS'`; \ - skip=`echo "$$results" | grep -c '^SKIP'`; \ - xfail=`echo "$$results" | grep -c '^XFAIL'`; \ - xpass=`echo "$$results" | grep -c '^XPASS'`; \ - failures=`expr $$fail + $$xpass`; \ - all=`expr $$all - $$skip`; \ - if test "$$all" -eq 1; then tests=test; All=; \ - else tests=tests; All="All "; fi; \ - case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \ - fail=0:xpass=0:xfail=0) \ - msg="$$All$$all $$tests passed. "; \ - exit=true;; \ - fail=0:xpass=0:xfail=*) \ - msg="$$All$$all $$tests behaved as expected"; \ - if test "$$xfail" -eq 1; then xfailures=failure; \ - else xfailures=failures; fi; \ - msg="$$msg ($$xfail expected $$xfailures). "; \ - exit=true;; \ - fail=*:xpass=0:xfail=*) \ - msg="$$fail of $$all $$tests failed. "; \ - exit=false;; \ - fail=*:xpass=*:xfail=*) \ - msg="$$failures of $$all $$tests did not behave as expected"; \ - if test "$$xpass" -eq 1; then xpasses=pass; \ - else xpasses=passes; fi; \ - msg="$$msg ($$xpass unexpected $$xpasses). "; \ - exit=false;; \ - *) \ - echo >&2 "incorrect case"; exit 4;; \ - esac; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - msg="$$msg($$skip test was not run). "; \ - else \ - msg="$$msg($$skip tests were not run). "; \ - fi; \ - fi; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - echo "$$msg"; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for f in $$list; do \ - test -r $$f && read line < $$f || line=; \ - case $$line in \ - PASS:*|XFAIL:*);; \ - *) echo; cat $$f;; \ - esac; \ - done; \ - } >$(TEST_SUITE_LOG).tmp; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if test "$$failures" -ne 0; then \ - msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \ - fi; \ - fi; \ - test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \ - $(am__tty_colors); \ - if $$exit; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$$msg" | $(am__text_box) "col=$$col" "std=$$std"; \ - $$exit || exit 1 - -check-TESTS recheck: - @if test $@ != recheck; then \ - list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list; \ - fi - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @list='' list2='$(TEST_LOGS)'; for f in $$list2; do \ - test .log = $$f && continue; \ - if test $@ = recheck; then \ - test -f $$f || continue; \ - if test -r $$f && read line < $$f; then \ - case $$line in FAIL*|XPASS*) : ;; *) continue;; esac; \ +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ - if test -z "$$list"; then list=$$f; else list="$$list $$f"; fi; \ - done; \ - if test $@ = recheck && test -n "$$list"; then \ - echo "am--clean: ; rm -f $$list" \ - | $(MAKE) $(AM_MAKEFLAGS) -f - am--clean || exit 1; \ - fi; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$list" -recheck: $(check_SCRIPTS) - -am--mostlyclean-test-html: - list='$(TEST_LOGS:.log=.html)'; test -z "$$list" || rm -f $$list - rm -f $(TEST_SUITE_HTML) - -.log.html: - @list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \ - for r2h in $$list; do \ - if ($$r2h --version) >/dev/null 2>&1; then \ - R2H=$$r2h; \ - fi; \ - done; \ - if test -z "$$R2H"; then \ - echo >&2 "cannot find rst2html, cannot create $@"; \ - exit 2; \ - fi; \ - $$R2H $< >$@.tmp - @mv $@.tmp $@ - -# Be sure to run check first, and then to convert the result. -# Beware of concurrent executions. Run "check" not "check-TESTS", as -# check-SCRIPTS and other dependencies are rebuilt by the former only. -# And expect check to fail. -check-html recheck-html: - @target=`echo $@ | sed 's/-html$$//'`; \ - rv=0; $(MAKE) $(AM_MAKEFLAGS) $$target || rv=$$?; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) TEST_LOGS= || exit 4; \ - exit $$rv -run_splint.sh.log: run_splint.sh - @p='run_splint.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) -.test.log: - @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -823,9 +718,6 @@ install-strip: "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @HAVE_SPLINT_FALSE@clean-generic: @@ -895,8 +787,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: am--mostlyclean-test-html mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf: pdf-am @@ -908,22 +800,21 @@ ps-am: uninstall-am: uninstall-libLTLIBRARIES uninstall-pkgconfigDATA -.MAKE: check-am check-html install-am install-strip recheck-html +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS all all-am am--mostlyclean-test-html check \ - check-TESTS check-am check-html clean clean-generic \ - clean-libLTLIBRARIES clean-libtool ctags distclean \ - distclean-compile distclean-generic distclean-libtool \ - distclean-tags distdir dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-man install-pdf install-pdf-am \ - install-pkgconfigDATA install-ps install-ps-am install-strip \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck recheck-html tags uninstall uninstall-am \ +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libLTLIBRARIES clean-libtool ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-libLTLIBRARIES install-man install-pdf \ + install-pdf-am install-pkgconfigDATA install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ + pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-libLTLIBRARIES uninstall-pkgconfigDATA diff --git a/lib/array.c b/lib/array.c index 7f5199a..d091f17 100644 --- a/lib/array.c +++ b/lib/array.c @@ -103,7 +103,7 @@ qb_array_index(struct qb_array * a, int32_t idx, void **element_out) int32_t b; int32_t elem; char *bin; - int32_t rc; + int32_t rc = 0; if (a == NULL || element_out == NULL) { return -EINVAL; @@ -207,6 +207,7 @@ qb_array_free(struct qb_array *a) for (i = 0; i < a->num_bins; i++) { free(a->bin[i]); } + free(a->bin); (void)qb_thread_lock_destroy(a->grow_lock); free(a); } diff --git a/lib/ipc_int.h b/lib/ipc_int.h index 16bc5c7..9cf70e7 100644 --- a/lib/ipc_int.h +++ b/lib/ipc_int.h @@ -25,9 +25,6 @@ #include "os_base.h" #include -#ifdef HAVE_MQUEUE_H -#include -#endif /* HAVE_MQUEUE_H */ #include #include #include @@ -35,10 +32,6 @@ #include #include -#ifdef HAVE_POSIX_SHARED_SEMAPHORE -#include -#endif /* HAVE_POSIX_SHARED_SEMAPHORE */ - #define QB_IPC_MAX_WAIT_MS 2000 /* @@ -50,23 +43,23 @@ SEND CONN REQ -> */ struct qb_ipc_connection_request { - struct qb_ipc_request_header hdr __attribute__ ((aligned(8))); - uint32_t max_msg_size __attribute__ ((aligned(8))); + struct qb_ipc_request_header hdr; + uint32_t max_msg_size; } __attribute__ ((aligned(8))); struct qb_ipc_event_connection_request { - struct qb_ipc_request_header hdr __attribute__ ((aligned(8))); - intptr_t connection __attribute__ ((aligned(8))); + struct qb_ipc_request_header hdr; + intptr_t connection; } __attribute__ ((aligned(8))); struct qb_ipc_connection_response { - struct qb_ipc_response_header hdr __attribute__ ((aligned(8))); - int32_t connection_type __attribute__ ((aligned(8))); - uint32_t max_msg_size __attribute__ ((aligned(8))); - intptr_t connection __attribute__ ((aligned(8))); - char request[PATH_MAX] __attribute__ ((aligned(8))); - char response[PATH_MAX] __attribute__ ((aligned(8))); - char event[PATH_MAX] __attribute__ ((aligned(8))); + struct qb_ipc_response_header hdr; + int32_t connection_type; + uint32_t max_msg_size; + intptr_t connection; + char request[PATH_MAX]; + char response[PATH_MAX]; + char event[PATH_MAX]; } __attribute__ ((aligned(8))); struct qb_ipcc_connection; @@ -80,16 +73,6 @@ struct qb_ipc_one_way { void* shared_data; char shared_file_name[NAME_MAX]; } us; -#ifdef HAVE_MQUEUE_H - struct { - mqd_t q; - char name[NAME_MAX]; - } pmq; -#endif - struct { - int32_t q; - int32_t key; - } smq; struct { qb_ringbuffer_t *rb; } shm; @@ -122,13 +105,11 @@ int32_t qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response *r); ssize_t qb_ipc_us_send(struct qb_ipc_one_way *one_way, const void *msg, size_t len); ssize_t qb_ipc_us_recv(struct qb_ipc_one_way *one_way, void *msg, size_t len, int32_t timeout); -int32_t qb_ipc_us_recv_ready(struct qb_ipc_one_way *one_way, int32_t ms_timeout); +int32_t qb_ipc_us_ready(struct qb_ipc_one_way *one_way, int32_t ms_timeout, int32_t events); void qb_ipcc_us_sock_close(int32_t sock); -int32_t qb_ipcc_pmq_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response); int32_t qb_ipcc_us_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response); -int32_t qb_ipcc_smq_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response); int32_t qb_ipcc_shm_connect(struct qb_ipcc_connection *c, struct qb_ipc_connection_response * response); struct qb_ipcs_service; @@ -173,12 +154,21 @@ enum qb_ipcs_connection_state { QB_IPCS_CONNECTION_SHUTTING_DOWN, }; +#define CONNECTION_DESCRIPTION (16) + +struct qb_ipcs_connection_auth { + uid_t uid; + gid_t gid; + mode_t mode; +}; + struct qb_ipcs_connection { enum qb_ipcs_connection_state state; int32_t refcount; pid_t pid; uid_t euid; gid_t egid; + struct qb_ipcs_connection_auth auth; struct qb_ipc_one_way setup; struct qb_ipc_one_way request; struct qb_ipc_one_way response; @@ -190,12 +180,11 @@ struct qb_ipcs_connection { int32_t fc_enabled; int32_t poll_events; int32_t outstanding_notifiers; - struct qb_ipcs_connection_stats stats; + char description[CONNECTION_DESCRIPTION]; + struct qb_ipcs_connection_stats_2 stats; }; -void qb_ipcs_pmq_init(struct qb_ipcs_service *s); void qb_ipcs_us_init(struct qb_ipcs_service *s); -void qb_ipcs_smq_init(struct qb_ipcs_service *s); void qb_ipcs_shm_init(struct qb_ipcs_service *s); int32_t qb_ipcs_us_publish(struct qb_ipcs_service *s); @@ -204,8 +193,11 @@ int32_t qb_ipcs_us_withdraw(struct qb_ipcs_service *s); int32_t qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data); int32_t qb_ipcs_dispatch_service_request(int32_t fd, int32_t revents, void *data); struct qb_ipcs_connection* qb_ipcs_connection_alloc(struct qb_ipcs_service *s); +void qb_ipcs_sockets_disconnect(struct qb_ipcs_connection *c); int32_t qb_ipcs_process_request(struct qb_ipcs_service *s, struct qb_ipc_request_header *hdr); +int32_t qb_ipc_us_sock_error_is_disconnected(int err); + #endif /* QB_IPC_INT_H_DEFINED */ diff --git a/lib/ipc_posix_mq.c b/lib/ipc_posix_mq.c deleted file mode 100644 index 6ed29dd..0000000 --- a/lib/ipc_posix_mq.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (C) 2010 Red Hat, Inc. - * - * Author: Angus Salkeld - * - * This file is part of libqb. - * - * libqb is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 of the License, or - * (at your option) any later version. - * - * libqb 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libqb. If not, see . - */ -#include "os_base.h" - -#include -#include -#include "ipc_int.h" -#include "util_int.h" -#include -#include -#include - -#define QB_REQUEST_Q_LEN 3 -#define QB_RESPONSE_Q_LEN 1 -#define QB_EVENT_Q_LEN 3 - -static size_t q_space_used = 0; -#ifdef QB_LINUX -#define QB_RLIMIT_CHANGE_NEEDED 1 -#endif /* QB_LINUX */ - -/* - * utility functions - * -------------------------------------------------------- - */ -static int32_t -posix_mq_increase_limits(size_t max_msg_size, int32_t q_len) -{ - int32_t res = 0; -#ifdef QB_RLIMIT_CHANGE_NEEDED - struct rlimit rlim; - size_t q_space_needed; -#endif /* QB_RLIMIT_CHANGE_NEEDED */ - -#ifdef QB_RLIMIT_CHANGE_NEEDED - if (getrlimit(RLIMIT_MSGQUEUE, &rlim) != 0) { - res = -errno; - qb_util_log(LOG_ERR, "getrlimit failed"); - return res; - } - q_space_needed = q_space_used + (max_msg_size * q_len * 4 / 3); - - qb_util_log(LOG_DEBUG, "rlimit:%d needed:%zu used:%zu", - (int)rlim.rlim_cur, q_space_needed, q_space_used); - - if (rlim.rlim_cur < q_space_needed) { - rlim.rlim_cur = q_space_needed; - } - if (rlim.rlim_max < q_space_needed) { - rlim.rlim_max = q_space_needed; - } - if (setrlimit(RLIMIT_MSGQUEUE, &rlim) != 0) { - res = -errno; - qb_util_log(LOG_ERR, "setrlimit failed"); - } -#endif /* QB_RLIMIT_CHANGE_NEEDED */ - return res; -} - -static int32_t -posix_mq_open(struct qb_ipc_one_way *one_way, const char *name, size_t q_len) -{ - int32_t res = posix_mq_increase_limits(one_way->max_msg_size, q_len); - if (res != 0) { - return res; - } - one_way->u.pmq.q = mq_open(name, O_RDWR); - if (one_way->u.pmq.q == (mqd_t) - 1) { - res = -errno; - perror("mq_open"); - return res; - } - (void)strlcpy(one_way->u.pmq.name, name, NAME_MAX); - q_space_used += one_way->max_msg_size * q_len; - return 0; -} - -static int32_t -posix_mq_create(struct qb_ipcs_connection *c, - struct qb_ipc_one_way *one_way, const char *name, size_t q_len) -{ - struct mq_attr attr; - mqd_t q = 0; - int32_t res = 0; - mode_t m = 0600; - size_t max_msg_size = one_way->max_msg_size; - - res = posix_mq_increase_limits(max_msg_size, q_len); - if (res != 0) { - return res; - } -try_smaller: - if (q != 0) { - max_msg_size = max_msg_size / 2; - q_len--; - } - attr.mq_flags = O_NONBLOCK; - attr.mq_maxmsg = q_len; - attr.mq_msgsize = max_msg_size; - - q = mq_open(name, O_RDWR | O_CREAT | O_EXCL | O_NONBLOCK, m, &attr); - if (q == (mqd_t) - 1 && errno == ENOMEM) { - if (max_msg_size > 9000 && q_len > 3) { - goto try_smaller; - } - } - if (q == (mqd_t) - 1) { - res = -errno; - qb_util_perror(LOG_ERR, "Can't create mq \"%s\"", name); - return res; - } - q_space_used += max_msg_size * q_len; - one_way->max_msg_size = max_msg_size; - one_way->u.pmq.q = q; - (void)strlcpy(one_way->u.pmq.name, name, NAME_MAX); - - res = fchown((int)q, c->euid, c->egid); - if (res == -1) { - res = -errno; - qb_util_perror(LOG_ERR, "fchown:%s", name); - mq_close(q); - mq_unlink(name); - } - - return res; -} - -static ssize_t -qb_ipc_pmq_send(struct qb_ipc_one_way *one_way, - const void *msg_ptr, size_t msg_len) -{ - int32_t res = mq_send(one_way->u.pmq.q, msg_ptr, msg_len, 1); - if (res != 0) { - return -errno; - } - return msg_len; -} - -static ssize_t -qb_ipc_pmq_sendv(struct qb_ipc_one_way *one_way, - const struct iovec *iov, size_t iov_len) -{ - int32_t total_size = 0; - int32_t i; - int32_t res = 0; - char *data = NULL; - char *pt = NULL; - - for (i = 0; i < iov_len; i++) { - total_size += iov[i].iov_len; - } - if (total_size == 0) { - return -EINVAL; - } - data = malloc(total_size); - if (data == NULL) { - return -ENOMEM; - } - pt = data; - - for (i = 0; i < iov_len; i++) { - memcpy(pt, iov[i].iov_base, iov[i].iov_len); - pt += iov[i].iov_len; - } - - res = mq_send(one_way->u.pmq.q, data, total_size, 1); - free(data); - if (res != 0) { - return -errno; - } - return total_size; -} - -static ssize_t -qb_ipc_pmq_recv(struct qb_ipc_one_way *one_way, - void *msg_ptr, size_t msg_len, int32_t ms_timeout) -{ - uint32_t msg_prio; - struct timespec ts_timeout; - ssize_t res; - - if (ms_timeout >= 0) { - qb_util_timespec_from_epoch_get(&ts_timeout); - qb_timespec_add_ms(&ts_timeout, ms_timeout); - } - -mq_receive_again: - if (ms_timeout >= 0) { - res = mq_timedreceive(one_way->u.pmq.q, - (char *)msg_ptr, - one_way->max_msg_size, - &msg_prio, &ts_timeout); - } else { - res = mq_receive(one_way->u.pmq.q, - (char *)msg_ptr, - one_way->max_msg_size, &msg_prio); - } - if (res == -1) { - switch (errno) { - case EINTR: - goto mq_receive_again; - break; - case EAGAIN: - res = -ETIMEDOUT; - break; - case ETIMEDOUT: - res = -errno; - break; - default: - res = -errno; - qb_util_perror(LOG_ERR, - "error waiting for mq_timedreceive"); - break; - } - } - - return res; -} - -/* - * client functions - * -------------------------------------------------------- - */ - -static void -qb_ipcc_pmq_disconnect(struct qb_ipcc_connection *c) -{ - struct qb_ipc_request_header hdr; - - qb_util_log(LOG_DEBUG, "%s()", __func__); - if (c->needs_sock_for_poll) { - return; - } - - hdr.id = QB_IPC_MSG_DISCONNECT; - hdr.size = sizeof(hdr); - mq_send(c->request.u.pmq.q, (const char *)&hdr, hdr.size, 30); - - mq_close(c->event.u.pmq.q); - mq_close(c->response.u.pmq.q); - mq_close(c->request.u.pmq.q); - - mq_unlink(c->event.u.pmq.name); - mq_unlink(c->request.u.pmq.name); - mq_unlink(c->response.u.pmq.name); -} - -int32_t -qb_ipcc_pmq_connect(struct qb_ipcc_connection *c, - struct qb_ipc_connection_response *response) -{ - int32_t res = 0; - - c->funcs.send = qb_ipc_pmq_send; - c->funcs.sendv = qb_ipc_pmq_sendv; - c->funcs.recv = qb_ipc_pmq_recv; - c->funcs.fc_get = NULL; - c->funcs.disconnect = qb_ipcc_pmq_disconnect; -#if defined(QB_LINUX) || defined(QB_BSD) - c->needs_sock_for_poll = QB_FALSE; -#else - c->needs_sock_for_poll = QB_TRUE; -#endif - - if (strlen(c->name) > (NAME_MAX - 20)) { - return -EINVAL; - } - - res = posix_mq_open(&c->request, response->request, QB_REQUEST_Q_LEN); - if (res != 0) { - perror("mq_open:REQUEST"); - return res; - } - res = posix_mq_open(&c->response, response->response, - QB_RESPONSE_Q_LEN); - if (res != 0) { - perror("mq_open:RESPONSE"); - goto cleanup_request; - } - res = posix_mq_open(&c->event, response->event, QB_EVENT_Q_LEN); - if (res != 0) { - perror("mq_open:EVENT"); - goto cleanup_request_response; - } - - return 0; - -cleanup_request_response: - mq_close(c->response.u.pmq.q); - -cleanup_request: - mq_close(c->request.u.pmq.q); - - return res; -} - -/* - * service functions - * -------------------------------------------------------- - */ - -static void -qb_ipcs_pmq_disconnect(struct qb_ipcs_connection *c) -{ - struct qb_ipc_response_header msg; - - msg.id = QB_IPC_MSG_DISCONNECT; - msg.size = sizeof(msg); - msg.error = 0; - - (void)qb_ipc_pmq_send(&c->event, &msg, msg.size); - - mq_close(c->event.u.pmq.q); - mq_close(c->response.u.pmq.q); - mq_close(c->request.u.pmq.q); - - mq_unlink(c->event.u.pmq.name); - mq_unlink(c->request.u.pmq.name); - mq_unlink(c->response.u.pmq.name); -} - -static int32_t -qb_ipcs_pmq_connect(struct qb_ipcs_service *s, - struct qb_ipcs_connection *c, - struct qb_ipc_connection_response *r) -{ - int32_t res = 0; - - snprintf(r->request, NAME_MAX, "/%s-request-%d", s->name, c->pid); - snprintf(r->response, NAME_MAX, "/%s-response-%d", s->name, c->pid); - snprintf(r->event, NAME_MAX, "/%s-event-%d", s->name, c->pid); - - res = posix_mq_create(c, &c->request, r->request, QB_REQUEST_Q_LEN); - if (res < 0) { - goto cleanup; - } - - res = posix_mq_create(c, &c->response, r->response, QB_RESPONSE_Q_LEN); - if (res < 0) { - goto cleanup_request; - } - - res = posix_mq_create(c, &c->event, r->event, QB_EVENT_Q_LEN); - if (res < 0) { - goto cleanup_request_response; - } - - if (!s->needs_sock_for_poll) { - res = - s->poll_fns.dispatch_add(s->poll_priority, - (int32_t) c->request.u.pmq.q, - POLLIN | POLLPRI | POLLNVAL, c, - qb_ipcs_dispatch_service_request); - } - - r->hdr.error = 0; - return res; - -cleanup_request_response: - mq_close(c->response.u.pmq.q); - mq_unlink(r->response); -cleanup_request: - mq_close(c->request.u.pmq.q); - mq_unlink(r->request); - -cleanup: - r->hdr.error = res; - - return res; -} - -static ssize_t -qb_ipc_pmq_q_len_get(struct qb_ipc_one_way *one_way) -{ - struct mq_attr info; - int32_t res = mq_getattr(one_way->u.pmq.q, &info); - if (res == 0) { - return info.mq_curmsgs; - } - return -errno; -} - -void -qb_ipcs_pmq_init(struct qb_ipcs_service *s) -{ - s->funcs.connect = qb_ipcs_pmq_connect; - s->funcs.disconnect = qb_ipcs_pmq_disconnect; - - s->funcs.recv = qb_ipc_pmq_recv; - s->funcs.send = qb_ipc_pmq_send; - s->funcs.sendv = qb_ipc_pmq_sendv; - s->funcs.peek = NULL; - s->funcs.reclaim = NULL; - - s->funcs.fc_set = NULL; - s->funcs.q_len_get = qb_ipc_pmq_q_len_get; - -#if defined(QB_LINUX) || defined(QB_BSD) - s->needs_sock_for_poll = QB_FALSE; -#else - s->needs_sock_for_poll = QB_TRUE; -#endif -} diff --git a/lib/ipc_shm.c b/lib/ipc_shm.c index 752c92e..f719b6b 100644 --- a/lib/ipc_shm.c +++ b/lib/ipc_shm.c @@ -106,10 +106,15 @@ static ssize_t qb_ipc_shm_peek(struct qb_ipc_one_way *one_way, void **data_out, int32_t ms_timeout) { + ssize_t rc; if (one_way->u.shm.rb == NULL) { return -ENOTCONN; } - return qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout); + rc = qb_rb_chunk_peek(one_way->u.shm.rb, data_out, ms_timeout); + if (rc == 0) { + return -EAGAIN; + } + return rc; } static void @@ -233,6 +238,40 @@ qb_ipcs_shm_disconnect(struct qb_ipcs_connection *c) } } +static int32_t +qb_ipcs_shm_rb_open(struct qb_ipcs_connection *c, + struct qb_ipc_one_way *ow, + const char *rb_name) +{ + int32_t res = 0; + + ow->u.shm.rb = qb_rb_open(rb_name, + ow->max_msg_size, + QB_RB_FLAG_CREATE | + QB_RB_FLAG_SHARED_PROCESS, + sizeof(int32_t)); + if (ow->u.shm.rb == NULL) { + res = -errno; + qb_util_perror(LOG_ERR, "qb_rb_open:%s", rb_name); + return res; + } + res = qb_rb_chown(ow->u.shm.rb, c->auth.uid, c->auth.gid); + if (res != 0) { + qb_util_perror(LOG_ERR, "qb_rb_chown:%s", rb_name); + goto cleanup; + } + res = qb_rb_chmod(ow->u.shm.rb, c->auth.mode); + if (res != 0) { + qb_util_perror(LOG_ERR, "qb_rb_chmod:%s", rb_name); + goto cleanup; + } + return res; + +cleanup: + qb_rb_close(ow->u.shm.rb); + return res; +} + static int32_t qb_ipcs_shm_connect(struct qb_ipcs_service *s, struct qb_ipcs_connection *c, @@ -242,66 +281,34 @@ qb_ipcs_shm_connect(struct qb_ipcs_service *s, qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); - snprintf(r->request, NAME_MAX, "%s-request-%d-%d", s->name, c->pid, - c->setup.u.us.sock); - snprintf(r->response, NAME_MAX, "%s-response-%d-%d", s->name, c->pid, - c->setup.u.us.sock); - snprintf(r->event, NAME_MAX, "%s-event-%d-%d", s->name, c->pid, - c->setup.u.us.sock); + snprintf(r->request, NAME_MAX, "%s-request-%s", + s->name, c->description); + snprintf(r->response, NAME_MAX, "%s-response-%s", + s->name, c->description); + snprintf(r->event, NAME_MAX, "%s-event-%s", + s->name, c->description); - c->request.u.shm.rb = qb_rb_open(r->request, - c->request.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, - sizeof(int32_t)); - if (c->request.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:REQUEST"); - goto cleanup; - } - res = qb_rb_chown(c->request.u.shm.rb, c->euid, c->egid); + res = qb_ipcs_shm_rb_open(c, &c->request, + r->request); if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:REQUEST"); goto cleanup; } - c->response.u.shm.rb = qb_rb_open(r->response, - c->response.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, 0); - if (c->response.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:RESPONSE"); - goto cleanup_request; - } - res = qb_rb_chown(c->response.u.shm.rb, c->euid, c->egid); + res = qb_ipcs_shm_rb_open(c, &c->response, + r->response); if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:RESPONSE"); goto cleanup_request; } - c->event.u.shm.rb = qb_rb_open(r->event, - c->event.max_msg_size, - QB_RB_FLAG_CREATE | - QB_RB_FLAG_SHARED_PROCESS, 0); - - if (c->event.u.shm.rb == NULL) { - res = -errno; - qb_util_perror(LOG_ERR, "qb_rb_open:EVENT"); + res = qb_ipcs_shm_rb_open(c, &c->event, + r->event); + if (res != 0) { goto cleanup_request_response; } - res = qb_rb_chown(c->event.u.shm.rb, c->euid, c->egid); - if (res != 0) { - qb_util_perror(LOG_ERR, "qb_rb_chown:EVENT"); - goto cleanup_all; - } r->hdr.error = 0; return 0; -cleanup_all: - qb_rb_close(c->event.u.shm.rb); - cleanup_request_response: qb_rb_close(c->request.u.shm.rb); diff --git a/lib/ipc_sysv_mq.c b/lib/ipc_sysv_mq.c deleted file mode 100644 index 9dfce1e..0000000 --- a/lib/ipc_sysv_mq.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * Copyright (C) 2010 Red Hat, Inc. - * - * Author: Angus Salkeld - * - * This file is part of libqb. - * - * libqb is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 2.1 of the License, or - * (at your option) any later version. - * - * libqb 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with libqb. If not, see . - */ -#include "os_base.h" - -#ifdef HAVE_SYS_IPC_H -#include -#endif -#ifdef HAVE_SYS_MSG_H -#include -#endif - -#include -#include -#include "ipc_int.h" -#include "util_int.h" - -#ifndef MSGMAX -#define MSGMAX 8192 -#endif - -#define MY_DATA_SIZE 8000 -struct my_msgbuf { - int32_t id __attribute__ ((aligned(8))); - char data[MY_DATA_SIZE] __attribute__ ((aligned(8))); -} __attribute__ ((aligned(8))); - -/* - * utility functions - * -------------------------------------------------------- - */ -static int32_t -sysv_mq_unnamed_create(struct qb_ipcs_connection *c, - struct qb_ipc_one_way *queue) -{ - struct msqid_ds info; - int32_t res = 0; - -retry_creating_the_q: - queue->u.smq.key = random(); - queue->u.smq.q = - msgget(queue->u.smq.key, - IPC_CREAT | IPC_EXCL | IPC_NOWAIT | S_IWUSR | S_IRUSR); - if (queue->u.smq.q == -1 && errno == EEXIST) { - goto retry_creating_the_q; - } else if (queue->u.smq.q == -1) { - return -errno; - } - - /* - * change the queue size and change the ownership to that of - * the client so they can access it. - */ - res = msgctl(queue->u.smq.q, IPC_STAT, &info); - if (res != 0) { - res = -errno; - qb_util_perror(LOG_ERR, "error getting sysv-mq info"); - return res; - } - - if (info.msg_perm.uid != 0) { - qb_util_log(LOG_WARNING, - "not enough privileges to increase msg_qbytes"); - return res; - } - info.msg_qbytes = 2 * queue->max_msg_size; - info.msg_perm.uid = c->euid; - info.msg_perm.gid = c->egid; - - res = msgctl(queue->u.smq.q, IPC_SET, &info); - if (res != 0) { - res = -errno; - qb_util_perror(LOG_ERR, - "error modifying the SYSV message queue"); - return res; - } - - return 0; -} - -static int32_t -sysv_split_and_send(int32_t q, const void *msg_ptr, - size_t msg_len, int32_t last_chunk) -{ - int32_t res; - int32_t sent = 0; -#ifdef PACK_MESSAGES - char *progress = (char *)msg_ptr; - struct my_msgbuf buf; - size_t to_send_now; /* to send in this message */ - size_t to_send_next; /* to send in next message */ - - do { - to_send_now = QB_MIN(msg_len - sent, MY_DATA_SIZE); - to_send_next = msg_len - (sent + to_send_now); - /* receiver used the ID to check to see if there - * is more to receive for this message. - */ - if (last_chunk) { - buf.id = to_send_next + 1; - } else { - buf.id = to_send_next + 1 + msg_len; - } - memcpy(buf.data, progress, to_send_now); - res = msgsnd(q, &buf, to_send_now, IPC_NOWAIT); - if (res == 0) { - sent += to_send_now; - progress += to_send_now; - } else { - goto return_status; - } - - } while (sent < msg_len); - -return_status: -#else - res = msgsnd(q, msg_ptr, msg_len, IPC_NOWAIT); - sent = msg_len; -#endif - if (res == -1) { - return -errno; - } - return sent; -} - -/* - * client functions - * -------------------------------------------------------- - */ -static ssize_t -qb_ipc_smq_send(struct qb_ipc_one_way *one_way, - const void *msg_ptr, size_t msg_len) -{ - return sysv_split_and_send(one_way->u.smq.q, msg_ptr, msg_len, QB_TRUE); -} - -static ssize_t -qb_ipc_smq_sendv(struct qb_ipc_one_way *one_way, - const struct iovec *iov, size_t iov_len) -{ - int32_t res; - int32_t sent = 0; - struct my_msgbuf buf; - int32_t i; - - for (i = 0; i < iov_len; i++) { - if (iov[i].iov_len <= MY_DATA_SIZE) { - if (i == iov_len - 1) { - buf.id = 1; - } else { - buf.id = i + iov[i].iov_len; - } - memcpy(buf.data, iov[i].iov_base, iov[i].iov_len); - res = msgsnd(one_way->u.smq.q, - &buf, iov[i].iov_len, - IPC_NOWAIT); - if (res == 0) { - res = iov[i].iov_len; - } else { - res = -errno; - } - } else { - res = sysv_split_and_send(one_way->u.smq.q, - iov[i].iov_base, - iov[i].iov_len, - (i == iov_len - 1)); - } - if (res > 0) { - sent += res; - } else { - return res; - } - } - return sent; -} - -static ssize_t -qb_ipc_smq_recv(struct qb_ipc_one_way *one_way, - void *msg_ptr, size_t msg_len, int32_t ms_timeout) -{ - ssize_t res; - ssize_t received = 0; -#ifdef PACK_MESSAGES - char *progress = (char *)msg_ptr; - struct my_msgbuf buf; - - do { -try_again: - res = msgrcv(one_way->u.smq.q, &buf, - MY_DATA_SIZE, 0, IPC_NOWAIT); - - if (res == -1 && errno == ENOMSG) { - goto try_again; - } - //printf("res:%zd, ID:%d\n", res, buf.id); - if (res == -1) { - goto return_status; - } - memcpy(progress, buf.data, res); - received += res; - progress += res; - } while (buf.id > 1); -return_status: -#else - res = msgrcv(one_way->u.smq.q, msg_ptr, msg_len, 0, IPC_NOWAIT); - received = res; -#endif - if (res == -1 && errno == ENOMSG) { - /* just to be consistent with other IPC types. - */ - return -EAGAIN; - } - if (res == -1) { - perror(__func__); - return -errno; - } - return received; -} - -static void -qb_ipcc_smq_disconnect(struct qb_ipcc_connection *c) -{ - struct qb_ipc_request_header hdr; - - qb_util_log(LOG_TRACE, "%s()", __func__); - - hdr.id = QB_IPC_MSG_DISCONNECT; - hdr.size = sizeof(hdr); - (void)sysv_split_and_send(c->request.u.smq.q, - (const char *)&hdr, hdr.size, QB_TRUE); - - msgctl(c->event.u.smq.q, IPC_RMID, NULL); - msgctl(c->response.u.smq.q, IPC_RMID, NULL); - msgctl(c->request.u.smq.q, IPC_RMID, NULL); -} - -int32_t -qb_ipcc_smq_connect(struct qb_ipcc_connection *c, - struct qb_ipc_connection_response *response) -{ - int32_t res = 0; - - c->funcs.send = qb_ipc_smq_send; - c->funcs.sendv = qb_ipc_smq_sendv; - c->funcs.recv = qb_ipc_smq_recv; - c->funcs.fc_get = NULL; - c->funcs.disconnect = qb_ipcc_smq_disconnect; - c->needs_sock_for_poll = QB_TRUE; - - if (strlen(c->name) > (NAME_MAX - 20)) { - return -EINVAL; - } - - memcpy(&c->request.u.smq.key, response->request, sizeof(uint32_t)); - c->request.u.smq.q = msgget(c->request.u.smq.key, IPC_NOWAIT); - if (c->request.u.smq.q == -1) { - res = -errno; - perror("msgget:REQUEST"); - goto cleanup; - } - - memcpy(&c->response.u.smq.key, response->response, sizeof(uint32_t)); - c->response.u.smq.q = msgget(c->response.u.smq.key, IPC_NOWAIT); - if (c->response.u.smq.q == -1) { - res = -errno; - perror("msgget:RESPONSE"); - goto cleanup_request; - } - - memcpy(&c->event.u.smq.key, response->event, sizeof(uint32_t)); - c->event.u.smq.q = msgget(c->event.u.smq.key, IPC_NOWAIT); - if (c->event.u.smq.q == -1) { - res = -errno; - perror("msgget:EVENT"); - goto cleanup_request_response; - } - return 0; - -cleanup_request_response: - msgctl(c->response.u.smq.q, IPC_RMID, NULL); -cleanup_request: - msgctl(c->request.u.smq.q, IPC_RMID, NULL); -cleanup: - return res; -} - -/* - * service functions - * -------------------------------------------------------- - */ -static void -qb_ipcs_smq_disconnect(struct qb_ipcs_connection *c) -{ - struct qb_ipc_response_header msg; - - if (c->setup.u.us.sock != -1) { - msg.id = QB_IPC_MSG_DISCONNECT; - msg.size = sizeof(msg); - msg.error = 0; - - (void)qb_ipc_smq_send(&c->event, &msg, msg.size); - } else { - msgctl(c->event.u.smq.q, IPC_RMID, NULL); - msgctl(c->response.u.smq.q, IPC_RMID, NULL); - msgctl(c->request.u.smq.q, IPC_RMID, NULL); - } -} - -static int32_t -qb_ipcs_smq_connect(struct qb_ipcs_service *s, - struct qb_ipcs_connection *c, - struct qb_ipc_connection_response *r) -{ - int32_t res = 0; - - res = sysv_mq_unnamed_create(c, &c->request); - if (res < 0) { - res = -errno; - goto cleanup; - } - memcpy(r->request, &c->request.u.smq.key, sizeof(int32_t)); - - res = sysv_mq_unnamed_create(c, &c->response); - if (res < 0) { - res = -errno; - goto cleanup_request; - } - memcpy(r->response, &c->response.u.smq.key, sizeof(int32_t)); - - res = sysv_mq_unnamed_create(c, &c->event); - if (res < 0) { - res = -errno; - goto cleanup_request_response; - } - memcpy(r->event, &c->event.u.smq.key, sizeof(int32_t)); - - r->hdr.error = 0; - return 0; - -cleanup_request_response: - msgctl(c->response.u.smq.q, IPC_RMID, NULL); -cleanup_request: - msgctl(c->request.u.smq.q, IPC_RMID, NULL); - -cleanup: - r->hdr.error = res; - return res; -} - -static ssize_t -qb_ipc_smq_q_len_get(struct qb_ipc_one_way *one_way) -{ - struct msqid_ds info; - int32_t res = msgctl(one_way->u.smq.q, IPC_STAT, &info); - if (res == 0) { - return info.msg_qnum; - } - return -errno; -} - -void -qb_ipcs_smq_init(struct qb_ipcs_service *s) -{ - s->funcs.connect = qb_ipcs_smq_connect; - s->funcs.disconnect = qb_ipcs_smq_disconnect; - - s->funcs.send = qb_ipc_smq_send; - s->funcs.sendv = qb_ipc_smq_sendv; - s->funcs.recv = qb_ipc_smq_recv; - s->funcs.peek = NULL; - s->funcs.reclaim = NULL; - - s->funcs.fc_set = NULL; - s->funcs.q_len_get = qb_ipc_smq_q_len_get; - - s->needs_sock_for_poll = QB_TRUE; -} diff --git a/lib/ipc_us.c b/lib/ipc_us.c index df4f735..8690de2 100644 --- a/lib/ipc_us.c +++ b/lib/ipc_us.c @@ -48,16 +48,22 @@ #define UNIX_PATH_MAX 108 #endif /* UNIX_PATH_MAX */ -#if defined(QB_LINUX) || defined(QB_SOLARIS) -#define QB_SUN_LEN(a) sizeof(*(a)) +/* + * SUN_LEN() does a strlen() on sun_path, but if you are trying to use the + * "Linux abstract namespace" (you have to set sun_path[0] == '\0') then + * the strlen() doesn't work. + */ +#if defined(SUN_LEN) +#define QB_SUN_LEN(a) ((a)->sun_path[0] == '\0') ? sizeof(*(a)) : SUN_LEN(a) #else -#define QB_SUN_LEN(a) SUN_LEN(a) +#define QB_SUN_LEN(a) sizeof(*(a)) #endif struct ipc_us_control { int32_t sent; int32_t flow_control; }; +#define SHM_CONTROL_SIZE (3 * sizeof(struct ipc_us_control)) struct ipc_auth_ugp { uid_t uid; @@ -85,33 +91,21 @@ ssize_t qb_ipc_us_send(struct qb_ipc_one_way *one_way, const void *msg, size_t len) { int32_t result; - struct msghdr msg_send; - struct iovec iov_send; - char *rbuf = (char *)msg; int32_t processed = 0; - struct ipc_us_control *ctl = NULL; - - msg_send.msg_iov = &iov_send; - msg_send.msg_iovlen = 1; - msg_send.msg_name = 0; - msg_send.msg_namelen = 0; - -#if !defined(QB_SOLARIS) - msg_send.msg_control = 0; - msg_send.msg_controllen = 0; - msg_send.msg_flags = 0; -#else - msg_send.msg_accrights = NULL; - msg_send.msg_accrightslen = 0; -#endif + char *rbuf = (char *)msg; retry_send: - iov_send.iov_base = &rbuf[processed]; - iov_send.iov_len = len - processed; + result = send(one_way->u.us.sock, + &rbuf[processed], + len - processed, + MSG_NOSIGNAL); - result = sendmsg(one_way->u.us.sock, &msg_send, MSG_NOSIGNAL); if (result == -1) { - return -errno; + if (errno == EAGAIN && processed > 0) { + goto retry_send; + } else { + return -errno; + } } processed += result; @@ -119,6 +113,7 @@ retry_send: goto retry_send; } if (one_way->type == QB_IPC_SOCKET) { + struct ipc_us_control *ctl = NULL; ctl = (struct ipc_us_control *)one_way->u.us.shared_data; if (ctl) { qb_atomic_int_inc(&ctl->sent); @@ -132,46 +127,46 @@ qb_ipc_us_sendv(struct qb_ipc_one_way *one_way, const struct iovec *iov, size_t iov_len) { int32_t result; - struct msghdr msg_send; int32_t processed = 0; - size_t len = 0; - int32_t i; - struct ipc_us_control *ctl = NULL; - - for (i = 0; i < iov_len; i++) { - len += iov[i].iov_len; - } - msg_send.msg_iov = (struct iovec *)iov; - msg_send.msg_iovlen = iov_len; - msg_send.msg_name = 0; - msg_send.msg_namelen = 0; - -#if !defined(QB_SOLARIS) - msg_send.msg_control = 0; - msg_send.msg_controllen = 0; - msg_send.msg_flags = 0; -#else - msg_send.msg_accrights = NULL; - msg_send.msg_accrightslen = 0; -#endif + int32_t total_processed = 0; + int32_t iov_p = 0; + char *rbuf = (char *)iov[iov_p].iov_base; retry_send: - result = sendmsg(one_way->u.us.sock, &msg_send, MSG_NOSIGNAL); + result = send(one_way->u.us.sock, + &rbuf[processed], + iov[iov_p].iov_len - processed, + MSG_NOSIGNAL); + if (result == -1) { - return -errno; + if (errno == EAGAIN && + (processed > 0 || iov_p > 0)) { + goto retry_send; + } else { + return -errno; + } } processed += result; - if (processed != len) { + if (processed == iov[iov_p].iov_len) { + iov_p++; + total_processed += processed; + if (iov_p < iov_len) { + processed = 0; + rbuf = (char *)iov[iov_p].iov_base; + goto retry_send; + } + } else { goto retry_send; } if (one_way->type == QB_IPC_SOCKET) { + struct ipc_us_control *ctl; ctl = (struct ipc_us_control *)one_way->u.us.shared_data; if (ctl) { qb_atomic_int_inc(&ctl->sent); } } - return processed; + return total_processed; } static ssize_t @@ -191,14 +186,11 @@ retry_recv: if (result == -1) { return -errno; } -#if defined(QB_SOLARIS) || defined(QB_BSD) || defined(QB_DARWIN) - /* On many OS poll never return POLLHUP or POLLERR. - * EOF is detected when recvmsg return 0. - */ if (result == 0) { - return -errno; //ENOTCONN + qb_util_log(LOG_DEBUG, + "recv(fd %d) got 0 bytes assuming ENOTCONN", s); + return -ENOTCONN; } -#endif processed += result; if (processed != len) { @@ -210,13 +202,29 @@ retry_recv: } int32_t -qb_ipc_us_recv_ready(struct qb_ipc_one_way * one_way, int32_t ms_timeout) +qb_ipc_us_sock_error_is_disconnected(int err) +{ + if (err == -EAGAIN || + err == -ETIMEDOUT || + err == -EINTR || +#ifdef EWOULDBLOCK + err == -EWOULDBLOCK || +#endif + err == -EINVAL) { + return QB_FALSE; + } + return QB_TRUE; +} + +int32_t +qb_ipc_us_ready(struct qb_ipc_one_way * one_way, + int32_t ms_timeout, int32_t events) { struct pollfd ufds; int32_t poll_events; ufds.fd = one_way->u.us.sock; - ufds.events = POLLIN; + ufds.events = events; ufds.revents = 0; poll_events = poll(&ufds, 1, ms_timeout); @@ -224,7 +232,14 @@ qb_ipc_us_recv_ready(struct qb_ipc_one_way * one_way, int32_t ms_timeout) return -EAGAIN; } else if (poll_events == -1) { return -errno; - } else if (poll_events == 1 && (ufds.revents & (POLLERR | POLLHUP))) { + } else if (poll_events == 1 && (ufds.revents & POLLERR)) { + qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLERR", one_way->u.us.sock); + return -ENOTCONN; + } else if (poll_events == 1 && (ufds.revents & POLLHUP)) { + qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLHUP", one_way->u.us.sock); + return -ENOTCONN; + } else if (poll_events == 1 && (ufds.revents & POLLNVAL)) { + qb_util_log(LOG_DEBUG, "poll(fd %d) got POLLNVAL", one_way->u.us.sock); return -ENOTCONN; } return 0; @@ -241,27 +256,38 @@ qb_ipc_us_recv(struct qb_ipc_one_way * one_way, int32_t processed = 0; int32_t to_recv = len; char *data = msg; - struct ipc_us_control *ctl = NULL; retry_recv: - result = recv(one_way->u.us.sock, &data[processed], to_recv, MSG_NOSIGNAL | MSG_WAITALL); - if (timeout == -1) { - if (result == -1 && errno == EAGAIN) { + result = recv(one_way->u.us.sock, &data[processed], to_recv, + MSG_NOSIGNAL | MSG_WAITALL); + + if (result == -1) { + if (errno == EAGAIN && + (processed > 0 || timeout == -1)) { goto retry_recv; + } else if (errno == ECONNRESET || errno == EPIPE) { + qb_util_perror(LOG_DEBUG, + "recv(fd %d) converting to ENOTCONN", + one_way->u.us.sock); + return -ENOTCONN; + } else { + return -errno; } } + if (result == 0) { + qb_util_log(LOG_DEBUG, + "recv(fd %d) got 0 bytes assuming ENOTCONN", + one_way->u.us.sock); return -ENOTCONN; } - if (result == -1) { - return -errno; - } processed += result; to_recv -= result; if (processed != len) { goto retry_recv; } if (one_way->type == QB_IPC_SOCKET) { + struct ipc_us_control *ctl = NULL; ctl = (struct ipc_us_control *)one_way->u.us.shared_data; if (ctl) { (void)qb_atomic_int_dec_and_test(&ctl->sent); @@ -271,34 +297,53 @@ retry_recv: } /* - * recv a message of unknow size. - * (could use MSG_PEEK here) + * recv a message of unknown size. */ static ssize_t qb_ipc_us_recv_at_most(struct qb_ipc_one_way * one_way, void *msg, size_t len, int32_t timeout) { int32_t result; + int32_t processed = 0; + int32_t to_recv = sizeof(struct qb_ipc_request_header); + char *data = msg; struct ipc_us_control *ctl = NULL; + struct qb_ipc_request_header *hdr = NULL; retry_recv: - result = recv(one_way->u.us.sock, msg, len, MSG_NOSIGNAL | MSG_WAITALL); - if (timeout == -1) { - if (result == -1 && errno == EAGAIN) { + result = recv(one_way->u.us.sock, &data[processed], to_recv, + MSG_NOSIGNAL | MSG_WAITALL); + if (result == -1) { + if (errno == EAGAIN && + (processed > 0 || timeout == -1)) { goto retry_recv; + } else { + return -errno; } - } - if (result == 0) { + } else if (result == 0) { + qb_util_log(LOG_DEBUG, + "recv(fd %d) got 0 bytes assuming ENOTCONN", + one_way->u.us.sock); return -ENOTCONN; } - if (result == -1) { - return -errno; + + processed += result; + if (processed >= sizeof(struct qb_ipc_request_header) && hdr == NULL) { + hdr = (struct qb_ipc_request_header*)msg; + } + if (hdr) { + to_recv = hdr->size - processed; + } else { + to_recv = len - processed; + } + if (to_recv > 0) { + goto retry_recv; } ctl = (struct ipc_us_control *)one_way->u.us.shared_data; if (ctl) { (void)qb_atomic_int_dec_and_test(&ctl->sent); } - return result; + return processed; } @@ -309,11 +354,7 @@ qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt) struct sockaddr_un address; int32_t res = 0; -#if defined(QB_SOLARIS) request_fd = socket(PF_UNIX, SOCK_STREAM, 0); -#else - request_fd = socket(PF_LOCAL, SOCK_STREAM, 0); -#endif if (request_fd == -1) { return -errno; } @@ -327,11 +368,11 @@ qb_ipcc_us_sock_connect(const char *socket_name, int32_t * sock_pt) memset(&address, 0, sizeof(struct sockaddr_un)); address.sun_family = AF_UNIX; -#if defined(QB_BSD) || defined(QB_DARWIN) - address.sun_len = SUN_LEN(&address); +#ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN + address.sun_len = QB_SUN_LEN(&address); #endif -#if defined(QB_LINUX) +#if defined(QB_LINUX) || defined(QB_CYGWIN) snprintf(address.sun_path + 1, UNIX_PATH_MAX - 1, "%s", socket_name); #else snprintf(address.sun_path, UNIX_PATH_MAX, "%s/%s", SOCKETDIR, @@ -366,12 +407,21 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, { int32_t res; struct qb_ipc_connection_request request; +#ifdef QB_LINUX + int off = 0; + int on = 1; +#endif res = qb_ipcc_us_sock_connect(c->name, &c->setup.u.us.sock); if (res != 0) { return res; } +#ifdef QB_LINUX + setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); +#endif + + memset(&request, 0, sizeof(request)); request.hdr.id = QB_IPC_MSG_AUTHENTICATE; request.hdr.size = sizeof(request); request.max_msg_size = c->setup.max_msg_size; @@ -381,6 +431,10 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, return res; } +#ifdef QB_LINUX + setsockopt(c->setup.u.us.sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off)); +#endif + res = qb_ipc_us_recv(&c->setup, r, sizeof(struct qb_ipc_connection_response), -1); @@ -397,7 +451,7 @@ qb_ipcc_us_setup_connect(struct qb_ipcc_connection *c, static void qb_ipcc_us_disconnect(struct qb_ipcc_connection *c) { - munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control)); + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); unlink(c->request.u.us.shared_file_name); close(c->request.u.us.sock); close(c->event.u.us.sock); @@ -411,7 +465,7 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c, struct qb_ipc_event_connection_request request; char path[PATH_MAX]; int32_t fd_hdr; - struct ipc_us_control *ctl; + char * shm_ptr; c->needs_sock_for_poll = QB_FALSE; c->funcs.send = qb_ipc_us_send; @@ -425,27 +479,24 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c, c->setup.u.us.sock = -1; fd_hdr = qb_sys_mmap_file_open(path, r->request, - sizeof(struct ipc_us_control), O_RDWR); + SHM_CONTROL_SIZE, O_RDWR); if (fd_hdr < 0) { res = -errno; qb_util_perror(LOG_ERR, "couldn't open file for mmap"); return res; } (void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX); - c->request.u.us.shared_data = mmap(0, - sizeof(struct ipc_us_control), - PROT_READ | PROT_WRITE, MAP_SHARED, - fd_hdr, 0); + shm_ptr = mmap(0, SHM_CONTROL_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, fd_hdr, 0); - if (c->request.u.us.shared_data == MAP_FAILED) { + if (shm_ptr == MAP_FAILED) { res = -errno; qb_util_perror(LOG_ERR, "couldn't create mmap for header"); goto cleanup_hdr; } - - ctl = (struct ipc_us_control *)c->request.u.us.shared_data; - ctl->sent = 0; - ctl->flow_control = 0; + c->request.u.us.shared_data = shm_ptr; + c->response.u.us.shared_data = shm_ptr + sizeof(struct ipc_us_control); + c->event.u.us.shared_data = shm_ptr + (2 * sizeof(struct ipc_us_control)); close(fd_hdr); @@ -454,13 +505,14 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c, goto cleanup_hdr; } + memset(&request, 0, sizeof(request)); request.hdr.id = QB_IPC_MSG_NEW_EVENT_SOCK; request.hdr.size = sizeof(request); request.connection = r->connection; res = qb_ipc_us_send(&c->event, &request, request.hdr.size); if (res < 0) { qb_ipcc_us_sock_close(c->event.u.us.sock); - return res; + goto cleanup_hdr; } return 0; @@ -468,7 +520,7 @@ qb_ipcc_us_connect(struct qb_ipcc_connection *c, cleanup_hdr: close(fd_hdr); unlink(r->request); - munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control)); + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); return res; } @@ -486,11 +538,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s) /* * Create socket for IPC clients, name socket, listen for connections */ -#if defined(QB_SOLARIS) s->server_sock = socket(PF_UNIX, SOCK_STREAM, 0); -#else - s->server_sock = socket(PF_LOCAL, SOCK_STREAM, 0); -#endif if (s->server_sock == -1) { res = -errno; qb_util_perror(LOG_ERR, "Cannot create server socket"); @@ -509,7 +557,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s) #endif qb_util_log(LOG_INFO, "server name: %s", s->name); -#if defined(QB_LINUX) +#if defined(QB_LINUX) || defined(QB_CYGWIN) snprintf(un_addr.sun_path + 1, UNIX_PATH_MAX - 1, "%s", s->name); #else { @@ -541,7 +589,7 @@ qb_ipcs_us_publish(struct qb_ipcs_service * s) * Allow everyone to write to the socket since the IPC layer handles * security automatically */ -#if !defined(QB_LINUX) +#if !defined(QB_LINUX) && !defined(QB_CYGWIN) res = chmod(un_addr.sun_path, S_IRWXU | S_IRWXG | S_IRWXO); #endif if (listen(s->server_sock, SERVER_BACKLOG) == -1) { @@ -585,7 +633,7 @@ handle_new_connection(struct qb_ipcs_service *s, return -ENOMEM; } - c->receive_buf = malloc(req->max_msg_size); + c->receive_buf = calloc(1, req->max_msg_size); if (c->receive_buf == NULL) { free(c); qb_ipcc_us_sock_close(sock); @@ -596,9 +644,13 @@ handle_new_connection(struct qb_ipcs_service *s, c->response.max_msg_size = req->max_msg_size; c->event.max_msg_size = req->max_msg_size; c->pid = ugp->pid; - c->euid = ugp->uid; - c->egid = ugp->gid; + c->auth.uid = c->euid = ugp->uid; + c->auth.gid = c->egid = ugp->gid; + c->auth.mode = 0600; c->stats.client_pid = ugp->pid; + snprintf(c->description, CONNECTION_DESCRIPTION, + "%d-%d-%d", s->pid, ugp->pid, + c->setup.u.us.sock); if (auth_result == 0 && c->service->serv_fns.connection_accept) { res = c->service->serv_fns.connection_accept(c, @@ -608,7 +660,8 @@ handle_new_connection(struct qb_ipcs_service *s, goto send_response; } - qb_util_log(LOG_INFO, "IPC credentials authenticated"); + qb_util_log(LOG_DEBUG, "IPC credentials authenticated (%s)", + c->description); memset(&response, 0, sizeof(response)); if (s->funcs.connect) { @@ -630,19 +683,15 @@ handle_new_connection(struct qb_ipcs_service *s, POLLIN | POLLPRI | POLLNVAL, c, qb_ipcs_dispatch_connection_request); + if (res < 0) { + qb_util_log(LOG_ERR, + "Error adding socket to mainloop (%s).", + c->description); + } } if (s->type == QB_IPC_SOCKET) { c->request.u.us.sock = c->setup.u.us.sock; c->response.u.us.sock = c->setup.u.us.sock; - res = s->poll_fns.dispatch_add(s->poll_priority, - c->request.u.us.sock, - POLLIN | POLLPRI | POLLNVAL, - c, - qb_ipcs_dispatch_connection_request); - if (res < 0) { - qb_util_log(LOG_ERR, - "Error adding socket to mainloop."); - } } send_response: @@ -662,19 +711,24 @@ send_response: } if (res == 0) { - qb_ipcs_connection_ref(c); - if (s->serv_fns.connection_created) { - s->serv_fns.connection_created(c); + if (s->type != QB_IPC_SOCKET) { + qb_ipcs_connection_ref(c); + if (s->serv_fns.connection_created) { + s->serv_fns.connection_created(c); + } + if (c->state == QB_IPCS_CONNECTION_ACTIVE) { + c->state = QB_IPCS_CONNECTION_ESTABLISHED; + } + qb_ipcs_connection_unref(c); } - if (c->state == QB_IPCS_CONNECTION_ACTIVE) { - c->state = QB_IPCS_CONNECTION_ESTABLISHED; - } - qb_ipcs_connection_unref(c); } else { if (res == -EACCES) { - qb_util_log(LOG_ERR, "Invalid IPC credentials."); + qb_util_log(LOG_ERR, "Invalid IPC credentials (%s).", + c->description); } else { - qb_util_perror(LOG_ERR, "Error in connection setup"); + errno = -res; + qb_util_perror(LOG_ERR, "Error in connection setup (%s)", + c->description); } qb_ipcs_disconnect(c); } @@ -688,7 +742,32 @@ handle_connection_new_sock(struct qb_ipcs_service *s, int32_t sock, void *msg) struct qb_ipc_event_connection_request *req = msg; c = (struct qb_ipcs_connection *)req->connection; + qb_ipcs_connection_ref(c); c->event.u.us.sock = sock; + if (c->state == QB_IPCS_CONNECTION_ACTIVE) { + c->state = QB_IPCS_CONNECTION_ESTABLISHED; + } + if (s->serv_fns.connection_created) { + s->serv_fns.connection_created(c); + } + + if (c->state == QB_IPCS_CONNECTION_ESTABLISHED && + s->type == QB_IPC_SOCKET) { + int32_t res; + qb_ipcs_connection_ref(c); + res = s->poll_fns.dispatch_add(s->poll_priority, + c->request.u.us.sock, + POLLIN | POLLPRI | POLLNVAL, + c, + qb_ipcs_dispatch_connection_request); + if (res < 0) { + qb_util_log(LOG_ERR, + "Error adding socket to mainloop (%s).", + c->description); + } + } + + qb_ipcs_connection_unref(c); } static int32_t @@ -699,28 +778,29 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len, struct msghdr msg_recv; struct iovec iov_recv; -#ifdef QB_LINUX +#ifdef SO_PASSCRED char cmsg_cred[CMSG_SPACE(sizeof(struct ucred))]; int off = 0; int on = 1; #endif - msg_recv.msg_flags = 0; msg_recv.msg_iov = &iov_recv; msg_recv.msg_iovlen = 1; msg_recv.msg_name = 0; msg_recv.msg_namelen = 0; -#ifdef QB_LINUX +#ifdef SO_PASSCRED msg_recv.msg_control = (void *)cmsg_cred; msg_recv.msg_controllen = sizeof(cmsg_cred); #endif #ifdef QB_SOLARIS msg_recv.msg_accrights = 0; msg_recv.msg_accrightslen = 0; +#else + msg_recv.msg_flags = 0; #endif /* QB_SOLARIS */ iov_recv.iov_base = msg; iov_recv.iov_len = len; -#ifdef QB_LINUX +#ifdef SO_PASSCRED setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on)); #endif @@ -776,16 +856,19 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len, */ { struct ucred cred; - struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg_recv); - assert(cmsg != NULL); - if (CMSG_DATA(cmsg)) { + struct cmsghdr *cmsg; + + res = -EINVAL; + for (cmsg = CMSG_FIRSTHDR(&msg_recv); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg_recv, cmsg)) { + if (cmsg->cmsg_type != SCM_CREDENTIALS) + continue; + memcpy(&cred, CMSG_DATA(cmsg), sizeof(struct ucred)); res = 0; ugp->pid = cred.pid; ugp->uid = cred.uid; ugp->gid = cred.gid; - } else { - res = -EBADMSG; + break; } } #else /* no credentials */ @@ -797,7 +880,7 @@ qb_ipcs_uc_recv_and_auth(int32_t sock, void *msg, size_t len, cleanup_and_return: -#ifdef QB_LINUX +#ifdef SO_PASSCRED setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &off, sizeof(off)); #endif @@ -815,6 +898,13 @@ qb_ipcs_us_connection_acceptor(int fd, int revent, void *data) struct ipc_auth_ugp ugp; socklen_t addrlen = sizeof(struct sockaddr_un); + if (revent & (POLLNVAL|POLLHUP|POLLERR)) { + /* + * handle shutdown more cleanly. + */ + return -1; + } + retry_accept: errno = 0; new_fd = accept(fd, (struct sockaddr *)&un_addr, &addrlen); @@ -847,6 +937,13 @@ retry_accept: res = qb_ipcs_uc_recv_and_auth(new_fd, &setup_msg, sizeof(setup_msg), &ugp); + if (res < 0) { + close(new_fd); + /* This is an error, but -1 would indicate disconnect + * from the poll loop + */ + return 0; + } if (setup_msg.hdr.id == QB_IPC_MSG_AUTHENTICATE) { (void)handle_new_connection(s, res, new_fd, &setup_msg, @@ -873,37 +970,60 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s, int32_t fd_hdr; int32_t res = 0; struct ipc_us_control *ctl; + char * shm_ptr; - qb_util_log(LOG_DEBUG, "connecting to client [%d]", c->pid); + qb_util_log(LOG_DEBUG, "connecting to client (%s)", + c->description); - snprintf(r->request, NAME_MAX, "qb-%s-control-%d-%d", - s->name, c->pid, c->setup.u.us.sock); + snprintf(r->request, NAME_MAX, "qb-%s-control-%s", + s->name, c->description); fd_hdr = qb_sys_mmap_file_open(path, r->request, - sizeof(struct ipc_us_control), + SHM_CONTROL_SIZE, O_CREAT | O_TRUNC | O_RDWR); if (fd_hdr < 0) { res = -errno; - qb_util_perror(LOG_ERR, "couldn't create file for mmap"); + qb_util_perror(LOG_ERR, "couldn't create file for mmap (%s)", + c->description); return res; } (void)strlcpy(r->request, path, PATH_MAX); (void)strlcpy(c->request.u.us.shared_file_name, r->request, NAME_MAX); - - c->request.u.us.shared_data = mmap(0, - sizeof(struct ipc_us_control), - PROT_READ | PROT_WRITE, MAP_SHARED, - fd_hdr, 0); - - if (c->request.u.us.shared_data == MAP_FAILED) { - res = -errno; - qb_util_perror(LOG_ERR, "couldn't create mmap for header"); - goto cleanup_hdr; + res = chown(r->request, c->auth.uid, c->auth.gid); + if (res != 0) { + /* ignore res, this is just for the compiler warnings. + */ + res = 0; + } + res = chmod(r->request, c->auth.mode); + if (res != 0) { + /* ignore res, this is just for the compiler warnings. + */ + res = 0; } + shm_ptr = mmap(0, SHM_CONTROL_SIZE, + PROT_READ | PROT_WRITE, MAP_SHARED, fd_hdr, 0); + + if (shm_ptr == MAP_FAILED) { + res = -errno; + qb_util_perror(LOG_ERR, "couldn't create mmap for header (%s)", + c->description); + goto cleanup_hdr; + } + c->request.u.us.shared_data = shm_ptr; + c->response.u.us.shared_data = shm_ptr + sizeof(struct ipc_us_control); + c->event.u.us.shared_data = shm_ptr + (2 * sizeof(struct ipc_us_control)); + ctl = (struct ipc_us_control *)c->request.u.us.shared_data; ctl->sent = 0; ctl->flow_control = 0; + ctl = (struct ipc_us_control *)c->response.u.us.shared_data; + ctl->sent = 0; + ctl->flow_control = 0; + ctl = (struct ipc_us_control *)c->event.u.us.shared_data; + ctl->sent = 0; + ctl->flow_control = 0; close(fd_hdr); return res; @@ -911,7 +1031,7 @@ qb_ipcs_us_connect(struct qb_ipcs_service *s, cleanup_hdr: close(fd_hdr); unlink(r->request); - munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control)); + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); return res; } @@ -921,7 +1041,8 @@ qb_ipc_us_fc_set(struct qb_ipc_one_way *one_way, int32_t fc_enable) struct ipc_us_control *ctl = (struct ipc_us_control *)one_way->u.us.shared_data; - qb_util_log(LOG_TRACE, "setting fc to %d", fc_enable); + qb_util_log(LOG_TRACE, "setting fc to %d", + fc_enable); qb_atomic_int_set(&ctl->flow_control, fc_enable); } @@ -942,14 +1063,35 @@ qb_ipc_us_q_len_get(struct qb_ipc_one_way *one_way) return qb_atomic_int_get(&ctl->sent); } +void +qb_ipcs_sockets_disconnect(struct qb_ipcs_connection *c) +{ + int sock = -1; + + qb_enter(); + if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) { + sock = c->setup.u.us.sock; + qb_ipcc_us_sock_close(sock); + c->setup.u.us.sock = -1; + } + if (c->request.type == QB_IPC_SOCKET) { + sock = c->request.u.us.sock; + } + if (sock > 0) { + (void)c->service->poll_fns.dispatch_del(sock); + qb_ipcs_connection_unref(c); + } +} + static void qb_ipcs_us_disconnect(struct qb_ipcs_connection *c) { - munmap(c->request.u.us.shared_data, sizeof(struct ipc_us_control)); + qb_enter(); + munmap(c->request.u.us.shared_data, SHM_CONTROL_SIZE); unlink(c->request.u.us.shared_file_name); - close(c->request.u.us.sock); - close(c->event.u.us.sock); + qb_ipcc_us_sock_close(c->request.u.us.sock); + qb_ipcc_us_sock_close(c->event.u.us.sock); } void diff --git a/lib/ipcc.c b/lib/ipcc.c index 5831e8c..0abb0e7 100644 --- a/lib/ipcc.c +++ b/lib/ipcc.c @@ -20,9 +20,6 @@ */ #include "os_base.h" -#ifdef HAVE_MQUEUE_H -#include -#endif /* HAVE_MQUEUE_H */ #include "ipc_int.h" #include "util_int.h" #include @@ -40,7 +37,8 @@ qb_ipcc_connect(const char *name, size_t max_msg_size) return NULL; } - c->setup.max_msg_size = max_msg_size; + c->setup.max_msg_size = QB_MAX(max_msg_size, + sizeof(struct qb_ipc_connection_response)); (void)strlcpy(c->name, name, NAME_MAX); res = qb_ipcc_us_setup_connect(c, &response); if (res < 0) { @@ -54,7 +52,7 @@ qb_ipcc_connect(const char *name, size_t max_msg_size) c->response.max_msg_size = response.max_msg_size; c->request.max_msg_size = response.max_msg_size; c->event.max_msg_size = response.max_msg_size; - c->receive_buf = malloc(response.max_msg_size); + c->receive_buf = calloc(1, response.max_msg_size); c->fc_enable_max = 1; if (c->receive_buf == NULL) { res = -ENOMEM; @@ -65,23 +63,13 @@ qb_ipcc_connect(const char *name, size_t max_msg_size) case QB_IPC_SHM: res = qb_ipcc_shm_connect(c, &response); break; - case QB_IPC_POSIX_MQ: -#ifdef HAVE_POSIX_MQ - res = qb_ipcc_pmq_connect(c, &response); -#else - res = -ENOTSUP; -#endif /* HAVE_POSIX_MQ */ - break; - case QB_IPC_SYSV_MQ: -#ifdef HAVE_SYSV_MQ - res = qb_ipcc_smq_connect(c, &response); -#else - res = -ENOTSUP; -#endif /* HAVE_SYSV_MQ */ - break; case QB_IPC_SOCKET: res = qb_ipcc_us_connect(c, &response); break; + case QB_IPC_POSIX_MQ: + case QB_IPC_SYSV_MQ: + res = -ENOTSUP; + break; default: res = -EINVAL; break; @@ -100,6 +88,44 @@ disconnect_and_cleanup: return NULL; } +static void +_check_connection_state(struct qb_ipcc_connection * c, int32_t res) +{ + if (res >= 0) return; + + if (qb_ipc_us_sock_error_is_disconnected(res)) { + errno = -res; + qb_util_perror(LOG_DEBUG, + "interpreting result %d as a disconnect", + res); + c->is_connected = QB_FALSE; + } +} + +static struct qb_ipc_one_way * +_event_sock_one_way_get(struct qb_ipcc_connection * c) +{ + if (c->needs_sock_for_poll) { + return &c->setup; + } + if (c->event.type == QB_IPC_SOCKET) { + return &c->event; + } + return NULL; +} + +static struct qb_ipc_one_way * +_response_sock_one_way_get(struct qb_ipcc_connection * c) +{ + if (c->needs_sock_for_poll) { + return &c->setup; + } + if (c->response.type == QB_IPC_SOCKET) { + return &c->response; + } + return NULL; +} + ssize_t qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len) { @@ -128,13 +154,13 @@ qb_ipcc_send(struct qb_ipcc_connection * c, const void *msg_ptr, size_t msg_len) res2 = qb_ipc_us_send(&c->setup, msg_ptr, 1); } while (res2 == -EAGAIN); if (res2 == -EPIPE) { - c->is_connected = QB_FALSE; - return -ENOTCONN; + res2 = -ENOTCONN; } if (res2 != 1) { res = res2; } } + _check_connection_state(c, res); return res; } @@ -183,13 +209,13 @@ qb_ipcc_sendv(struct qb_ipcc_connection * c, const struct iovec * iov, res2 = qb_ipc_us_send(&c->setup, &res, 1); } while (res2 == -EAGAIN); if (res2 == -EPIPE) { - c->is_connected = QB_FALSE; - return -ENOTCONN; + res2 = -ENOTCONN; } if (res2 != 1) { res = res2; } } + _check_connection_state(c, res); return res; } @@ -204,17 +230,17 @@ qb_ipcc_recv(struct qb_ipcc_connection * c, void *msg_ptr, } res = c->funcs.recv(&c->response, msg_ptr, msg_len, ms_timeout); - if ((res == -EAGAIN || res == -ETIMEDOUT) && c->needs_sock_for_poll) { - res2 = qb_ipc_us_recv_ready(&c->setup, 0); + if (res == -EAGAIN || res == -ETIMEDOUT) { + struct qb_ipc_one_way *ow = _response_sock_one_way_get(c); + + if (ow == NULL) return res; + + res2 = qb_ipc_us_ready(ow, 0, POLLIN); if (res2 < 0) { - if (res2 == -ENOTCONN) { - c->is_connected = QB_FALSE; - } - return res2; - } else { - return res; + res = res2; } } + _check_connection_state(c, res); return res; } @@ -303,31 +329,23 @@ qb_ipcc_event_recv(struct qb_ipcc_connection * c, void *msg_pt, if (c == NULL) { return -EINVAL; } - if (c->needs_sock_for_poll) { - ow = &c->setup; - } - if (c->event.type == QB_IPC_SOCKET) { - ow = &c->event; - } + ow = _event_sock_one_way_get(c); if (ow) { - res = qb_ipc_us_recv_ready(ow, ms_timeout); + res = qb_ipc_us_ready(ow, ms_timeout, POLLIN); if (res < 0) { - if (res == -ENOTCONN) { - c->is_connected = QB_FALSE; - } + _check_connection_state(c, res); return res; } } size = c->funcs.recv(&c->event, msg_pt, msg_len, ms_timeout); if (size < 0) { + _check_connection_state(c, size); return size; } if (c->needs_sock_for_poll) { res = qb_ipc_us_recv(&c->setup, &one_byte, 1, -1); if (res < 0) { - if (res == -ENOTCONN) { - c->is_connected = QB_FALSE; - } + _check_connection_state(c, res); return res; } } @@ -338,6 +356,7 @@ void qb_ipcc_disconnect(struct qb_ipcc_connection *c) { struct qb_ipc_one_way *ow = NULL; + int32_t res = 0; qb_util_log(LOG_DEBUG, "%s()", __func__); @@ -345,19 +364,13 @@ qb_ipcc_disconnect(struct qb_ipcc_connection *c) return; } - if (c->needs_sock_for_poll) { - ow = &c->setup; - } - if (c->event.type == QB_IPC_SOCKET) { - ow = &c->event; - } + ow = _event_sock_one_way_get(c); if (ow) { - if (qb_ipc_us_recv_ready(ow, 0) == -ENOTCONN) { - c->is_connected = QB_FALSE; - } + res = qb_ipc_us_ready(ow, 0, POLLIN); + _check_connection_state(c, res); + qb_ipcc_us_sock_close(ow->u.us.sock); } - qb_ipcc_us_sock_close(c->setup.u.us.sock); if (c->funcs.disconnect) { c->funcs.disconnect(c); } @@ -381,3 +394,20 @@ void *qb_ipcc_context_get(struct qb_ipcc_connection *c) } return c->context; } + +int32_t +qb_ipcc_is_connected(qb_ipcc_connection_t *c) +{ + struct qb_ipc_one_way *ow; + + if (c == NULL) { + return QB_FALSE; + } + + ow = _response_sock_one_way_get(c); + if (ow) { + _check_connection_state(c, qb_ipc_us_ready(ow, 0, POLLIN)); + } + + return c->is_connected; +} diff --git a/lib/ipcs.c b/lib/ipcs.c index 5f5560f..0fa7142 100644 --- a/lib/ipcs.c +++ b/lib/ipcs.c @@ -28,6 +28,8 @@ static void qb_ipcs_flowcontrol_set(struct qb_ipcs_connection *c, int32_t fc_enable); +static int32_t +new_event_notification(struct qb_ipcs_connection * c); static QB_LIST_DECLARE(qb_ipc_services); @@ -42,9 +44,17 @@ qb_ipcs_create(const char *name, if (s == NULL) { return NULL; } + if (type == QB_IPC_NATIVE) { +#ifdef DISABLE_IPC_SHM + s->type = QB_IPC_SOCKET; +#else + s->type = QB_IPC_SHM; +#endif /* DISABLE_IPC_SHM */ + } else { + s->type = type; + } s->pid = getpid(); - s->type = type; s->needs_sock_for_poll = QB_FALSE; s->poll_priority = QB_LOOP_MED; s->ref_count = 1; @@ -91,21 +101,15 @@ qb_ipcs_run(struct qb_ipcs_service *s) qb_ipcs_us_init((struct qb_ipcs_service *)s); break; case QB_IPC_SHM: +#ifdef DISABLE_IPC_SHM + res = -ENOTSUP; +#else qb_ipcs_shm_init((struct qb_ipcs_service *)s); +#endif /* DISABLE_IPC_SHM */ break; case QB_IPC_POSIX_MQ: -#ifdef HAVE_POSIX_MQ - qb_ipcs_pmq_init((struct qb_ipcs_service *)s); -#else - res = -ENOTSUP; -#endif /* HAVE_POSIX_MQ */ - break; case QB_IPC_SYSV_MQ: -#ifdef HAVE_SYSV_MQ - qb_ipcs_smq_init((struct qb_ipcs_service *)s); -#else res = -ENOTSUP; -#endif /* HAVE_SYSV_MQ */ break; default: res = -EINVAL; @@ -130,15 +134,7 @@ _modify_dispatch_descriptor_(struct qb_ipcs_connection *c) { qb_ipcs_dispatch_mod_fn disp_mod = c->service->poll_fns.dispatch_mod; - if (c->service->type == QB_IPC_POSIX_MQ - && !c->service->needs_sock_for_poll) { -#ifdef HAVE_MQUEUE_H - return disp_mod(c->service->poll_priority, - (int32_t) c->request.u.pmq.q, - c->poll_events, c, - qb_ipcs_dispatch_service_request); -#endif /* HAVE_MQUEUE_H */ - } else if (c->service->type == QB_IPC_SOCKET) { + if (c->service->type == QB_IPC_SOCKET) { return disp_mod(c->service->poll_priority, c->event.u.us.sock, c->poll_events, c, @@ -236,6 +232,29 @@ qb_ipcs_destroy(struct qb_ipcs_service *s) /* * connection API */ +static struct qb_ipc_one_way * +_event_sock_one_way_get(struct qb_ipcs_connection * c) +{ + if (c->service->needs_sock_for_poll) { + return &c->setup; + } + if (c->event.type == QB_IPC_SOCKET) { + return &c->event; + } + return NULL; +} + +static struct qb_ipc_one_way * +_response_sock_one_way_get(struct qb_ipcs_connection * c) +{ + if (c->service->needs_sock_for_poll) { + return &c->setup; + } + if (c->response.type == QB_IPC_SOCKET) { + return &c->response; + } + return NULL; +} ssize_t qb_ipcs_response_send(struct qb_ipcs_connection *c, const void *data, @@ -251,6 +270,13 @@ qb_ipcs_response_send(struct qb_ipcs_connection *c, const void *data, if (res == size) { c->stats.responses++; } else if (res == -EAGAIN || res == -ETIMEDOUT) { + struct qb_ipc_one_way *ow = _response_sock_one_way_get(c); + if (ow) { + ssize_t res2 = qb_ipc_us_ready(ow, 0, POLLOUT); + if (res2 < 0) { + res = res2; + } + } c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -272,6 +298,13 @@ qb_ipcs_response_sendv(struct qb_ipcs_connection * c, const struct iovec * iov, if (res > 0) { c->stats.responses++; } else if (res == -EAGAIN || res == -ETIMEDOUT) { + struct qb_ipc_one_way *ow = _response_sock_one_way_get(c); + if (ow) { + ssize_t res2 = qb_ipc_us_ready(ow, 0, POLLOUT); + if (res2 < 0) { + res = res2; + } + } c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -285,7 +318,7 @@ resend_event_notifications(struct qb_ipcs_connection *c) ssize_t res = 0; if (c->outstanding_notifiers > 0) { - res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers, + res = qb_ipc_us_send(&c->setup, c->receive_buf, c->outstanding_notifiers); } if (res > 0) { @@ -313,15 +346,14 @@ new_event_notification(struct qb_ipcs_connection * c) c->outstanding_notifiers++; } else { res = qb_ipc_us_send(&c->setup, &c->outstanding_notifiers, 1); - if (res == 1) { - return res; + if (res == -EAGAIN) { + /* + * notify the client later, when we can. + */ + c->outstanding_notifiers++; + c->poll_events = POLLOUT | POLLIN | POLLPRI | POLLNVAL; + (void)_modify_dispatch_descriptor_(c); } - /* - * notify the client later, when we can. - */ - c->outstanding_notifiers++; - c->poll_events = POLLOUT | POLLIN | POLLPRI | POLLNVAL; - (void)_modify_dispatch_descriptor_(c); } return res; } @@ -343,8 +375,20 @@ qb_ipcs_event_send(struct qb_ipcs_connection * c, const void *data, size_t size) resn = new_event_notification(c); if (resn < 0 && resn != -EAGAIN) { errno = -resn; - qb_util_perror(LOG_WARNING, "new_event_notification"); + qb_util_perror(LOG_WARNING, + "new_event_notification (%s)", + c->description); + res = resn; } + } else if (res == -EAGAIN || res == -ETIMEDOUT) { + struct qb_ipc_one_way *ow = _event_sock_one_way_get(c); + if (ow) { + resn = qb_ipc_us_ready(ow, 0, POLLOUT); + if (resn < 0) { + res = resn; + } + } + c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -369,8 +413,20 @@ qb_ipcs_event_sendv(struct qb_ipcs_connection * c, resn = new_event_notification(c); if (resn < 0 && resn != -EAGAIN) { errno = -resn; - qb_util_perror(LOG_WARNING, "new_event_notification"); + qb_util_perror(LOG_WARNING, + "new_event_notification (%s)", + c->description); + res = resn; } + } else if (res == -EAGAIN || res == -ETIMEDOUT) { + struct qb_ipc_one_way *ow = _event_sock_one_way_get(c); + if (ow) { + resn = qb_ipc_us_ready(ow, 0, POLLOUT); + if (resn < 0) { + res = resn; + } + } + c->stats.send_retries++; } qb_ipcs_connection_unref(c); @@ -447,6 +503,7 @@ qb_ipcs_connection_alloc(struct qb_ipcs_service *s) c->request.type = s->type; c->response.type = s->type; c->event.type = s->type; + (void)strlcpy(c->description, "not set yet", CONNECTION_DESCRIPTION); return c; } @@ -468,9 +525,9 @@ qb_ipcs_connection_unref(struct qb_ipcs_connection *c) return; } if (c->refcount < 1) { - qb_util_log(LOG_ERR, "ref:%d state:%d fd:%d", + qb_util_log(LOG_ERR, "ref:%d state:%d (%s)", c->refcount, c->state, - c->setup.u.us.sock); + c->description); assert(0); } free_it = qb_atomic_int_dec_and_test(&c->refcount); @@ -494,17 +551,14 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c) if (c == NULL) { return; } - qb_util_log(LOG_DEBUG, "%s() state:%d", __func__, c->state); + qb_util_log(LOG_DEBUG, "%s(%s) state:%d", + __func__, c->description, c->state); if (c->state == QB_IPCS_CONNECTION_ACTIVE) { c->state = QB_IPCS_CONNECTION_INACTIVE; c->service->stats.closed_connections++; - if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) { - (void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock); - qb_ipcc_us_sock_close(c->setup.u.us.sock); - c->setup.u.us.sock = -1; - qb_ipcs_connection_unref(c); - } + + qb_ipcs_sockets_disconnect(c); /* return early as it's an incomplete connection. */ return; @@ -514,12 +568,7 @@ qb_ipcs_disconnect(struct qb_ipcs_connection *c) c->service->stats.active_connections--; c->service->stats.closed_connections++; - if (c->service->needs_sock_for_poll && c->setup.u.us.sock > 0) { - (void)c->service->poll_fns.dispatch_del(c->setup.u.us.sock); - qb_ipcc_us_sock_close(c->setup.u.us.sock); - c->setup.u.us.sock = -1; - qb_ipcs_connection_unref(c); - } + qb_ipcs_sockets_disconnect(c); } if (c->state == QB_IPCS_CONNECTION_SHUTTING_DOWN) { res = 0; @@ -580,20 +629,21 @@ _process_request_(struct qb_ipcs_connection *c, int32_t ms_timeout) if (size < 0) { if (size != -EAGAIN && size != -ETIMEDOUT) { qb_util_perror(LOG_ERR, - "recv from client connection failed"); + "recv from client connection failed (%s)", + c->description); } else { c->stats.recv_retries++; } res = size; goto cleanup; - } - c->stats.requests++; - - if (hdr->id == QB_IPC_MSG_DISCONNECT) { - qb_util_log(LOG_DEBUG, "client requesting a disconnect"); + } else if (size == 0 || hdr->id == QB_IPC_MSG_DISCONNECT) { + qb_util_log(LOG_DEBUG, "client requesting a disconnect (%s)", + c->description); qb_ipcs_disconnect(c); + c = NULL; res = -ESHUTDOWN; } else { + c->stats.requests++; res = c->service->serv_fns.msg_process(c, hdr, hdr->size); /* 0 == good, negative == backoff */ if (res < 0) { @@ -603,7 +653,7 @@ _process_request_(struct qb_ipcs_connection *c, int32_t ms_timeout) } } - if (c->service->funcs.peek && c->service->funcs.reclaim) { + if (c && c->service->funcs.peek && c->service->funcs.reclaim) { c->service->funcs.reclaim(&c->request); } @@ -658,8 +708,12 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data) int32_t recvd = 0; ssize_t avail; + if (revents & POLLNVAL) { + qb_util_log(LOG_DEBUG, "NVAL conn (%s)", c->description); + return -EINVAL; + } if (revents & POLLHUP) { - qb_util_log(LOG_DEBUG, "HUP conn:%p fd:%d", c, fd); + qb_util_log(LOG_DEBUG, "HUP conn (%s)", c->description); qb_ipcs_disconnect(c); return -ESHUTDOWN; } @@ -668,7 +722,9 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data) res = resend_event_notifications(c); if (res < 0 && res != -EAGAIN) { errno = -res; - qb_util_perror(LOG_WARNING, "resend_event_notifications"); + qb_util_perror(LOG_WARNING, + "resend_event_notifications (%s)", + c->description); } if ((revents & POLLIN) == 0) { return 0; @@ -681,10 +737,18 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data) if (c->service->needs_sock_for_poll && avail == 0) { res2 = qb_ipc_us_recv(&c->setup, bytes, 1, 0); - qb_util_log(LOG_WARNING, - "conn:%p Nothing in q but got POLLIN on fd:%d (res2:%d)", - c, fd, res2); - return 0; + if (qb_ipc_us_sock_error_is_disconnected(res2)) { + errno = -res2; + qb_util_perror(LOG_WARNING, "conn (%s) disconnected", + c->description); + qb_ipcs_disconnect(c); + return -ESHUTDOWN; + } else { + qb_util_log(LOG_WARNING, + "conn (%s) Nothing in q but got POLLIN on fd:%d (res2:%d)", + c->description, fd, res2); + return 0; + } } do { @@ -701,7 +765,9 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data) res2 = qb_ipc_us_recv(&c->setup, bytes, recvd, -1); if (res2 < 0) { errno = -res2; - qb_util_perror(LOG_ERR, "error receiving from setup sock"); + qb_util_perror(LOG_ERR, + "error receiving from setup sock (%s)", + c->description); } } @@ -711,7 +777,8 @@ qb_ipcs_dispatch_connection_request(int32_t fd, int32_t revents, void *data) } if (res != 0) { errno = -res; - qb_util_perror(LOG_ERR, "request returned error"); + qb_util_perror(LOG_ERR, "request returned error (%s)", + c->description); qb_ipcs_connection_unref(c); } @@ -746,12 +813,41 @@ qb_ipcs_connection_stats_get(qb_ipcs_connection_t * c, } memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats)); if (clear_after_read) { - memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats)); + memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2)); c->stats.client_pid = c->pid; } return 0; } +struct qb_ipcs_connection_stats_2* +qb_ipcs_connection_stats_get_2(qb_ipcs_connection_t *c, + int32_t clear_after_read) +{ + struct qb_ipcs_connection_stats_2* stats; + + if (c == NULL) { + errno = EINVAL; + return NULL; + } + stats = calloc(1, sizeof(struct qb_ipcs_connection_stats_2)); + if (stats == NULL) { + return NULL; + } + + memcpy(stats, &c->stats, sizeof(struct qb_ipcs_connection_stats_2)); + + if (c->service->funcs.q_len_get) { + stats->event_q_length = c->service->funcs.q_len_get(&c->event); + } else { + stats->event_q_length = 0; + } + if (clear_after_read) { + memset(&c->stats, 0, sizeof(struct qb_ipcs_connection_stats_2)); + c->stats.client_pid = c->pid; + } + return stats; +} + int32_t qb_ipcs_stats_get(struct qb_ipcs_service * s, struct qb_ipcs_stats * stats, int32_t clear_after_read) @@ -765,3 +861,14 @@ qb_ipcs_stats_get(struct qb_ipcs_service * s, } return 0; } + +void +qb_ipcs_connection_auth_set(qb_ipcs_connection_t *c, uid_t uid, + gid_t gid, mode_t mode) +{ + if (c) { + c->auth.uid = uid; + c->auth.gid = gid; + c->auth.mode = mode; + } +} diff --git a/lib/libqb.pc.in b/lib/libqb.pc.in index caaabd0..8a8d0ba 100644 --- a/lib/libqb.pc.in +++ b/lib/libqb.pc.in @@ -7,5 +7,5 @@ Name: libqb Version: @PACKAGE_VERSION@ Description: libqb Requires: -Libs: -L${libdir} -lqb @LIB_RT@ -ldl +Libs: -L${libdir} -lqb @LIBS@ Cflags: -I${includedir} diff --git a/lib/log.c b/lib/log.c index 4056b1f..128779f 100644 --- a/lib/log.c +++ b/lib/log.c @@ -225,7 +225,7 @@ qb_log_thread_log_write(struct qb_log_callsite *cs, if (t->state != QB_LOG_STATE_ENABLED) { continue; } - if (t->threaded) { + if (!t->threaded) { continue; } if (qb_bit_is_set(cs->targets, t->pos)) { @@ -287,6 +287,11 @@ qb_log_callsite_get(const char *function, _custom_filter_fn(cs); } pthread_rwlock_unlock(&_listlock); + } else if (cs->tags != tags) { + cs->tags = tags; + if (_custom_filter_fn) { + _custom_filter_fn(cs); + } } return cs; } @@ -730,6 +735,7 @@ qb_log_init(const char *name, int32_t facility, uint8_t priority) for (i = 0; i < QB_LOG_TARGET_MAX; i++) { conf[i].pos = i; conf[i].debug = QB_FALSE; + conf[i].file_sync = QB_FALSE; conf[i].state = QB_LOG_STATE_UNUSED; (void)strlcpy(conf[i].name, name, PATH_MAX); conf[i].facility = facility; @@ -894,7 +900,9 @@ qb_log_custom_close(int32_t t) target = qb_log_target_get(t); if (target->close) { + in_logger = QB_TRUE; target->close(t); + in_logger = QB_FALSE; } qb_log_target_free(target); } @@ -965,6 +973,9 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg) need_reload = QB_TRUE; } break; + case QB_LOG_CONF_FILE_SYNC: + conf[t].file_sync = arg; + break; case QB_LOG_CONF_PRIORITY_BUMP: conf[t].priority_bump = arg; break; @@ -987,7 +998,9 @@ qb_log_ctl(int32_t t, enum qb_log_conf c, int32_t arg) rc = -EINVAL; } if (rc == 0 && need_reload && conf[t].reload) { + in_logger = QB_TRUE; conf[t].reload(t); + in_logger = QB_FALSE; } return rc; } diff --git a/lib/log_blackbox.c b/lib/log_blackbox.c index e2a1f7e..06b60d2 100644 --- a/lib/log_blackbox.c +++ b/lib/log_blackbox.c @@ -38,6 +38,8 @@ _blackbox_reload(int32_t target) } /* file lineno + * tags + * priority * function name length * function name * buffer length @@ -49,8 +51,10 @@ _blackbox_vlogger(int32_t target, { size_t max_size; size_t actual_size; - size_t fn_size; + uint32_t fn_size; char *chunk; + char *msg_len_pt; + uint32_t msg_len; struct qb_log_target *t = qb_log_target_get(target); if (t->instance == NULL) { @@ -59,7 +63,7 @@ _blackbox_vlogger(int32_t target, fn_size = strlen(cs->function) + 1; - actual_size = 2 * sizeof(uint32_t) + fn_size + sizeof(time_t); + actual_size = 4 * sizeof(uint32_t) + sizeof(uint8_t) + fn_size + sizeof(time_t); max_size = actual_size + QB_LOG_MAX_LEN; chunk = qb_rb_chunk_alloc(t->instance, max_size); @@ -68,6 +72,14 @@ _blackbox_vlogger(int32_t target, memcpy(chunk, &cs->lineno, sizeof(uint32_t)); chunk += sizeof(uint32_t); + /* tags */ + memcpy(chunk, &cs->tags, sizeof(uint32_t)); + chunk += sizeof(uint32_t); + + /* log level/priority */ + memcpy(chunk, &cs->priority, sizeof(uint8_t)); + chunk += sizeof(uint8_t); + /* function name */ memcpy(chunk, &fn_size, sizeof(uint32_t)); chunk += sizeof(uint32_t); @@ -78,8 +90,26 @@ _blackbox_vlogger(int32_t target, memcpy(chunk, ×tamp, sizeof(time_t)); chunk += sizeof(time_t); + /* log message length */ + msg_len_pt = chunk; + chunk += sizeof(uint32_t); + /* log message */ - actual_size += qb_vsprintf_serialize(chunk, cs->format, ap); + msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN, cs->format, ap); + if(msg_len >= QB_LOG_MAX_LEN) { + chunk = msg_len_pt + sizeof(uint32_t); /* Reset */ + + msg_len = qb_vsnprintf_serialize(chunk, QB_LOG_MAX_LEN, + "Log message too long to be stored in the blackbox. "\ + "Maximum is QB_LOG_MAX_LEN" , ap); + actual_size += msg_len; + } + + actual_size += msg_len; + + /* now that we know the length, write it + */ + memcpy(msg_len_pt, &msg_len, sizeof(uint32_t)); (void)qb_rb_chunk_commit(t->instance, actual_size); } @@ -142,7 +172,8 @@ qb_log_blackbox_print_from_file(const char *bb_filename) { qb_ringbuffer_t *instance; ssize_t bytes_read; - char chunk[512]; + int max_size = 2 * QB_LOG_MAX_LEN; + char *chunk; int fd; char time_buf[64]; @@ -156,17 +187,21 @@ qb_log_blackbox_print_from_file(const char *bb_filename) if (instance == NULL) { return; } + chunk = malloc(max_size); do { char *ptr; uint32_t lineno; + uint32_t tags; + uint8_t priority; uint32_t fn_size; char *function; uint32_t len; time_t timestamp; + uint32_t msg_len; char message[QB_LOG_MAX_LEN]; - bytes_read = qb_rb_chunk_read(instance, chunk, 512, 0); + bytes_read = qb_rb_chunk_read(instance, chunk, max_size, 0); ptr = chunk; if (bytes_read > 0) { struct tm *tm; @@ -174,6 +209,14 @@ qb_log_blackbox_print_from_file(const char *bb_filename) memcpy(&lineno, ptr, sizeof(uint32_t)); ptr += sizeof(uint32_t); + /* tags */ + memcpy(&tags, ptr, sizeof(uint32_t)); + ptr += sizeof(uint32_t); + + /* priority */ + memcpy(&priority, ptr, sizeof(uint8_t)); + ptr += sizeof(uint8_t); + /* function size & name */ memcpy(&fn_size, ptr, sizeof(uint32_t)); ptr += sizeof(uint32_t); @@ -182,7 +225,7 @@ qb_log_blackbox_print_from_file(const char *bb_filename) ptr += fn_size; /* timestamp size & content */ - memcpy(×tamp, ptr, sizeof(uint32_t)); + memcpy(×tamp, ptr, sizeof(time_t)); ptr += sizeof(time_t); tm = localtime(×tamp); if (tm) { @@ -193,6 +236,10 @@ qb_log_blackbox_print_from_file(const char *bb_filename) snprintf(time_buf, sizeof(time_buf), "%ld", (long int)timestamp); } + /* message length */ + memcpy(&msg_len, ptr, sizeof(uint32_t)); + ptr += sizeof(uint32_t); + /* message content */ len = qb_vsnprintf_deserialize(message, QB_LOG_MAX_LEN, ptr); len--; @@ -200,8 +247,12 @@ qb_log_blackbox_print_from_file(const char *bb_filename) message[len] = '\0'; len--; } - printf("%s %s():%d %s\n", - time_buf, function, lineno, message); + message[msg_len] = '\0'; + printf("%-7s %s %s(%u):%u: %s\n", + qb_log_priority2str(priority), + time_buf, function, lineno, tags, message); } } while (bytes_read > 0); + qb_rb_close(instance); + free(chunk); } diff --git a/lib/log_dcs.c b/lib/log_dcs.c index 3142fc8..e59f57f 100644 --- a/lib/log_dcs.c +++ b/lib/log_dcs.c @@ -113,7 +113,7 @@ qb_log_dcs_get(int32_t * newly_created, int32_t rc; struct qb_log_callsite *cs = NULL; struct callsite_list *csl_head; - struct callsite_list *csl_last; + struct callsite_list *csl_last = NULL; struct callsite_list *csl; const char *safe_filename = filename; const char *safe_function = function; @@ -196,6 +196,27 @@ qb_log_dcs_init(void) void qb_log_dcs_fini(void) { + struct callsite_list *csl_head; + struct callsite_list *csl_next; + struct callsite_list *csl; + int32_t i; + int32_t rc; + int32_t cnt = qb_array_num_bins_get(lookup_arr); + cnt *= qb_array_elems_per_bin_get(lookup_arr); + + for (i = 0; i < cnt; i++) { + rc = qb_array_index(lookup_arr, i, (void **)&csl_head); + if (rc != 0 || csl_head->next == NULL) { + continue; + } + + for (csl = csl_head->next; csl; csl = csl_next) { + csl_next = csl->next; + free(csl); + } + } + + qb_array_free(lookup_arr); qb_array_free(callsite_arr); (void)qb_thread_lock_destroy(arr_next_lock); diff --git a/lib/log_file.c b/lib/log_file.c index 152c2fd..8f1a94b 100644 --- a/lib/log_file.c +++ b/lib/log_file.c @@ -26,6 +26,7 @@ _file_logger(int32_t t, struct qb_log_callsite *cs, time_t timestamp, const char *msg) { char output_buffer[QB_LOG_MAX_LEN]; + struct qb_log_target *target = qb_log_target_get(t); FILE *f = qb_log_target_user_data_get(t); if (f == NULL) { @@ -36,7 +37,11 @@ _file_logger(int32_t t, qb_log_target_format(t, cs, timestamp, msg, output_buffer); fprintf(f, "%s\n", output_buffer); + fflush(f); + if (target->file_sync) { + fsync(fileno(f)); + } } static void diff --git a/lib/log_format.c b/lib/log_format.c index 6071a30..aab62f0 100644 --- a/lib/log_format.c +++ b/lib/log_format.c @@ -51,10 +51,14 @@ static struct syslog_names prioritynames[] = { struct syslog_names facilitynames[] = { {"auth", LOG_AUTH}, +#if defined(LOG_AUTHPRIV) {"authpriv", LOG_AUTHPRIV}, +#endif {"cron", LOG_CRON}, {"daemon", LOG_DAEMON}, +#if defined(LOG_FTP) {"ftp", LOG_FTP}, +#endif {"kern", LOG_KERN}, {"lpr", LOG_LPR}, {"mail", LOG_MAIL}, @@ -110,6 +114,15 @@ qb_log_facility2str(int32_t fnum) return NULL; } +const char * +qb_log_priority2str(uint8_t priority) +{ + if (priority > LOG_TRACE) { + return prioritynames[LOG_TRACE].c_name; + } + return prioritynames[priority].c_name; +} + void qb_log_tags_stringify_fn_set(qb_log_tags_stringify_fn fn) { @@ -366,16 +379,16 @@ qb_log_target_format(int32_t target, } size_t -qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap) +qb_vsnprintf_serialize(char *serialize, size_t max_len, + const char *fmt, va_list ap) { char *format; char *p; - uint32_t location = 0; int type_long = 0; int type_longlong = 0; - - p = stpcpy(serialize, fmt); - location = p - serialize + 1; + int sformat_length = 0; + int sformat_precision = 0; + uint32_t location = strlcpy(serialize, fmt, max_len) + 1; format = (char *)fmt; for (;;) { @@ -394,7 +407,12 @@ reprocess: case '+': /* a sign should be used, ignore */ case '\'': /* group in thousands, ignore */ case 'I': /* glibc-ism locale alternative, ignore */ + format++; + goto reprocess; case '.': /* precision, ignore */ + format++; + sformat_precision = 1; + goto reprocess; case '0': /* field width, ignore */ case '1': /* field width, ignore */ case '2': /* field width, ignore */ @@ -405,11 +423,17 @@ reprocess: case '7': /* field width, ignore */ case '8': /* field width, ignore */ case '9': /* field width, ignore */ + if(sformat_precision) { + sformat_length *= 10; + sformat_length += (format[0] - '0'); + } format++; goto reprocess; - case '*': /* variable field width, save */ { int arg_int = va_arg(ap, int); + if (location + sizeof (int) > max_len) { + return max_len; + } memcpy(&serialize[location], &arg_int, sizeof (int)); location += sizeof(int); format++; @@ -433,6 +457,9 @@ reprocess: if (type_long) { long int arg_int; + if (location + sizeof (long int) > max_len) { + return max_len; + } arg_int = va_arg(ap, long int); memcpy(&serialize[location], &arg_int, sizeof(long int)); @@ -442,6 +469,9 @@ reprocess: } else if (type_longlong) { long long int arg_int; + if (location + sizeof (long long int) > max_len) { + return max_len; + } arg_int = va_arg(ap, long long int); memcpy(&serialize[location], &arg_int, sizeof(long long int)); @@ -451,6 +481,9 @@ reprocess: } else { int arg_int; + if (location + sizeof (int) > max_len) { + return max_len; + } arg_int = va_arg(ap, int); memcpy(&serialize[location], &arg_int, sizeof(int)); @@ -469,6 +502,9 @@ reprocess: { double arg_double; + if (location + sizeof (double) > max_len) { + return max_len; + } arg_double = va_arg(ap, double); memcpy (&serialize[location], &arg_double, sizeof (double)); location += sizeof(double); @@ -480,6 +516,9 @@ reprocess: int arg_int; unsigned char arg_char; + if (location + sizeof (unsigned int) > max_len) { + return max_len; + } arg_int = va_arg(ap, unsigned int); arg_char = (unsigned char)arg_int; memcpy (&serialize[location], &arg_char, sizeof (unsigned char)); @@ -490,20 +529,42 @@ reprocess: { char *arg_string; arg_string = va_arg(ap, char *); - p = stpcpy(&serialize[location], arg_string); - location += p - &serialize[location] + 1; + if (arg_string == NULL) { + location += strlcpy(&serialize[location], + "(null)", + QB_MIN(strlen("(null)") + 1, + max_len - location)); + } else if (sformat_length) { + location += strlcpy(&serialize[location], + arg_string, + QB_MIN(sformat_length + 1, + (max_len - location))); + } else { + location += strlcpy(&serialize[location], + arg_string, + QB_MIN(strlen(arg_string) + 1, + max_len - location)); + } + location++; break; } case 'p': { - void *arg_pointer; - arg_pointer = va_arg(ap, void *); - memcpy (&serialize[location], &arg_pointer, sizeof (void *)); - location += sizeof (arg_pointer); + ptrdiff_t arg_pointer = va_arg(ap, ptrdiff_t); + if (location + sizeof (ptrdiff_t) > max_len) { + return max_len; + } + memcpy(&serialize[location], &arg_pointer, sizeof(ptrdiff_t)); + location += sizeof(ptrdiff_t); break; } case '%': + if (location + 1 > max_len) { + return max_len; + } serialize[location++] = '%'; + sformat_length = 0; + sformat_precision = 0; break; } @@ -527,19 +588,18 @@ qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf) int type_longlong = 0; int len; + string[0] = '\0'; format = (char *)buf; for (;;) { type_long = 0; type_longlong = 0; p = strchrnul((const char *)format, '%'); if (*p == '\0') { - p = stpcpy(&string[location], format); - location += p - &string[location] + 1; - break; + return strlcat(string, format, str_len) + 1; } /* copy from current to the next % */ len = p - format; - strncpy(&string[location], format, len); + memcpy(&string[location], format, len); location += len; format = p; @@ -681,11 +741,14 @@ reprocess: } case 'p': { + ptrdiff_t pt; + memcpy(&pt, &buf[data_pos], + sizeof(ptrdiff_t)); fmt[fmt_pos++] = *format; fmt[fmt_pos++] = '\0'; - location = snprintf(&string[location], - str_len - location, - fmt, &buf[data_pos]); + location += snprintf(&string[location], + str_len - location, + fmt, pt); data_pos += sizeof(void*); format++; break; diff --git a/lib/log_int.h b/lib/log_int.h index 88f4b0c..cbd989b 100644 --- a/lib/log_int.h +++ b/lib/log_int.h @@ -35,6 +35,7 @@ struct qb_log_target { struct qb_list_head filter_head; int32_t facility; int32_t priority_bump; + int32_t file_sync; int32_t debug; size_t size; char *format; @@ -93,7 +94,8 @@ struct qb_log_callsite *qb_log_dcs_get(int32_t *newly_created, uint32_t lineno, uint32_t tags); -size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap); +const char * qb_log_priority2str(uint8_t priority); +size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap); size_t qb_vsnprintf_deserialize(char *string, size_t str_len, const char *buf); void qb_log_target_format_static(int32_t target, const char * format, char *output_buffer); diff --git a/lib/log_thread.c b/lib/log_thread.c index d9939d6..328eb07 100644 --- a/lib/log_thread.c +++ b/lib/log_thread.c @@ -121,7 +121,7 @@ qb_log_thread_priority_set(int32_t policy, int32_t priority) #ifdef SCHED_IDLE || policy == SCHED_IDLE #endif -#ifndef QB_DARWIN +#if defined(SCHED_BATCH) && !defined(QB_DARWIN) || policy == SCHED_BATCH #endif ) { @@ -152,6 +152,8 @@ qb_log_thread_start(void) } wthread_active = 1; + sem_init(&logt_thread_start, 0, 0); + sem_init(&logt_print_finished, 0, 0); res = pthread_create(&logt_thread_id, NULL, qb_logt_worker_thread, NULL); if (res != 0) { @@ -179,6 +181,8 @@ cleanup_pthread: wthread_should_exit = 1; sem_post(&logt_print_finished); pthread_join(logt_thread_id, NULL); + sem_destroy(&logt_print_finished); + sem_destroy(&logt_thread_start); return res; } @@ -270,4 +274,6 @@ qb_log_thread_stop(void) pthread_join(logt_thread_id, NULL); } (void)qb_thread_lock_destroy(logt_wthread_lock); + sem_destroy(&logt_print_finished); + sem_destroy(&logt_thread_start); } diff --git a/lib/loop_poll.c b/lib/loop_poll.c index 44f9601..30f8666 100644 --- a/lib/loop_poll.c +++ b/lib/loop_poll.c @@ -23,27 +23,10 @@ #ifdef HAVE_SYS_RESOURCE_H #include #endif -#ifdef HAVE_SYS_EPOLL_H -#include -#ifndef epoll_create1 -int epoll_create1(int flags); -#endif /* workaround a set of sparc and alpha broken headers */ -#endif /* HAVE_SYS_EPOLL_H */ -#ifdef HAVE_SYS_POLL_H -#include -#endif /* HAVE_SYS_POLL_H */ -#ifndef S_SPLINT_S -#endif /* S_SPLINT_S */ #include -#include -#include -#include -#include -#include -#include "loop_int.h" -#include "util_int.h" +#include "loop_poll_int.h" /* * Define this to log slow (>10ms) jobs. @@ -53,77 +36,19 @@ int epoll_create1(int flags); /* logs, std(in|out|err), pipe */ #define POLL_FDS_USED_MISC 50 -struct qb_poll_entry; - -typedef int32_t(*qb_poll_add_to_jobs_fn) (struct qb_loop * l, - struct qb_poll_entry * pe); - -struct qb_poll_entry { - struct qb_loop_item item; - qb_loop_poll_dispatch_fn poll_dispatch_fn; - enum qb_loop_priority p; - uint32_t install_pos; - struct pollfd ufd; - qb_poll_add_to_jobs_fn add_to_jobs; - uint32_t runs; - enum qb_poll_entry_state state; - uint32_t check; -}; - -struct qb_poll_source { - struct qb_loop_source s; #ifdef HAVE_EPOLL - int32_t epollfd; +#define USE_EPOLL 1 #else - struct pollfd *ufds; + #ifdef HAVE_KQUEUE + #define USE_KQUEUE 1 + #else + #define USE_POLL 1 + #endif /* HAVE_KQUEUE */ #endif /* HAVE_EPOLL */ - int32_t poll_entry_count; - qb_array_t *poll_entries; - qb_loop_poll_low_fds_event_fn low_fds_event_fn; - int32_t not_enough_fds; -}; static int32_t _qb_signal_add_to_jobs_(struct qb_loop *l, struct qb_poll_entry *pe); -#ifdef HAVE_EPOLL -static int32_t -_poll_to_epoll_event_(int32_t event) -{ - int32_t out = 0; - if (event & POLLIN) - out |= EPOLLIN; - if (event & POLLOUT) - out |= EPOLLOUT; - if (event & POLLPRI) - out |= EPOLLPRI; - if (event & POLLERR) - out |= EPOLLERR; - if (event & POLLHUP) - out |= EPOLLHUP; - if (event & POLLNVAL) - out |= EPOLLERR; - return out; -} - -static int32_t -_epoll_to_poll_event_(int32_t event) -{ - int32_t out = 0; - if (event & EPOLLIN) - out |= POLLIN; - if (event & EPOLLOUT) - out |= POLLOUT; - if (event & EPOLLPRI) - out |= POLLPRI; - if (event & EPOLLERR) - out |= POLLERR; - if (event & EPOLLHUP) - out |= POLLHUP; - return out; -} -#endif /* HAVE_EPOLL */ - static void _poll_entry_check_generate_(struct qb_poll_entry *pe) { @@ -138,28 +63,6 @@ _poll_entry_check_generate_(struct qb_poll_entry *pe) } } -#if defined(HAVE_EPOLL) -static int32_t -_poll_entry_from_handle_(struct qb_poll_source *s, - uint64_t handle_in, struct qb_poll_entry **pe_pt) -{ - int32_t res = 0; - uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); - uint32_t handle = handle_in & 0xffffffff; - struct qb_poll_entry *pe; - - res = qb_array_index(s->poll_entries, handle, (void **)&pe); - if (res != 0) { - return res; - } - if (pe->check != check) { - return -EINVAL; - } - *pe_pt = pe; - return 0; -} -#endif /* HAVE_EPOLL */ - static void _poll_entry_mark_deleted_(struct qb_poll_entry *pe) { @@ -224,8 +127,8 @@ _poll_dispatch_and_take_back_(struct qb_loop_item *item, #endif /* DEBUG_DISPATCH_TIME */ } -static void -_poll_fds_usage_check_(struct qb_poll_source *s) +void +qb_poll_fds_usage_check_(struct qb_poll_source *s) { struct rlimit lim; static int32_t socks_limit = 0; @@ -279,107 +182,6 @@ _poll_fds_usage_check_(struct qb_poll_source *s) } } -#ifdef HAVE_EPOLL -#define MAX_EVENTS 12 -static int32_t -_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout) -{ - int32_t i; - int32_t res; - int32_t event_count; - int32_t new_jobs = 0; - struct qb_poll_entry *pe = NULL; - struct qb_poll_source *s = (struct qb_poll_source *)src; - struct epoll_event events[MAX_EVENTS]; - - _poll_fds_usage_check_(s); - -retry_poll: - - event_count = epoll_wait(s->epollfd, events, MAX_EVENTS, ms_timeout); - - if (errno == EINTR && event_count == -1) { - goto retry_poll; - } else if (event_count == -1) { - return -errno; - } - - for (i = 0; i < event_count; i++) { - res = _poll_entry_from_handle_(s, events[i].data.u64, &pe); - if (res != 0) { - qb_util_log(LOG_WARNING, - "can't find poll entry for new event."); - continue; - } - if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) { - qb_util_log(LOG_WARNING, - "can't post new event to a deleted entry."); - /* - * empty/deleted - */ - continue; - } - if (events[i].events == pe->ufd.revents || - pe->state == QB_POLL_ENTRY_JOBLIST) { - /* - * entry already in the job queue. - */ - continue; - } - pe->ufd.revents = _epoll_to_poll_event_(events[i].events); - - new_jobs += pe->add_to_jobs(src->l, pe); - } - - return new_jobs; -} -#else -static int32_t -_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout) -{ - int32_t i; - int32_t res; - int32_t new_jobs = 0; - struct qb_poll_entry *pe; - struct qb_poll_source *s = (struct qb_poll_source *)src; - - _poll_fds_usage_check_(s); - - for (i = 0; i < s->poll_entry_count; i++) { - assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0); - memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd)); - } - -retry_poll: - res = poll(s->ufds, s->poll_entry_count, ms_timeout); - if (errno == EINTR && res == -1) { - goto retry_poll; - } else if (res == -1) { - return -errno; - } - - for (i = 0; i < s->poll_entry_count; i++) { - if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) { - /* - * empty entry - */ - continue; - } - assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0); - if (pe->state != QB_POLL_ENTRY_ACTIVE || - s->ufds[i].revents == pe->ufd.revents) { - /* - * Wrong state to accept an event. - */ - continue; - } - pe->ufd.revents = s->ufds[i].revents; - new_jobs += pe->add_to_jobs(src->l, pe); - } - - return new_jobs; -} -#endif /* HAVE_EPOLL */ struct qb_loop_source * qb_loop_poll_create(struct qb_loop *l) @@ -390,18 +192,21 @@ qb_loop_poll_create(struct qb_loop *l) } s->s.l = l; s->s.dispatch_and_take_back = _poll_dispatch_and_take_back_; - s->s.poll = _poll_and_add_to_jobs_; s->poll_entries = qb_array_create_2(16, sizeof(struct qb_poll_entry), 16); s->poll_entry_count = 0; s->low_fds_event_fn = NULL; s->not_enough_fds = 0; -#ifdef HAVE_EPOLL - s->epollfd = epoll_create1(EPOLL_CLOEXEC); -#else - s->ufds = 0; -#endif /* HAVE_EPOLL */ +#ifdef USE_EPOLL + (void)qb_epoll_init(s); +#endif +#ifdef USE_KQUEUE + (void)qb_kqueue_init(s); +#endif +#ifdef USE_POLL + (void)qb_poll_init(s); +#endif /* USE_POLL */ return (struct qb_loop_source *)s; } @@ -411,12 +216,9 @@ qb_loop_poll_destroy(struct qb_loop *l) { struct qb_poll_source *s = (struct qb_poll_source *)l->fd_source; qb_array_free(s->poll_entries); -#ifdef HAVE_EPOLL - if (s->epollfd != -1) { - close(s->epollfd); - s->epollfd = -1; - } -#endif /* HAVE_EPOLL */ + + s->driver.fini(s); + free(s); } @@ -437,10 +239,6 @@ _get_empty_array_position_(struct qb_poll_source *s) uint32_t install_pos; int32_t res = 0; struct qb_poll_entry *pe; -#ifndef HAVE_EPOLL - struct pollfd *ufds; - int32_t new_size = 0; -#endif /* HAVE_EPOLL */ for (found = 0, install_pos = 0; install_pos < s->poll_entry_count; install_pos++) { @@ -453,6 +251,15 @@ _get_empty_array_position_(struct qb_poll_source *s) } if (found == 0) { +#ifdef USE_POLL + struct pollfd *ufds; + int32_t new_size = (s->poll_entry_count + 1) * sizeof(struct pollfd); + ufds = realloc(s->ufds, new_size); + if (ufds == NULL) { + return -ENOMEM; + } + s->ufds = ufds; +#endif /* USE_POLL */ /* * Grow pollfd list */ @@ -460,14 +267,6 @@ _get_empty_array_position_(struct qb_poll_source *s) if (res != 0) { return res; } -#ifndef HAVE_EPOLL - new_size = (s->poll_entry_count + 1) * sizeof(struct pollfd); - ufds = realloc(s->ufds, new_size); - if (ufds == NULL) { - return -ENOMEM; - } - s->ufds = ufds; -#endif /* HAVE_EPOLL */ s->poll_entry_count += 1; install_pos = s->poll_entry_count - 1; @@ -484,9 +283,6 @@ _poll_add_(struct qb_loop *l, uint32_t install_pos; int32_t res = 0; struct qb_poll_source *s; -#ifdef HAVE_EPOLL - struct epoll_event ev; -#endif /* HAVE_EPOLL */ if (l == NULL) { return -EINVAL; @@ -507,17 +303,14 @@ _poll_add_(struct qb_loop *l, pe->item.source = (struct qb_loop_source *)l->fd_source; pe->p = p; pe->runs = 0; -#ifdef HAVE_EPOLL - ev.events = _poll_to_epoll_event_(events); - ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos; - if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { - res = -errno; - qb_util_perror(LOG_ERR, "epoll_ctl(add)"); + res = s->driver.add(s, pe, fd, events); + if (res == 0) { + *pe_pt = pe; + return 0; + } else { + pe->state = QB_POLL_ENTRY_EMPTY; + return res; } -#endif /* HAVE_EPOLL */ - *pe_pt = pe; - - return (res); } static int32_t @@ -548,6 +341,11 @@ qb_loop_poll_add(struct qb_loop * lp, size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count; res = _poll_add_(l, p, fd, events, data, &pe); + if (res != 0) { + qb_util_perror(LOG_ERR, + "couldn't add poll entryfor FD %d", fd); + return res; + } new_size = ((struct qb_poll_source *)l->fd_source)->poll_entry_count; pe->poll_dispatch_fn = dispatch_fn; @@ -573,9 +371,6 @@ qb_loop_poll_mod(struct qb_loop * lp, int32_t res = 0; struct qb_poll_entry *pe; struct qb_poll_source *s; -#ifdef HAVE_EPOLL - struct epoll_event ev; -#endif /* HAVE_EPOLL */ struct qb_loop *l = lp; if (l == NULL) { @@ -600,14 +395,7 @@ qb_loop_poll_mod(struct qb_loop * lp, pe->item.user_data = data; pe->p = p; if (pe->ufd.events != events) { -#ifdef HAVE_EPOLL - ev.events = _poll_to_epoll_event_(events); - ev.data.u64 = (((uint64_t) (pe->check)) << 32) | i; - if (epoll_ctl(s->epollfd, EPOLL_CTL_MOD, fd, &ev) == -1) { - res = -errno; - qb_util_perror(LOG_ERR, "epoll_ctl(mod)"); - } -#endif /* HAVE_EPOLL */ + res = s->driver.mod(s, pe, fd, events); pe->ufd.events = events; } return res; @@ -641,16 +429,7 @@ qb_loop_poll_del(struct qb_loop * lp, int32_t fd) if (pe->state == QB_POLL_ENTRY_JOBLIST) { qb_loop_level_item_del(&l->level[pe->p], &pe->item); } -#ifdef HAVE_EPOLL - if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) { - res = -errno; - qb_util_perror(LOG_WARNING, "epoll_ctl(del)"); - } -#else - s->ufds[i].fd = -1; - s->ufds[i].events = 0; - s->ufds[i].revents = 0; -#endif /* HAVE_EPOLL */ + res = s->driver.del(s, pe, fd, i); _poll_entry_mark_deleted_(pe); return res; } diff --git a/lib/loop_poll_epoll.c b/lib/loop_poll_epoll.c new file mode 100644 index 0000000..b4039b0 --- /dev/null +++ b/lib/loop_poll_epoll.c @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * Author: Angus Salkeld + * + * This file is part of libqb. + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ + +#include "os_base.h" +#include "loop_poll_int.h" + +#ifdef HAVE_SYS_EPOLL_H +#include +#ifndef epoll_create1 +int epoll_create1(int flags); +#endif /* workaround a set of sparc and alpha broken headers */ +#endif /* HAVE_SYS_EPOLL_H */ + +#define MAX_EVENTS 12 + +static int32_t +_poll_to_epoll_event_(int32_t event) +{ + int32_t out = 0; + if (event & POLLIN) + out |= EPOLLIN; + if (event & POLLOUT) + out |= EPOLLOUT; + if (event & POLLPRI) + out |= EPOLLPRI; + if (event & POLLERR) + out |= EPOLLERR; + if (event & POLLHUP) + out |= EPOLLHUP; + if (event & POLLNVAL) + out |= EPOLLERR; + return out; +} + +static int32_t +_epoll_to_poll_event_(int32_t event) +{ + int32_t out = 0; + if (event & EPOLLIN) + out |= POLLIN; + if (event & EPOLLOUT) + out |= POLLOUT; + if (event & EPOLLPRI) + out |= POLLPRI; + if (event & EPOLLERR) + out |= POLLERR; + if (event & EPOLLHUP) + out |= POLLHUP; + return out; +} + +static void +_fini(struct qb_poll_source *s) +{ + if (s->epollfd != -1) { + close(s->epollfd); + s->epollfd = -1; + } +} + +static int32_t +_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + struct epoll_event ev; + int32_t res = 0; + + ev.events = _poll_to_epoll_event_(events); + ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos; + if (epoll_ctl(s->epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) { + res = -errno; + qb_util_perror(LOG_ERR, "epoll_ctl(add)"); + } + return res; +} + + +static int32_t +_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + struct epoll_event ev; + int32_t res = 0; + + ev.events = _poll_to_epoll_event_(events); + ev.data.u64 = (((uint64_t) (pe->check)) << 32) | pe->install_pos; + if (epoll_ctl(s->epollfd, EPOLL_CTL_MOD, fd, &ev) == -1) { + res = -errno; + qb_util_perror(LOG_DEBUG, "epoll_ctl(mod)"); + } + return res; +} + +static int32_t +_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t arr_index) +{ + int32_t res = 0; + + if (epoll_ctl(s->epollfd, EPOLL_CTL_DEL, fd, NULL) == -1) { + res = -errno; + qb_util_perror(LOG_DEBUG, "epoll_ctl(del)"); + } + return res; +} + +static int32_t +_poll_entry_from_handle_(struct qb_poll_source *s, + uint64_t handle_in, struct qb_poll_entry **pe_pt) +{ + int32_t res = 0; + uint32_t check = ((uint32_t) (((uint64_t) handle_in) >> 32)); + uint32_t handle = handle_in & 0xffffffff; + struct qb_poll_entry *pe; + + res = qb_array_index(s->poll_entries, handle, (void **)&pe); + if (res != 0) { + return res; + } + if (pe->check != check) { + return -EINVAL; + } + *pe_pt = pe; + return 0; +} + +static int32_t +_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout) +{ + int32_t i; + int32_t res; + int32_t event_count; + int32_t new_jobs = 0; + struct qb_poll_entry *pe = NULL; + struct qb_poll_source *s = (struct qb_poll_source *)src; + struct epoll_event events[MAX_EVENTS]; + + qb_poll_fds_usage_check_(s); + +retry_poll: + + event_count = epoll_wait(s->epollfd, events, MAX_EVENTS, ms_timeout); + + if (errno == EINTR && event_count == -1) { + goto retry_poll; + } else if (event_count == -1) { + return -errno; + } + + for (i = 0; i < event_count; i++) { + res = _poll_entry_from_handle_(s, events[i].data.u64, &pe); + if (res != 0) { + qb_util_log(LOG_WARNING, + "can't find poll entry for new event."); + continue; + } + if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) { + qb_util_log(LOG_WARNING, + "can't post new event to a deleted entry."); + /* + * empty/deleted + */ + continue; + } + if (events[i].events == pe->ufd.revents || + pe->state == QB_POLL_ENTRY_JOBLIST) { + /* + * entry already in the job queue. + */ + continue; + } + pe->ufd.revents = _epoll_to_poll_event_(events[i].events); + + new_jobs += pe->add_to_jobs(src->l, pe); + } + + return new_jobs; +} + +int32_t +qb_epoll_init(struct qb_poll_source *s) +{ + s->epollfd = epoll_create1(EPOLL_CLOEXEC); + if (s->epollfd < 0) { + return -errno; + } + s->driver.fini = _fini; + s->driver.add = _add; + s->driver.mod = _mod; + s->driver.del = _del; + s->s.poll = _poll_and_add_to_jobs_; + return 0; +} + diff --git a/lib/loop_poll_int.h b/lib/loop_poll_int.h new file mode 100644 index 0000000..f99f442 --- /dev/null +++ b/lib/loop_poll_int.h @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * Author: Angus Salkeld + * + * This file is part of libqb. + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ +#ifndef QB_LOOP_POLL_INT_DEFINED +#define QB_LOOP_POLL_INT_DEFINED + +#include "os_base.h" + +#ifdef HAVE_SYS_POLL_H +#include +#endif /* HAVE_SYS_POLL_H */ + +#include +#include +#include +#include + +#include "loop_int.h" +#include "util_int.h" + +struct qb_poll_entry; + +typedef int32_t(*qb_poll_add_to_jobs_fn) (struct qb_loop * l, + struct qb_poll_entry * pe); + +struct qb_poll_entry { + struct qb_loop_item item; + qb_loop_poll_dispatch_fn poll_dispatch_fn; + enum qb_loop_priority p; + uint32_t install_pos; + struct pollfd ufd; + qb_poll_add_to_jobs_fn add_to_jobs; + uint32_t runs; + enum qb_poll_entry_state state; + uint32_t check; +}; + +struct qb_poll_source; + +struct qb_loop_driver { + int32_t (*poll)(struct qb_loop_source* s, int32_t ms_timeout); + void (*fini)(struct qb_poll_source *s); + int32_t (*add)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events); + int32_t (*mod)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events); + int32_t (*del)(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t arr_index); +}; + +struct qb_poll_source { + struct qb_loop_source s; + int32_t poll_entry_count; + qb_array_t *poll_entries; + qb_loop_poll_low_fds_event_fn low_fds_event_fn; + int32_t not_enough_fds; +#if defined(HAVE_EPOLL) || defined(HAVE_KQUEUE) + int32_t epollfd; +#else + struct pollfd *ufds; +#endif /* HAVE_EPOLL */ + struct qb_loop_driver driver; +}; + +void +qb_poll_fds_usage_check_(struct qb_poll_source *s); + +int32_t +qb_epoll_init(struct qb_poll_source *s); + +int32_t +qb_poll_init(struct qb_poll_source *s); + +int32_t +qb_kqueue_init(struct qb_poll_source *s); + +#endif /* QB_LOOP_POLL_INT_DEFINED */ diff --git a/lib/loop_poll_kqueue.c b/lib/loop_poll_kqueue.c new file mode 100644 index 0000000..3149640 --- /dev/null +++ b/lib/loop_poll_kqueue.c @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * Author: Angus Salkeld + * + * This file is part of libqb. + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ + +#include "os_base.h" +#include "loop_poll_int.h" + +#ifdef HAVE_SYS_EVENT_H +#include +#endif /* HAVE_SYS_EVENT_H */ + +#define MAX_EVENTS 12 + +static int32_t +_poll_to_filter_(int32_t event) +{ + int32_t out = 0; + if (event & POLLIN) + out |= EVFILT_READ; + if (event & POLLOUT) + out |= EVFILT_WRITE; + return out; +} + +static void +_fini(struct qb_poll_source *s) +{ + if (s->epollfd != -1) { + close(s->epollfd); + s->epollfd = -1; + } +} + +static int32_t +_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + int32_t res = 0; + struct kevent ke; + short filters = _poll_to_filter_(events); + + EV_SET(&ke, fd, filters, EV_ADD, 0, 0, (intptr_t)pe); + + res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL); + if (res == -1) { + res = -errno; + qb_util_perror(LOG_ERR, "kevent(add)"); + } + + return res; +} + +static int32_t +_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + int32_t res = 0; + struct kevent ke[2]; + short new_filters = _poll_to_filter_(events); + short old_filters = _poll_to_filter_(pe->ufd.events); + + EV_SET(&ke[0], fd, old_filters, EV_DELETE, 0, 0, (intptr_t)pe); + EV_SET(&ke[1], fd, new_filters, EV_ADD, 0, 0, (intptr_t)pe); + + res = kevent(s->epollfd, ke, 2, NULL, 0, NULL); + if (res == -1) { + res = -errno; + qb_util_perror(LOG_ERR, "kevent(mod)"); + } + return res; +} + +static int32_t +_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + int32_t res = 0; + struct kevent ke; + short filters = _poll_to_filter_(events); + + EV_SET(&ke, fd, filters, EV_DELETE, 0, 0, (intptr_t)pe); + + res = kevent(s->epollfd, &ke, 1, NULL, 0, NULL); + if (res == -1 && errno == ENOENT) { + /* + * Not a problem already cleaned up. + */ + res = 0; + } else if (res == -1) { + res = -errno; + qb_util_perror(LOG_ERR, "kevent(del)"); + } + return res; +} + +static int32_t +_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout) +{ + int32_t i; + int32_t event_count; + int32_t new_jobs = 0; + int32_t revents = 0; + struct qb_poll_entry *pe = NULL; + struct qb_poll_source *s = (struct qb_poll_source *)src; + struct kevent events[MAX_EVENTS]; + struct timespec timeout = { 0, 0 }; + struct timespec *timeout_pt = &timeout; + + if (ms_timeout > 0) { + qb_timespec_add_ms(&timeout, ms_timeout); + } else if (ms_timeout < 0) { + timeout_pt = NULL; + } + qb_poll_fds_usage_check_(s); + +retry_poll: + + event_count = kevent(s->epollfd, NULL, 0, events, MAX_EVENTS, timeout_pt); + if (errno == EINTR && event_count == -1) { + goto retry_poll; + } else if (event_count == -1) { + qb_util_perror(LOG_ERR, "kevent(poll)"); + return -errno; + } + + for (i = 0; i < event_count; i++) { + revents = 0; + pe = (struct qb_poll_entry *)events[i].udata; + if (events[i].flags) { + qb_util_log(LOG_TRACE, + "got flags %d on fd %d.", events[i].flags, + pe->ufd.fd); + } + if (events[i].flags & EV_ERROR) { + qb_util_log(LOG_WARNING, + "got EV_ERROR on fd %d.", pe->ufd.fd); + revents |= POLLERR; + } + if (events[i].flags & EV_EOF) { + qb_util_log(LOG_INFO, + "got EV_EOF on fd %d.", pe->ufd.fd); + revents |= POLLHUP; + } + if (events[i].filter == EVFILT_READ) { + revents |= POLLIN; + } + if (events[i].filter == EVFILT_WRITE) { + revents |= POLLOUT; + } + if (pe->ufd.fd == -1 || pe->state == QB_POLL_ENTRY_DELETED) { + qb_util_log(LOG_WARNING, + "can't post new event to a deleted entry."); + /* + * empty/deleted + */ + EV_SET(&events[i], events[i].ident, events[i].filter, + EV_DELETE, 0, 0, (intptr_t)pe); + (void)kevent(s->epollfd, &events[i], 1, NULL, 0, NULL); + continue; + } + if (pe->ufd.fd != events[i].ident) { + qb_util_log(LOG_WARNING, + "can't find poll entry for new event."); + continue; + } + if (revents == pe->ufd.revents || + pe->state == QB_POLL_ENTRY_JOBLIST) { + /* + * entry already in the job queue. + */ + continue; + } + pe->ufd.revents = revents; + + new_jobs += pe->add_to_jobs(src->l, pe); + } + + return new_jobs; +} + +int32_t +qb_kqueue_init(struct qb_poll_source *s) +{ + s->epollfd = kqueue(); + + if (s->epollfd < 0) { + qb_util_perror(LOG_ERR, "kqueue()"); + return -errno; + } + s->driver.fini = _fini; + s->driver.add = _add; + s->driver.mod = _mod; + s->driver.del = _del; + s->s.poll = _poll_and_add_to_jobs_; + return 0; +} diff --git a/lib/loop_poll_poll.c b/lib/loop_poll_poll.c new file mode 100644 index 0000000..ecc7418 --- /dev/null +++ b/lib/loop_poll_poll.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2012 Red Hat, Inc. + * + * Author: Angus Salkeld + * + * This file is part of libqb. + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ +#include "os_base.h" + +#include "loop_poll_int.h" + + +static void +_fini(struct qb_poll_source *s) +{ +} + +static int32_t +_add(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + return 0; +} + +static int32_t +_mod(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t events) +{ + return 0; +} + +static int32_t +_del(struct qb_poll_source *s, struct qb_poll_entry *pe, int32_t fd, int32_t i) +{ + s->ufds[i].fd = -1; + s->ufds[i].events = 0; + s->ufds[i].revents = 0; + return 0; +} + +static int32_t +_poll_and_add_to_jobs_(struct qb_loop_source *src, int32_t ms_timeout) +{ + int32_t i; + int32_t res; + int32_t new_jobs = 0; + struct qb_poll_entry *pe; + struct qb_poll_source *s = (struct qb_poll_source *)src; + + qb_poll_fds_usage_check_(s); + + for (i = 0; i < s->poll_entry_count; i++) { + assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0); + memcpy(&s->ufds[i], &pe->ufd, sizeof(struct pollfd)); + } + +retry_poll: + res = poll(s->ufds, s->poll_entry_count, ms_timeout); + if (errno == EINTR && res == -1) { + goto retry_poll; + } else if (res == -1) { + return -errno; + } + + for (i = 0; i < s->poll_entry_count; i++) { + if (s->ufds[i].fd == -1 || s->ufds[i].revents == 0) { + /* + * empty entry + */ + continue; + } + assert(qb_array_index(s->poll_entries, i, (void **)&pe) == 0); + if (pe->state != QB_POLL_ENTRY_ACTIVE || + s->ufds[i].revents == pe->ufd.revents) { + /* + * Wrong state to accept an event. + */ + continue; + } + pe->ufd.revents = s->ufds[i].revents; + new_jobs += pe->add_to_jobs(src->l, pe); + } + + return new_jobs; +} + +int32_t +qb_poll_init(struct qb_poll_source *s) +{ + s->ufds = 0; + s->driver.fini = _fini; + s->driver.add = _add; + s->driver.mod = _mod; + s->driver.del = _del; + s->s.poll = _poll_and_add_to_jobs_; + return 0; +} + diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c index f46d735..af45174 100644 --- a/lib/ringbuffer.c +++ b/lib/ringbuffer.c @@ -34,6 +34,35 @@ do { \ #define DEBUG_PRINTF(format, args...) #endif /* CRAZY_DEBUG_PRINTFS */ +/* + * move the write pointer to the next 128 byte boundary + * write_pt goes in 4 bytes (sizeof(uint32_t)) + * #define USE_CACHE_LINE_ALIGNMENT 1 + */ +#ifdef USE_CACHE_LINE_ALIGNMENT +#define QB_CACHE_LINE_SIZE 128 +#define QB_CACHE_LINE_WORDS (QB_CACHE_LINE_SIZE/sizeof(uint32_t)) +#define idx_cache_line_step(idx) \ +do { \ + if (idx % QB_CACHE_LINE_WORDS) { \ + idx += (QB_CACHE_LINE_WORDS - (idx % QB_CACHE_LINE_WORDS)); \ + } \ + if (idx > (rb->shared_hdr->word_size - 1)) { \ + idx = ((idx) % (rb->shared_hdr->word_size)); \ + } \ +} while (0) +#else +#define QB_CACHE_LINE_SIZE 0 +#define QB_CACHE_LINE_WORDS 0 +#define idx_cache_line_step(idx) \ +do { \ + if (idx > (rb->shared_hdr->word_size - 1)) { \ + idx = ((idx) % (rb->shared_hdr->word_size)); \ + } \ +} while (0) +#endif + + /* the chunk header is two words * 1) the chunk data size * 2) the magic number @@ -46,16 +75,31 @@ do { \ * So: * qb_rb_space_free() >= QB_RB_CHUNK_MARGIN + new data chunk * The extra word size is to allow for non word sized data chunks. + * QB_CACHE_LINE_WORDS is to make sure we have space to align the + * chunk. */ -#define QB_RB_CHUNK_MARGIN (sizeof(uint32_t) * (QB_RB_CHUNK_HEADER_WORDS + 1)) -#define QB_RB_CHUNK_MAGIC 0xAAAAAAAA +#define QB_RB_WORD_ALIGN 1 +#define QB_RB_CHUNK_MARGIN (sizeof(uint32_t) * (QB_RB_CHUNK_HEADER_WORDS +\ + QB_RB_WORD_ALIGN +\ + QB_CACHE_LINE_WORDS)) +#define QB_RB_CHUNK_MAGIC 0xA1A1A1A1 +#define QB_RB_CHUNK_MAGIC_DEAD 0xD0D0D0D0 +#define QB_RB_CHUNK_MAGIC_ALLOC 0xA110CED0 #define QB_RB_CHUNK_SIZE_GET(rb, pointer) \ rb->shared_data[pointer] #define QB_RB_CHUNK_MAGIC_GET(rb, pointer) \ rb->shared_data[(pointer + 1) % rb->shared_hdr->word_size] +#define QB_RB_CHUNK_MAGIC_SET(rb, pointer, new_val) \ + rb->shared_data[(pointer + 1) % rb->shared_hdr->word_size] = new_val; +#define QB_RB_CHUNK_DATA_GET(rb, pointer) \ + &rb->shared_data[(pointer + QB_RB_CHUNK_HEADER_WORDS) % rb->shared_hdr->word_size] -#define QB_RB_WRITE_PT_INDEX (rb->shared_hdr->word_size) -#define QB_RB_READ_PT_INDEX (rb->shared_hdr->word_size + 1) +#define QB_MAGIC_ASSERT(_ptr_) \ +do { \ + uint32_t chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, _ptr_); \ + if (chunk_magic != QB_RB_CHUNK_MAGIC) print_header(rb); \ + assert(chunk_magic == QB_RB_CHUNK_MAGIC); \ +} while (0) #define idx_step(idx) \ do { \ @@ -64,33 +108,8 @@ do { \ } \ } while (0) -/* - * move the write pointer to the next 32 byte boundary - * write_pt goes in 4 bytes (sizeof(uint32_t)) - */ -/* - * #define USE_CACHE_LINE_ALIGNMENT 1 - */ -#ifdef USE_CACHE_LINE_ALIGNMENT -#define idx_cache_line_step(idx) \ -do { \ - if (idx % 8) { \ - idx += (8 - (idx % 8)); \ - } \ - if (idx > (rb->shared_hdr->word_size - 1)) { \ - idx = ((idx) % (rb->shared_hdr->word_size)); \ - } \ -} while (0) -#else -#define idx_cache_line_step(idx) \ -do { \ - if (idx > (rb->shared_hdr->word_size - 1)) { \ - idx = ((idx) % (rb->shared_hdr->word_size)); \ - } \ -} while (0) -#endif - -static void qb_rb_chunk_check(struct qb_ringbuffer_s * rb, uint32_t pointer); +static void print_header(struct qb_ringbuffer_s * rb); +static void _rb_chunk_reclaim(struct qb_ringbuffer_s * rb); qb_ringbuffer_t * qb_rb_open(const char *name, size_t size, uint32_t flags, @@ -221,7 +240,9 @@ cleanup_hdr: } if (rb && (flags & QB_RB_FLAG_CREATE)) { unlink(rb->shared_hdr->hdr_path); - (void)rb->sem_destroy_fn(rb); + if (rb->sem_destroy_fn) { + (void)rb->sem_destroy_fn(rb); + } } if (rb && (rb->shared_hdr != MAP_FAILED && rb->shared_hdr != NULL)) { munmap(rb->shared_hdr, sizeof(struct qb_ringbuffer_shared_s)); @@ -240,7 +261,9 @@ qb_rb_close(struct qb_ringbuffer_s * rb) (void)qb_atomic_int_dec_and_test(&rb->shared_hdr->ref_count); if (rb->flags & QB_RB_FLAG_CREATE) { - (void)rb->sem_destroy_fn(rb); + if (rb->sem_destroy_fn) { + (void)rb->sem_destroy_fn(rb); + } unlink(rb->shared_hdr->data_path); unlink(rb->shared_hdr->hdr_path); qb_util_log(LOG_DEBUG, @@ -262,7 +285,9 @@ qb_rb_force_close(struct qb_ringbuffer_s * rb) return; } - (void)rb->sem_destroy_fn(rb); + if (rb->sem_destroy_fn) { + (void)rb->sem_destroy_fn(rb); + } unlink(rb->shared_hdr->data_path); unlink(rb->shared_hdr->hdr_path); qb_util_log(LOG_DEBUG, @@ -311,9 +336,6 @@ qb_rb_space_free(struct qb_ringbuffer_s * rb) return -EINVAL; } write_size = rb->shared_hdr->write_pt; - /* - * TODO idx_cache_line_step (write_size); - */ read_size = rb->shared_hdr->read_pt; if (write_size > read_size) { @@ -322,7 +344,11 @@ qb_rb_space_free(struct qb_ringbuffer_s * rb) } else if (write_size < read_size) { space_free = (read_size - write_size) - 1; } else { - space_free = rb->shared_hdr->word_size; + if (rb->sem_getvalue_fn && rb->sem_getvalue_fn(rb) > 0) { + space_free = 0; + } else { + space_free = rb->shared_hdr->word_size; + } } /* word -> bytes */ @@ -360,7 +386,11 @@ qb_rb_chunks_used(struct qb_ringbuffer_s *rb) if (rb == NULL) { return -EINVAL; } - return rb->sem_getvalue_fn(rb); + if (rb->sem_getvalue_fn) { + return rb->sem_getvalue_fn(rb); + } else { + return -ENOTSUP; + } } void * @@ -369,6 +399,7 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len) uint32_t write_pt; if (rb == NULL) { + errno = EINVAL; return NULL; } /* @@ -376,7 +407,7 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len) */ if (rb->flags & QB_RB_FLAG_OVERWRITE) { while (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) { - qb_rb_chunk_reclaim(rb); + _rb_chunk_reclaim(rb); } } else { if (qb_rb_space_free(rb) < (len + QB_RB_CHUNK_MARGIN)) { @@ -389,15 +420,13 @@ qb_rb_chunk_alloc(struct qb_ringbuffer_s * rb, size_t len) /* * insert the chunk header */ - rb->shared_data[write_pt++] = 0; - idx_step(write_pt); - rb->shared_data[write_pt++] = QB_RB_CHUNK_MAGIC; - idx_step(write_pt); + rb->shared_data[write_pt] = 0; + QB_RB_CHUNK_MAGIC_SET(rb, write_pt, QB_RB_CHUNK_MAGIC_ALLOC); /* * return a pointer to the beginning of the chunk data */ - return (void *)&rb->shared_data[write_pt]; + return (void *)QB_RB_CHUNK_DATA_GET(rb, write_pt); } @@ -409,14 +438,13 @@ qb_rb_chunk_step(struct qb_ringbuffer_s * rb, uint32_t pointer) * skip over the chunk header */ pointer += QB_RB_CHUNK_HEADER_WORDS; - idx_step(pointer); /* * skip over the user's data. */ pointer += (chunk_size / sizeof(uint32_t)); /* make allowance for non-word sizes */ - if ((chunk_size % sizeof(uint32_t)) != 0) { + if ((chunk_size % (sizeof(uint32_t) * QB_RB_WORD_ALIGN)) != 0) { pointer++; } @@ -437,21 +465,28 @@ qb_rb_chunk_commit(struct qb_ringbuffer_s * rb, size_t len) */ old_write_pt = rb->shared_hdr->write_pt; rb->shared_data[old_write_pt] = len; - rb->shared_data[old_write_pt + 1] = QB_RB_CHUNK_MAGIC; /* * commit the new write pointer */ rb->shared_hdr->write_pt = qb_rb_chunk_step(rb, old_write_pt); + QB_RB_CHUNK_MAGIC_SET(rb, old_write_pt, QB_RB_CHUNK_MAGIC); - DEBUG_PRINTF("%s: read: %u, write: %u (was:%u)\n", __func__, - rb->shared_hdr->read_pt, rb->shared_hdr->write_pt, - old_write_pt); + DEBUG_PRINTF("commit [%zd] read: %u, write: %u -> %u (%u)\n", + (rb->sem_getvalue_fn ? rb->sem_getvalue_fn(rb) : 0), + rb->shared_hdr->read_pt, + old_write_pt, + rb->shared_hdr->write_pt, + rb->shared_hdr->word_size); /* * post the notification to the reader */ - return rb->sem_post_fn(rb); + if (rb->sem_post_fn) { + return rb->sem_post_fn(rb); + } else { + return 0; + } } ssize_t @@ -478,59 +513,85 @@ qb_rb_chunk_write(struct qb_ringbuffer_s * rb, const void *data, size_t len) return len; } -void -qb_rb_chunk_reclaim(struct qb_ringbuffer_s * rb) +static void +_rb_chunk_reclaim(struct qb_ringbuffer_s * rb) { uint32_t old_read_pt; + uint32_t new_read_pt; + uint32_t chunk_magic; - if (rb == NULL || qb_rb_space_used(rb) == 0) { + old_read_pt = rb->shared_hdr->read_pt; + chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, old_read_pt); + if (chunk_magic != QB_RB_CHUNK_MAGIC) { return; } - old_read_pt = rb->shared_hdr->read_pt; - qb_rb_chunk_check(rb, old_read_pt); - rb->shared_hdr->read_pt = qb_rb_chunk_step(rb, old_read_pt); + new_read_pt = qb_rb_chunk_step(rb, old_read_pt); /* * clear the header */ rb->shared_data[old_read_pt] = 0; - rb->shared_data[old_read_pt + 1] = 0; + QB_RB_CHUNK_MAGIC_SET(rb, old_read_pt, QB_RB_CHUNK_MAGIC_DEAD); - DEBUG_PRINTF("%s: read: %u (was:%u), write: %u\n", __func__, - rb->shared_hdr->read_pt, old_read_pt, + /* + * set the new read pointer after clearing the header + * to prevent a situation where a fast writer will write their + * new chunk between setting the new read pointer and clearing the + * header. + */ + rb->shared_hdr->read_pt = new_read_pt; + + DEBUG_PRINTF("reclaim [%zd]: read: %u -> %u, write: %u\n", + (rb->sem_getvalue_fn ? rb->sem_getvalue_fn(rb) : 0), + old_read_pt, + rb->shared_hdr->read_pt, rb->shared_hdr->write_pt); } +void +qb_rb_chunk_reclaim(struct qb_ringbuffer_s * rb) +{ + if (rb == NULL) { + return; + } + _rb_chunk_reclaim(rb); +} + ssize_t qb_rb_chunk_peek(struct qb_ringbuffer_s * rb, void **data_out, int32_t timeout) { uint32_t read_pt; uint32_t chunk_size; uint32_t chunk_magic; - int32_t res; + int32_t res = 0; if (rb == NULL) { return -EINVAL; } - res = rb->sem_timedwait_fn(rb, timeout); + if (rb->sem_timedwait_fn) { + res = rb->sem_timedwait_fn(rb, timeout); + } if (res < 0 && res != -EIDRM) { - if (res != -ETIMEDOUT) { + if (res == -ETIMEDOUT) { + return 0; + } else { + errno = -res; qb_util_perror(LOG_ERR, "sem_timedwait"); } return res; } read_pt = rb->shared_hdr->read_pt; - chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt); chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt); - *data_out = &rb->shared_data[read_pt + QB_RB_CHUNK_HEADER_WORDS]; - if (chunk_magic != QB_RB_CHUNK_MAGIC) { - errno = ENOMSG; + if (rb->sem_post_fn) { + (void)rb->sem_post_fn(rb); + } return 0; - } else { - return chunk_size; } + chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt); + *data_out = QB_RB_CHUNK_DATA_GET(rb, read_pt); + return chunk_size; } ssize_t @@ -539,6 +600,7 @@ qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t len, { uint32_t read_pt; uint32_t chunk_size; + uint32_t chunk_magic; int32_t res = 0; if (rb == NULL) { @@ -554,26 +616,36 @@ qb_rb_chunk_read(struct qb_ringbuffer_s * rb, void *data_out, size_t len, return res; } - if (qb_rb_space_used(rb) == 0) { - return -ENOMSG; + read_pt = rb->shared_hdr->read_pt; + chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt); + + if (chunk_magic != QB_RB_CHUNK_MAGIC) { + if (rb->sem_timedwait_fn == NULL) { + return -ETIMEDOUT; + } else { + (void)rb->sem_post_fn(rb); +#ifdef EBADMSG + return -EBADMSG; +#else + return -EINVAL; +#endif + } } - read_pt = rb->shared_hdr->read_pt; - qb_rb_chunk_check(rb, read_pt); chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt); - if (len < chunk_size) { qb_util_log(LOG_ERR, "trying to recv chunk of size %d but %d available", len, chunk_size); + (void)rb->sem_post_fn(rb); return -ENOBUFS; } - + ; memcpy(data_out, - &rb->shared_data[read_pt + QB_RB_CHUNK_HEADER_WORDS], + QB_RB_CHUNK_DATA_GET(rb, read_pt), chunk_size); - qb_rb_chunk_reclaim(rb); + _rb_chunk_reclaim(rb); return chunk_size; } @@ -596,21 +668,6 @@ print_header(struct qb_ringbuffer_s * rb) #endif /* S_SPLINT_S */ } -static void -qb_rb_chunk_check(struct qb_ringbuffer_s * rb, uint32_t pointer) -{ - uint32_t chunk_size; - uint32_t chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, pointer); - - if (chunk_magic != QB_RB_CHUNK_MAGIC) { - chunk_size = QB_RB_CHUNK_SIZE_GET(rb, pointer); - printf("size: %x\n", chunk_size); - printf("magic: %x\n", chunk_magic); - print_header(rb); - assert(0); - } -} - ssize_t qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd) { @@ -628,13 +685,6 @@ qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd) } written_size += result; - result = write(fd, rb->shared_data, - rb->shared_hdr->word_size * sizeof(uint32_t)); - if (result != rb->shared_hdr->word_size * sizeof(uint32_t)) { - return -errno; - } - written_size += result; - /* * store the read & write pointers */ @@ -649,6 +699,13 @@ qb_rb_write_to_file(struct qb_ringbuffer_s * rb, int32_t fd) } written_size += result; + result = write(fd, rb->shared_data, + rb->shared_hdr->word_size * sizeof(uint32_t)); + if (result != rb->shared_hdr->word_size * sizeof(uint32_t)) { + return -errno; + } + written_size += result; + qb_util_log(LOG_DEBUG, " writing total of: %zd\n", written_size); return written_size; @@ -663,35 +720,37 @@ qb_rb_create_from_file(int32_t fd, uint32_t flags) uint32_t read_pt; uint32_t write_pt; struct qb_ringbuffer_s *rb; + uint32_t word_size = 0; if (fd < 0) { return NULL; } - rb = calloc(1, sizeof(struct qb_ringbuffer_s)); - if (rb == NULL) { - return NULL; - } - rb->shared_hdr = calloc(1, sizeof(struct qb_ringbuffer_shared_s)); - if (rb->shared_hdr == NULL) { - goto cleanup_fail2; - } - - rb->flags = flags; n_required = sizeof(uint32_t); - n_read = read(fd, &rb->shared_hdr->word_size, n_required); + n_read = read(fd, &word_size, n_required); if (n_read != n_required) { qb_util_perror(LOG_ERR, "Unable to read blackbox file header"); - goto cleanup_fail; + return NULL; } total_read += n_read; - n_required = (rb->shared_hdr->word_size * sizeof(uint32_t)); + n_read = read(fd, &write_pt, sizeof(uint32_t)); + assert(n_read == sizeof(uint32_t)); + total_read += n_read; - if ((rb->shared_data = malloc(n_required)) == NULL) { - qb_util_perror(LOG_ERR, "exhausted virtual memory"); - goto cleanup_fail; + n_read = read(fd, &read_pt, sizeof(uint32_t)); + assert(n_read == sizeof(uint32_t)); + total_read += n_read; + + n_required = (word_size * sizeof(uint32_t)); + rb = qb_rb_open("create_from_file", n_required, + QB_RB_FLAG_CREATE | QB_RB_FLAG_NO_SEMAPHORE, 0); + if (rb == NULL) { + return NULL; } + rb->shared_hdr->read_pt = read_pt; + rb->shared_hdr->write_pt = write_pt; + n_read = read(fd, rb->shared_data, n_required); if (n_read < 0) { qb_util_perror(LOG_ERR, "Unable to read blackbox file data"); @@ -705,25 +764,13 @@ qb_rb_create_from_file(int32_t fd, uint32_t flags) goto cleanup_fail; } - n_read = read(fd, &write_pt, sizeof(uint32_t)); - assert(n_read == sizeof(uint32_t)); - rb->shared_hdr->write_pt = write_pt; - total_read += n_read; - - n_read = read(fd, &read_pt, sizeof(uint32_t)); - assert(n_read == sizeof(uint32_t)); - rb->shared_hdr->read_pt = read_pt; - total_read += n_read; - qb_util_log(LOG_DEBUG, "read total of: %zd", total_read); print_header(rb); return rb; cleanup_fail: - free(rb->shared_hdr); -cleanup_fail2: - free(rb); + qb_rb_close(rb); return NULL; } @@ -736,10 +783,29 @@ qb_rb_chown(struct qb_ringbuffer_s * rb, uid_t owner, gid_t group) return -EINVAL; } res = chown(rb->shared_hdr->data_path, owner, group); - if (res < 0) { + if (res < 0 && errno != EPERM) { return -errno; } res = chown(rb->shared_hdr->hdr_path, owner, group); + if (res < 0 && errno != EPERM) { + return -errno; + } + return 0; +} + +int32_t +qb_rb_chmod(qb_ringbuffer_t * rb, mode_t mode) +{ + int32_t res; + + if (rb == NULL) { + return -EINVAL; + } + res = chmod(rb->shared_hdr->data_path, mode); + if (res < 0) { + return -errno; + } + res = chmod(rb->shared_hdr->hdr_path, mode); if (res < 0) { return -errno; } diff --git a/lib/ringbuffer_helper.c b/lib/ringbuffer_helper.c index 4634771..bff1b2c 100644 --- a/lib/ringbuffer_helper.c +++ b/lib/ringbuffer_helper.c @@ -34,11 +34,11 @@ my_posix_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout) sem_wait_again: if (ms_timeout > 0) { - res = sem_timedwait(&rb->shared_hdr->posix_sem, &ts_timeout); + res = rpl_sem_timedwait(&rb->shared_hdr->posix_sem, &ts_timeout); } else if (ms_timeout == 0) { - res = sem_trywait(&rb->shared_hdr->posix_sem); + res = rpl_sem_trywait(&rb->shared_hdr->posix_sem); } else { - res = sem_wait(&rb->shared_hdr->posix_sem); + res = rpl_sem_wait(&rb->shared_hdr->posix_sem); } if (res == -1) { switch (errno) { @@ -63,7 +63,7 @@ sem_wait_again: static int32_t my_posix_sem_post(qb_ringbuffer_t * rb) { - if (sem_post(&rb->shared_hdr->posix_sem) < 0) { + if (rpl_sem_post(&rb->shared_hdr->posix_sem) < 0) { return -errno; } else { return 0; @@ -74,7 +74,7 @@ static ssize_t my_posix_getvalue_fn(struct qb_ringbuffer_s *rb) { int val; - if (sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) { + if (rpl_sem_getvalue(&rb->shared_hdr->posix_sem, &val) < 0) { return -errno; } else { return val; @@ -84,7 +84,7 @@ my_posix_getvalue_fn(struct qb_ringbuffer_s *rb) static int32_t my_posix_sem_destroy(qb_ringbuffer_t * rb) { - if (sem_destroy(&rb->shared_hdr->posix_sem) == -1) { + if (rpl_sem_destroy(&rb->shared_hdr->posix_sem) == -1) { return -errno; } else { return 0; @@ -101,20 +101,19 @@ my_posix_sem_create(struct qb_ringbuffer_s *rb, uint32_t flags) } pshared = 1; } - if (sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) { + if (rpl_sem_init(&rb->shared_hdr->posix_sem, pshared, 0) == -1) { return -errno; } else { return 0; } } -#ifndef HAVE_POSIX_SHARED_SEMAPHORE static int32_t my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout) { struct sembuf sops[1]; int32_t res = 0; -#ifndef QB_FREEBSD_GE_8 +#ifdef HAVE_SEMTIMEDOP struct timespec ts_timeout; struct timespec *ts_pt; @@ -130,25 +129,25 @@ my_sysv_sem_timedwait(qb_ringbuffer_t * rb, int32_t ms_timeout) } else { ts_pt = NULL; } -#endif /* bsd */ +#endif /* HAVE_SEMTIMEDOP */ /* * wait for sem post. */ sops[0].sem_num = 0; sops[0].sem_op = -1; -#ifdef QB_FREEBSD_GE_8 - sops[0].sem_flg = IPC_NOWAIT; -#else +#ifdef HAVE_SEMTIMEDOP sops[0].sem_flg = 0; -#endif /* bsd */ +#else + sops[0].sem_flg = IPC_NOWAIT; +#endif /* HAVE_SEMTIMEDOP */ semop_again: -#ifdef QB_FREEBSD_GE_8 - if (semop(rb->sem_id, sops, 1) == -1) -#else +#ifdef HAVE_SEMTIMEDOP if (semtimedop(rb->sem_id, sops, 1, ts_pt) == -1) -#endif +#else + if (semop(rb->sem_id, sops, 1) == -1) +#endif /* HAVE_SEMTIMEDOP */ { if (errno == EINTR) { goto semop_again; @@ -249,25 +248,44 @@ my_sysv_sem_create(qb_ringbuffer_t * rb, uint32_t flags) return res; } -#endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */ int32_t qb_rb_sem_create(struct qb_ringbuffer_s * rb, uint32_t flags) { -#ifndef HAVE_POSIX_SHARED_SEMAPHORE - if (rb->flags & QB_RB_FLAG_SHARED_PROCESS) { - rb->sem_timedwait_fn = my_sysv_sem_timedwait; - rb->sem_post_fn = my_sysv_sem_post; - rb->sem_getvalue_fn = my_sysv_getvalue_fn; - rb->sem_destroy_fn = my_sysv_sem_destroy; - return my_sysv_sem_create(rb, flags); - } else -#endif /* NOT HAVE_POSIX_SHARED_SEMAPHORE */ - { + int32_t rc; + int32_t use_posix = QB_TRUE; + + if ((flags & QB_RB_FLAG_SHARED_PROCESS) && + !(flags & QB_RB_FLAG_NO_SEMAPHORE)) { +#if defined(HAVE_POSIX_PSHARED_SEMAPHORE) || \ + defined(HAVE_RPL_PSHARED_SEMAPHORE) + use_posix = QB_TRUE; +#else + #ifdef HAVE_SYSV_PSHARED_SEMAPHORE + use_posix = QB_FALSE; + #else + return -ENOTSUP; + #endif /* HAVE_SYSV_PSHARED_SEMAPHORE */ +#endif /* HAVE_POSIX_PSHARED_SEMAPHORE */ + } + if (flags & QB_RB_FLAG_NO_SEMAPHORE) { + rc = 0; + rb->sem_timedwait_fn = NULL; + rb->sem_post_fn = NULL; + rb->sem_getvalue_fn = NULL; + rb->sem_destroy_fn = NULL; + } else if (use_posix) { + rc = my_posix_sem_create(rb, flags); rb->sem_timedwait_fn = my_posix_sem_timedwait; rb->sem_post_fn = my_posix_sem_post; rb->sem_getvalue_fn = my_posix_getvalue_fn; rb->sem_destroy_fn = my_posix_sem_destroy; - return my_posix_sem_create(rb, flags); + } else { + rc = my_sysv_sem_create(rb, flags); + rb->sem_timedwait_fn = my_sysv_sem_timedwait; + rb->sem_post_fn = my_sysv_sem_post; + rb->sem_getvalue_fn = my_sysv_getvalue_fn; + rb->sem_destroy_fn = my_sysv_sem_destroy; } + return rc; } diff --git a/lib/ringbuffer_int.h b/lib/ringbuffer_int.h index 3a7f22d..dfdee17 100644 --- a/lib/ringbuffer_int.h +++ b/lib/ringbuffer_int.h @@ -32,9 +32,7 @@ #ifdef HAVE_SYS_IPC_H #include #endif -#include -#include - +#include "rpl_sem.h" #include "util_int.h" #include #include @@ -55,9 +53,9 @@ struct qb_ringbuffer_shared_s { char hdr_path[PATH_MAX]; char data_path[PATH_MAX]; int32_t ref_count; - sem_t posix_sem; + rpl_sem_t posix_sem; char user_data[1]; -}; +} __attribute__ ((aligned(8))); struct qb_ringbuffer_s { uint32_t flags; @@ -74,13 +72,13 @@ struct qb_ringbuffer_s { void qb_rb_force_close(qb_ringbuffer_t * rb); -#if defined(_SEM_SEMUN_UNDEFINED) +#ifndef HAVE_SEMUN union semun { int32_t val; struct semid_ds *buf; unsigned short int *array; struct seminfo *__buf; }; -#endif /* _SEM_SEMUN_UNDEFINED */ +#endif /* HAVE_SEMUN */ #endif /* _RINGBUFFER_H_ */ diff --git a/lib/rpl_sem.c b/lib/rpl_sem.c new file mode 100644 index 0000000..37cc830 --- /dev/null +++ b/lib/rpl_sem.c @@ -0,0 +1,190 @@ +/* + * Copyright (C) 2007 Pingtel Corp., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + * Modified by: Angus Salkeld + * Copyright (C) 2012 Red Hat, Inc. + * To conform to posix API and support process shared semaphores. + * + * The bsd posix semaphore implementation does not have support for timing + * out while waiting for a synchronization object. This uses the + * pthread_cond_timedwait function and a mutex to build all the other + * synchronization objecs with timeout capabilities. + */ + +#include "os_base.h" +#include +#include "rpl_sem.h" + +int +rpl_sem_init(rpl_sem_t * sem, int pshared, unsigned int count) +{ + int rc; + pthread_mutexattr_t mattr; + pthread_condattr_t cattr; + +#ifndef HAVE_RPL_PSHARED_SEMAPHORE + if (pshared) { + errno = ENOSYS; + return -1; + } +#endif /* HAVE_RPL_PSHARED_SEMAPHORE */ + sem->count = count; + + (void)pthread_mutexattr_init(&mattr); + (void)pthread_condattr_init(&cattr); +#ifdef HAVE_RPL_PSHARED_SEMAPHORE + if (pshared) { + rc = pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); + if (rc != 0) { + goto cleanup; + } + rc = pthread_condattr_setpshared(&cattr, PTHREAD_PROCESS_SHARED); + if (rc != 0) { + goto cleanup; + } + } +#endif /* HAVE_RPL_PSHARED_SEMAPHORE */ + rc = pthread_mutex_init(&sem->mutex, &mattr); + if (rc != 0) { + goto cleanup; + } + rc = pthread_cond_init(&sem->cond, &cattr); + + if (rc != 0) { + goto cleanup_mutex; + } + return 0; + +cleanup_mutex: + pthread_mutex_destroy(&sem->mutex); + +cleanup: + pthread_mutexattr_destroy(&mattr); + pthread_condattr_destroy(&cattr); + return rc; +} + +int +rpl_sem_wait(rpl_sem_t * sem) +{ + int retval = pthread_mutex_lock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + + /* wait for sem->count to be not zero, or error + */ + while (retval == 0 && !sem->count) { + retval = pthread_cond_wait(&sem->cond, &sem->mutex); + } + switch (retval) { + case 0: + /* retval is 0 and sem->count is not, the sem is ours + */ + sem->count--; + break; + + default: + errno = retval; + retval = -1; + } + + pthread_mutex_unlock(&sem->mutex); + return retval; +} + +int +rpl_sem_timedwait(rpl_sem_t * sem, const struct timespec *timeout) +{ + int retval = pthread_mutex_lock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + + /* wait for sem->count to be not zero, or error + */ + while (0 == retval && !sem->count) { + retval = pthread_cond_timedwait(&sem->cond, &sem->mutex, timeout); + } + + switch (retval) { + case 0: + /* retval is 0 and sem->count is not, the sem is ours + */ + sem->count--; + break; + + case ETIMEDOUT: + /* timedout waiting for count to be not zero + */ + errno = EAGAIN; + retval = -1; + break; + + default: + errno = retval; + retval = -1; + } + pthread_mutex_unlock(&sem->mutex); + return retval; +} + +int +rpl_sem_trywait(rpl_sem_t * sem) +{ + int retval = pthread_mutex_lock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + if (sem->count) { + sem->count--; + pthread_mutex_unlock(&sem->mutex); + return 0; + } + errno = EAGAIN; + pthread_mutex_unlock(&sem->mutex); + return -1; +} + +int +rpl_sem_post(rpl_sem_t * sem) +{ + int retval = pthread_mutex_lock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + sem->count++; + retval = pthread_cond_broadcast(&sem->cond); + pthread_mutex_unlock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + return 0; +} + +int +rpl_sem_getvalue(rpl_sem_t * sem, int *sval) +{ + int retval = pthread_mutex_lock(&sem->mutex); + if (retval != 0) { + errno = retval; + return -1; + } + *sval = sem->count; + pthread_mutex_unlock(&sem->mutex); + return 0; +} + +int +rpl_sem_destroy(rpl_sem_t * sem) +{ + return pthread_mutex_destroy(&sem->mutex) | + pthread_cond_destroy(&sem->cond); +} diff --git a/lib/rpl_sem.h b/lib/rpl_sem.h new file mode 100644 index 0000000..23724e4 --- /dev/null +++ b/lib/rpl_sem.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2007 Pingtel Corp., certain elements licensed under a Contributor Agreement. + * Contributors retain copyright to elements licensed under a Contributor Agreement. + * Licensed to the User under the LGPL license. + * + * Modified by: Angus Salkeld + * Copyright (C) 2012 Red Hat, Inc. + * To conform to official implementation and support process shared semaphores. + * + * The bsd posix semaphore implementation does not have support for timing + * out while waiting for a synchronization object. This uses the + * pthread_cond_timedwait function and a mutex to build all the other + * synchronization objecs with timeout capabilities. + */ + +#ifndef _RPL_SEM_H +#define _RPL_SEM_H + +#include "os_base.h" +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef HAVE_SEM_TIMEDWAIT +#define rpl_sem_t sem_t +#define rpl_sem_init sem_init +#define rpl_sem_wait sem_wait +#define rpl_sem_timedwait sem_timedwait +#define rpl_sem_post sem_post +#define rpl_sem_getvalue sem_getvalue +#define rpl_sem_destroy sem_destroy +#define rpl_sem_trywait sem_trywait +#else + +typedef struct rpl_sem { + unsigned int count; + pthread_mutex_t mutex; + pthread_cond_t cond; +} rpl_sem_t; + +int rpl_sem_init(rpl_sem_t * sem, int pshared, unsigned int count); + +int rpl_sem_wait(rpl_sem_t *sem); + +int rpl_sem_timedwait(rpl_sem_t *sem,const struct timespec *timeout); + +int rpl_sem_trywait(rpl_sem_t *sem); + +int rpl_sem_post(rpl_sem_t *sem); + +int rpl_sem_getvalue(rpl_sem_t * sem, int *sval); + +int rpl_sem_destroy(rpl_sem_t *sem); + +#endif /* HAVE_SEM_TIMEDWAIT */ + +#ifdef __cplusplus +} +#endif + +#endif /* _RPL_SEM_H */ diff --git a/lib/unix.c b/lib/unix.c index 2bbe25d..70ea461 100644 --- a/lib/unix.c +++ b/lib/unix.c @@ -32,17 +32,25 @@ #include #include +#if defined(MAP_ANON) && ! defined(MAP_ANONYMOUS) +/* + * BSD derivatives usually have MAP_ANON, not MAP_ANONYMOUS + **/ +#define MAP_ANONYMOUS MAP_ANON +#endif + + char * qb_strerror_r(int errnum, char *buf, size_t buflen) { -#ifdef QB_LINUX +#ifdef STRERROR_R_CHAR_P return strerror_r(errnum, buf, buflen); #else if (strerror_r(errnum, buf, buflen) != 0) { buf[0] = '\0'; } return buf; -#endif /* QB_LINUX */ +#endif /* STRERROR_R_CHAR_P */ } static int32_t @@ -72,7 +80,12 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes, if (is_absolute) { (void)strlcpy(path, file, PATH_MAX); } else { +#if defined(QB_LINUX) || defined(QB_CYGWIN) snprintf(path, PATH_MAX, "/dev/shm/%s", file); +#else + snprintf(path, PATH_MAX, LOCALSTATEDIR "/run/%s", file); + is_absolute = path; +#endif } fd = open_mmap_file(path, file_flags); if (fd < 0 && !is_absolute) { @@ -85,6 +98,10 @@ qb_sys_mmap_file_open(char *path, const char *file, size_t bytes, qb_util_perror(LOG_ERR, "couldn't open file %s", path); return res; } + } else if (fd < 0 && is_absolute) { + res = -errno; + qb_util_perror(LOG_ERR, "couldn't open file %s", path); + return res; } if (ftruncate(fd, bytes) == -1) { @@ -165,7 +182,7 @@ qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes) res = -errno; goto cleanup_fail; } -#ifdef QB_BSD +#if defined(QB_BSD) && defined(MADV_NOSYNC) madvise(addr_orig, bytes, MADV_NOSYNC); #endif addr_next = ((char *)addr_orig) + bytes; @@ -176,7 +193,7 @@ qb_sys_circular_mmap(int32_t fd, void **buf, size_t bytes) res = -errno; goto cleanup_fail; } -#ifdef QB_BSD +#if defined(QB_BSD) && defined(MADV_NOSYNC) madvise(((char *)addr_orig) + bytes, bytes, MADV_NOSYNC); #endif diff --git a/lib/util.c b/lib/util.c index a044368..ef5ba25 100644 --- a/lib/util.c +++ b/lib/util.c @@ -197,7 +197,7 @@ qb_util_nano_current_get(void) uint64_t qb_util_nano_monotonic_hz(void) { - return HZ; + return sysconf(_SC_CLK_TCK); } void diff --git a/libqb.spec.in b/libqb.spec.in index f734656..bd11b16 100644 --- a/libqb.spec.in +++ b/libqb.spec.in @@ -34,7 +34,7 @@ make check rm -rf $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT find $RPM_BUILD_ROOT -name '*.la' -exec rm -f {} ';' -rm -rf $RPM_BUILD_ROOT/%{_docdir}/* +rm -rf $RPM_BUILD_ROOT/%{_datadir}/doc/libqb %clean rm -rf $RPM_BUILD_ROOT @@ -46,6 +46,7 @@ rm -rf $RPM_BUILD_ROOT %files %defattr(-,root,root,-) %doc COPYING +%{_sbindir}/qb-blackbox %{_libdir}/libqb.so.* %package devel @@ -64,6 +65,7 @@ developing applications that use %{name}. %{_libdir}/libqb.so %{_libdir}/pkgconfig/libqb.pc %{_mandir}/man3/qb*3* +%{_mandir}/man8/qb-blackbox.8.gz %changelog * @date@ Autotools generated version - @version@-1-@numcomm@.@alphatag@.@dirty@ diff --git a/tests/Makefile.am b/tests/Makefile.am index c77f7bc..7b8d327 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -17,7 +17,7 @@ # You should have received a copy of the GNU Lesser General Public License # along with libqb. If not, see . # -MAINTAINERCLEANFILES = Makefiles.in +MAINTAINERCLEANFILES = Makefile.in EXTRA_DIST = CLEANFILES = AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include @@ -31,23 +31,23 @@ noinst_PROGRAMS = bmc bmcpt bms rbwriter rbreader loop bench-log \ bmc_SOURCES = bmc.c $(top_builddir)/include/qb/qbipcc.h -bmc_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bmc_LDADD = $(top_builddir)/lib/libqb.la bmcpt_SOURCES = bmcpt.c $(top_builddir)/include/qb/qbipcc.h -bmcpt_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bmcpt_LDADD = $(top_builddir)/lib/libqb.la bms_SOURCES = bms.c $(top_builddir)/include/qb/qbipcs.h bms_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include $(GLIB_CFLAGS) -bms_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS) +bms_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS) rbwriter_SOURCES = rbwriter.c $(top_builddir)/include/qb/qbrb.h -rbwriter_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +rbwriter_LDADD = $(top_builddir)/lib/libqb.la rbreader_SOURCES = rbreader.c $(top_builddir)/include/qb/qbrb.h -rbreader_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +rbreader_LDADD = $(top_builddir)/lib/libqb.la loop_SOURCES = loop.c $(top_builddir)/include/qb/qbloop.h -loop_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +loop_LDADD = $(top_builddir)/lib/libqb.la public_headers = $(wildcard $(top_srcdir)/include/qb/qb*.h) auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers)) @@ -84,7 +84,7 @@ endif bench_log_SOURCES = bench-log.c $(top_builddir)/include/qb/qblog.h bench_log_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bench_log_LDADD = $(top_builddir)/lib/libqb.la if HAVE_CHECK EXTRA_DIST += resources.test @@ -103,31 +103,31 @@ endif array_test_SOURCES = check_array.c $(top_builddir)/include/qb/qbarray.h array_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -array_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +array_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ map_test_SOURCES = check_map.c $(top_builddir)/include/qb/qbmap.h map_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -map_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +map_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ rb_test_SOURCES = check_rb.c $(top_builddir)/include/qb/qbrb.h rb_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -rb_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +rb_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ loop_test_SOURCES = check_loop.c $(top_builddir)/include/qb/qbloop.h loop_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -loop_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -ipc_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -log_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -util_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +util_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ endif diff --git a/tests/Makefile.in b/tests/Makefile.in index 96ac719..e48bd09 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -87,10 +87,8 @@ am__array_test_SOURCES_DIST = check_array.c \ @HAVE_CHECK_TRUE@am_array_test_OBJECTS = \ @HAVE_CHECK_TRUE@ array_test-check_array.$(OBJEXT) array_test_OBJECTS = $(am_array_test_OBJECTS) -am__DEPENDENCIES_1 = @HAVE_CHECK_TRUE@array_test_DEPENDENCIES = \ -@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -148,26 +146,23 @@ am_bench_log_OBJECTS = bench_log-bench-log.$(OBJEXT) @HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@nodist_bench_log_OBJECTS = bench_log-auto_write_logs.$(OBJEXT) bench_log_OBJECTS = $(am_bench_log_OBJECTS) \ $(nodist_bench_log_OBJECTS) -bench_log_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +bench_log_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_bmc_OBJECTS = bmc.$(OBJEXT) bmc_OBJECTS = $(am_bmc_OBJECTS) -bmc_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la +bmc_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_bmcpt_OBJECTS = bmcpt.$(OBJEXT) bmcpt_OBJECTS = $(am_bmcpt_OBJECTS) -bmcpt_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +bmcpt_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_bms_OBJECTS = bms-bms.$(OBJEXT) bms_OBJECTS = $(am_bms_OBJECTS) -bms_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la \ - $(am__DEPENDENCIES_1) +am__DEPENDENCIES_1 = +bms_DEPENDENCIES = $(top_builddir)/lib/libqb.la $(am__DEPENDENCIES_1) am__ipc_test_SOURCES_DIST = check_ipc.c \ $(top_builddir)/include/qb/qbipcc.h \ $(top_builddir)/include/qb/qbipcs.h @HAVE_CHECK_TRUE@am_ipc_test_OBJECTS = ipc_test-check_ipc.$(OBJEXT) ipc_test_OBJECTS = $(am_ipc_test_OBJECTS) -@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@ipc_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la ipc_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ipc_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -175,22 +170,20 @@ am__log_test_SOURCES_DIST = check_log.c \ $(top_builddir)/include/qb/qblog.h @HAVE_CHECK_TRUE@am_log_test_OBJECTS = log_test-check_log.$(OBJEXT) log_test_OBJECTS = $(am_log_test_OBJECTS) -@HAVE_CHECK_TRUE@log_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@log_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la log_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(log_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_loop_OBJECTS = loop.$(OBJEXT) loop_OBJECTS = $(am_loop_OBJECTS) -loop_DEPENDENCIES = $(am__DEPENDENCIES_1) $(top_builddir)/lib/libqb.la +loop_DEPENDENCIES = $(top_builddir)/lib/libqb.la am__loop_test_SOURCES_DIST = check_loop.c \ $(top_builddir)/include/qb/qbloop.h @HAVE_CHECK_TRUE@am_loop_test_OBJECTS = \ @HAVE_CHECK_TRUE@ loop_test-check_loop.$(OBJEXT) loop_test_OBJECTS = $(am_loop_test_OBJECTS) @HAVE_CHECK_TRUE@loop_test_DEPENDENCIES = \ -@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la loop_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(loop_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -198,8 +191,7 @@ am__map_test_SOURCES_DIST = check_map.c \ $(top_builddir)/include/qb/qbmap.h @HAVE_CHECK_TRUE@am_map_test_OBJECTS = map_test-check_map.$(OBJEXT) map_test_OBJECTS = $(am_map_test_OBJECTS) -@HAVE_CHECK_TRUE@map_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@map_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la map_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(map_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ @@ -207,32 +199,28 @@ am__rb_test_SOURCES_DIST = check_rb.c \ $(top_builddir)/include/qb/qbrb.h @HAVE_CHECK_TRUE@am_rb_test_OBJECTS = rb_test-check_rb.$(OBJEXT) rb_test_OBJECTS = $(am_rb_test_OBJECTS) -@HAVE_CHECK_TRUE@rb_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@rb_test_DEPENDENCIES = $(top_builddir)/lib/libqb.la rb_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(rb_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ am_rbreader_OBJECTS = rbreader.$(OBJEXT) rbreader_OBJECTS = $(am_rbreader_OBJECTS) -rbreader_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +rbreader_DEPENDENCIES = $(top_builddir)/lib/libqb.la am_rbwriter_OBJECTS = rbwriter.$(OBJEXT) rbwriter_OBJECTS = $(am_rbwriter_OBJECTS) -rbwriter_DEPENDENCIES = $(am__DEPENDENCIES_1) \ - $(top_builddir)/lib/libqb.la +rbwriter_DEPENDENCIES = $(top_builddir)/lib/libqb.la am__util_test_SOURCES_DIST = check_util.c \ $(top_builddir)/include/qb/qbutil.h @HAVE_CHECK_TRUE@am_util_test_OBJECTS = \ @HAVE_CHECK_TRUE@ util_test-check_util.$(OBJEXT) util_test_OBJECTS = $(am_util_test_OBJECTS) @HAVE_CHECK_TRUE@util_test_DEPENDENCIES = \ -@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la \ -@HAVE_CHECK_TRUE@ $(am__DEPENDENCIES_1) +@HAVE_CHECK_TRUE@ $(top_builddir)/lib/libqb.la util_test_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(util_test_CFLAGS) \ $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb -depcomp = $(SHELL) $(top_srcdir)/depcomp +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp am__depfiles_maybe = depfiles am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ @@ -286,132 +274,8 @@ DIST_SOURCES = $(am__array_test_SOURCES_DIST) \ $(rbwriter_SOURCES) $(am__util_test_SOURCES_DIST) ETAGS = etags CTAGS = ctags -# If stdout is a non-dumb tty, use colors. If test -t is not supported, -# then this fails; a conservative approach. Of course do not redirect -# stdout here, just stderr. am__tty_colors = \ -red=; grn=; lgn=; blu=; std=; \ -test "X$(AM_COLOR_TESTS)" != Xno \ -&& test "X$$TERM" != Xdumb \ -&& { test "X$(AM_COLOR_TESTS)" = Xalways || test -t 1 2>/dev/null; } \ -&& { \ - red=''; \ - grn=''; \ - lgn=''; \ - blu=''; \ - std=''; \ -} -am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; -am__vpath_adj = case $$p in \ - $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ - *) f=$$p;; \ - esac; -am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; -am__install_max = 40 -am__nobase_strip_setup = \ - srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` -am__nobase_strip = \ - for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" -am__nobase_list = $(am__nobase_strip_setup); \ - for p in $$list; do echo "$$p $$p"; done | \ - sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ - $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ - if (++n[$$2] == $(am__install_max)) \ - { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ - END { for (dir in files) print dir, files[dir] }' -am__base_list = \ - sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ - sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' -am__uninstall_files_from_dir = { \ - test -z "$$files" \ - || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ - || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ - $(am__cd) "$$dir" && rm -f $$files; }; \ - } -# Restructured Text title and section. -am__rst_title = sed 's/.*/ & /;h;s/./=/g;p;x;p;g;p;s/.*//' -am__rst_section = sed 'p;s/./=/g;p;g' -# Put stdin (possibly several lines separated by ". ") in a box. -# Prefix each line by 'col' and terminate each with 'std', for coloring. -# Multi line coloring is problematic with "less -R", so we really need -# to color each line individually. -am__text_box = $(AWK) '{ \ - n = split($$0, lines, "\\. "); max = 0; \ - for (i = 1; i <= n; ++i) \ - if (max < length(lines[i])) \ - max = length(lines[i]); \ - for (i = 0; i < max; ++i) \ - line = line "="; \ - print col line std; \ - for (i = 1; i <= n; ++i) \ - if (lines[i]) \ - print col lines[i] std; \ - print col line std; \ -}' -# Solaris 10 'make', and several other traditional 'make' implementations, -# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it -# by disabling -e (using the XSI extension "set +e") if it's set. -am__sh_e_setup = case $$- in *e*) set +e;; esac -# To be inserted before the command running the test. Creates the -# directory for the log if needed. Stores in $dir the directory -# containing $f, in $tst the test, in $log the log, and passes -# TESTS_ENVIRONMENT. Save and restore TERM around use of -# TESTS_ENVIRONMENT, in case that unsets it. -am__check_pre = \ -$(am__sh_e_setup); \ -$(am__vpath_adj_setup) $(am__vpath_adj) \ -srcdir=$(srcdir); export srcdir; \ -rm -f $@-t; \ -am__trap='rm -f '\''$(abs_builddir)/$@-t'\''; (exit $$st); exit $$st'; \ -trap "st=129; $$am__trap" 1; trap "st=130; $$am__trap" 2; \ -trap "st=141; $$am__trap" 13; trap "st=143; $$am__trap" 15; \ -am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`; \ -test "x$$am__odir" = x. || $(MKDIR_P) "$$am__odir" || exit $$?; \ -if test -f "./$$f"; then dir=./; \ -elif test -f "$$f"; then dir=; \ -else dir="$(srcdir)/"; fi; \ -tst=$$dir$$f; log='$@'; __SAVED_TERM=$$TERM; \ -$(TESTS_ENVIRONMENT) -# To be appended to the command running the test. Handle the stdout -# and stderr redirection, and catch the exit status. -am__check_post = \ ->$@-t 2>&1; \ -estatus=$$?; \ -if test -n '$(DISABLE_HARD_ERRORS)' \ - && test $$estatus -eq 99; then \ - estatus=1; \ -fi; \ -TERM=$$__SAVED_TERM; export TERM; \ -$(am__tty_colors); \ -xfailed=PASS; \ -case " $(XFAIL_TESTS) " in \ - *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ - xfailed=XFAIL;; \ -esac; \ -case $$estatus.$$xfailed in \ - 0.XFAIL) col=$$red; res=XPASS;; \ - 0.*) col=$$grn; res=PASS ;; \ - 77.*) col=$$blu; res=SKIP ;; \ - 99.*) col=$$red; res=FAIL ;; \ - *.XFAIL) col=$$lgn; res=XFAIL;; \ - *.*) col=$$red; res=FAIL ;; \ -esac; \ -echo "$${col}$$res$${std}: $$f"; \ -echo "$$res: $$f (exit: $$estatus)" | \ - $(am__rst_section) >$@; \ -cat $@-t >>$@; \ -rm -f $@-t -RECHECK_LOGS = $(TEST_LOGS) -AM_RECURSIVE_TARGETS = check recheck check-html recheck-html -TEST_SUITE_HTML = $(TEST_SUITE_LOG:.log=.html) -TEST_SUITE_LOG = test-suite.log -TEST_EXTENSIONS = @EXEEXT@ .test -am__test_logs1 = $(TESTS:=.log) -am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) -TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ - $(TEST_LOG_FLAGS) -TEST_LOGS_TMP = $(TEST_LOGS:.log=.log-t) +red=; grn=; lgn=; blu=; std= DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ @@ -459,7 +323,6 @@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ -LIB_RT = @LIB_RT@ LINT_FLAGS = @LINT_FLAGS@ LIPO = @LIPO@ LN_S = @LN_S@ @@ -566,55 +429,55 @@ top_srcdir = @top_srcdir@ # You should have received a copy of the GNU Lesser General Public License # along with libqb. If not, see . # -MAINTAINERCLEANFILES = Makefiles.in $(auto_c_files) $(am__append_3) +MAINTAINERCLEANFILES = Makefile.in $(auto_c_files) $(am__append_3) EXTRA_DIST = $(am__append_1) $(am__append_4) CLEANFILES = $(auto_c_files) $(am__append_2) AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include bmc_SOURCES = bmc.c $(top_builddir)/include/qb/qbipcc.h -bmc_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bmc_LDADD = $(top_builddir)/lib/libqb.la bmcpt_SOURCES = bmcpt.c $(top_builddir)/include/qb/qbipcc.h -bmcpt_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bmcpt_LDADD = $(top_builddir)/lib/libqb.la bms_SOURCES = bms.c $(top_builddir)/include/qb/qbipcs.h bms_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include $(GLIB_CFLAGS) -bms_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la $(GLIB_LIBS) +bms_LDADD = $(top_builddir)/lib/libqb.la $(GLIB_LIBS) rbwriter_SOURCES = rbwriter.c $(top_builddir)/include/qb/qbrb.h -rbwriter_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +rbwriter_LDADD = $(top_builddir)/lib/libqb.la rbreader_SOURCES = rbreader.c $(top_builddir)/include/qb/qbrb.h -rbreader_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +rbreader_LDADD = $(top_builddir)/lib/libqb.la loop_SOURCES = loop.c $(top_builddir)/include/qb/qbloop.h -loop_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +loop_LDADD = $(top_builddir)/lib/libqb.la public_headers = $(wildcard $(top_srcdir)/include/qb/qb*.h) auto_c_files = $(patsubst %.h,auto_check_header_%.c,$(public_headers)) @HAVE_DICT_WORDS_TRUE@@HAVE_SLOW_TESTS_TRUE@nodist_bench_log_SOURCES = auto_write_logs.c bench_log_SOURCES = bench-log.c $(top_builddir)/include/qb/qblog.h bench_log_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include -bench_log_LDADD = $(LIB_RT) $(top_builddir)/lib/libqb.la +bench_log_LDADD = $(top_builddir)/lib/libqb.la @HAVE_CHECK_TRUE@check_SCRIPTS = resources.test @HAVE_CHECK_TRUE@array_test_SOURCES = check_array.c $(top_builddir)/include/qb/qbarray.h @HAVE_CHECK_TRUE@array_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@array_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@array_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@map_test_SOURCES = check_map.c $(top_builddir)/include/qb/qbmap.h @HAVE_CHECK_TRUE@map_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@map_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@map_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@rb_test_SOURCES = check_rb.c $(top_builddir)/include/qb/qbrb.h @HAVE_CHECK_TRUE@rb_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@rb_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@rb_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@loop_test_SOURCES = check_loop.c $(top_builddir)/include/qb/qbloop.h @HAVE_CHECK_TRUE@loop_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@loop_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@loop_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@ipc_test_SOURCES = check_ipc.c $(top_builddir)/include/qb/qbipcc.h $(top_builddir)/include/qb/qbipcs.h @HAVE_CHECK_TRUE@ipc_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@ipc_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@log_test_SOURCES = check_log.c $(top_builddir)/include/qb/qblog.h @HAVE_CHECK_TRUE@log_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@log_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@log_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ @HAVE_CHECK_TRUE@util_test_SOURCES = check_util.c $(top_builddir)/include/qb/qbutil.h @HAVE_CHECK_TRUE@util_test_CFLAGS = @CHECK_CFLAGS@ -I$(top_srcdir)/include -@HAVE_CHECK_TRUE@util_test_LDADD = $(top_builddir)/lib/libqb.la $(LIB_RT) @CHECK_LIBS@ +@HAVE_CHECK_TRUE@util_test_LDADD = $(top_builddir)/lib/libqb.la @CHECK_LIBS@ all: all-am .SUFFIXES: -.SUFFIXES: .c .html .lo .log .o .obj .test .test$(EXEEXT) +.SUFFIXES: .c .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -1000,137 +863,98 @@ GTAGS: distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -$(TEST_SUITE_LOG): $(TEST_LOGS) - @$(am__sh_e_setup); \ - list='$(TEST_LOGS)'; \ - results=`for f in $$list; do \ - test -r $$f && read line < $$f && echo "$$line" \ - || echo FAIL; \ - done`; \ - all=`echo "$$results" | sed '/^$$/d' | wc -l | sed -e 's/^[ ]*//'`; \ - fail=`echo "$$results" | grep -c '^FAIL'`; \ - pass=`echo "$$results" | grep -c '^PASS'`; \ - skip=`echo "$$results" | grep -c '^SKIP'`; \ - xfail=`echo "$$results" | grep -c '^XFAIL'`; \ - xpass=`echo "$$results" | grep -c '^XPASS'`; \ - failures=`expr $$fail + $$xpass`; \ - all=`expr $$all - $$skip`; \ - if test "$$all" -eq 1; then tests=test; All=; \ - else tests=tests; All="All "; fi; \ - case fail=$$fail:xpass=$$xpass:xfail=$$xfail in \ - fail=0:xpass=0:xfail=0) \ - msg="$$All$$all $$tests passed. "; \ - exit=true;; \ - fail=0:xpass=0:xfail=*) \ - msg="$$All$$all $$tests behaved as expected"; \ - if test "$$xfail" -eq 1; then xfailures=failure; \ - else xfailures=failures; fi; \ - msg="$$msg ($$xfail expected $$xfailures). "; \ - exit=true;; \ - fail=*:xpass=0:xfail=*) \ - msg="$$fail of $$all $$tests failed. "; \ - exit=false;; \ - fail=*:xpass=*:xfail=*) \ - msg="$$failures of $$all $$tests did not behave as expected"; \ - if test "$$xpass" -eq 1; then xpasses=pass; \ - else xpasses=passes; fi; \ - msg="$$msg ($$xpass unexpected $$xpasses). "; \ - exit=false;; \ - *) \ - echo >&2 "incorrect case"; exit 4;; \ - esac; \ - if test "$$skip" -ne 0; then \ - if test "$$skip" -eq 1; then \ - msg="$$msg($$skip test was not run). "; \ - else \ - msg="$$msg($$skip tests were not run). "; \ - fi; \ - fi; \ - { \ - echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ - $(am__rst_title); \ - echo "$$msg"; \ - echo; \ - echo ".. contents:: :depth: 2"; \ - echo; \ - for f in $$list; do \ - test -r $$f && read line < $$f || line=; \ - case $$line in \ - PASS:*|XFAIL:*);; \ - *) echo; cat $$f;; \ - esac; \ - done; \ - } >$(TEST_SUITE_LOG).tmp; \ - mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ - if test "$$failures" -ne 0; then \ - msg="$${msg}See $(subdir)/$(TEST_SUITE_LOG). "; \ - if test -n "$(PACKAGE_BUGREPORT)"; then \ - msg="$${msg}Please report to $(PACKAGE_BUGREPORT). "; \ - fi; \ - fi; \ - test x"$$VERBOSE" = x || $$exit || cat $(TEST_SUITE_LOG); \ - $(am__tty_colors); \ - if $$exit; then \ - col="$$grn"; \ - else \ - col="$$red"; \ - fi; \ - echo "$$msg" | $(am__text_box) "col=$$col" "std=$$std"; \ - $$exit || exit 1 - -check-TESTS recheck: - @if test $@ != recheck; then \ - list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list; \ - fi - @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) - @list='' list2='$(TEST_LOGS)'; for f in $$list2; do \ - test .log = $$f && continue; \ - if test $@ = recheck; then \ - test -f $$f || continue; \ - if test -r $$f && read line < $$f; then \ - case $$line in FAIL*|XPASS*) : ;; *) continue;; esac; \ +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + $(am__tty_colors); \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + col=$$red; res=XPASS; \ + ;; \ + *) \ + col=$$grn; res=PASS; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + col=$$lgn; res=XFAIL; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + col=$$red; res=FAIL; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + col=$$blu; res=SKIP; \ + fi; \ + echo "$${col}$$res$${std}: $$tst"; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ - if test -z "$$list"; then list=$$f; else list="$$list $$f"; fi; \ - done; \ - if test $@ = recheck && test -n "$$list"; then \ - echo "am--clean: ; rm -f $$list" \ - | $(MAKE) $(AM_MAKEFLAGS) -f - am--clean || exit 1; \ - fi; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$list" -recheck: $(check_PROGRAMS) $(check_SCRIPTS) - -am--mostlyclean-test-html: - list='$(TEST_LOGS:.log=.html)'; test -z "$$list" || rm -f $$list - rm -f $(TEST_SUITE_HTML) - -.log.html: - @list='$(RST2HTML) $$RST2HTML rst2html rst2html.py'; \ - for r2h in $$list; do \ - if ($$r2h --version) >/dev/null 2>&1; then \ - R2H=$$r2h; \ - fi; \ - done; \ - if test -z "$$R2H"; then \ - echo >&2 "cannot find rst2html, cannot create $@"; \ - exit 2; \ - fi; \ - $$R2H $< >$@.tmp - @mv $@.tmp $@ - -# Be sure to run check first, and then to convert the result. -# Beware of concurrent executions. Run "check" not "check-TESTS", as -# check-SCRIPTS and other dependencies are rebuilt by the former only. -# And expect check to fail. -check-html recheck-html: - @target=`echo $@ | sed 's/-html$$//'`; \ - rv=0; $(MAKE) $(AM_MAKEFLAGS) $$target || rv=$$?; \ - $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_HTML) TEST_LOGS= || exit 4; \ - exit $$rv -.test.log: - @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) -@am__EXEEXT_TRUE@.test$(EXEEXT).log: -@am__EXEEXT_TRUE@ @p='$<'; $(am__check_pre) $(TEST_LOG_COMPILE) "$$tst" $(am__check_post) + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + if test "$$failed" -eq 0; then \ + col="$$grn"; \ + else \ + col="$$red"; \ + fi; \ + echo "$${col}$$dashes$${std}"; \ + echo "$${col}$$banner$${std}"; \ + test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \ + test -z "$$report" || echo "$${col}$$report$${std}"; \ + echo "$${col}$$dashes$${std}"; \ + test "$$failed" -eq 0; \ + else :; fi distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -1188,9 +1012,6 @@ install-strip: "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: - -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) - -test -z "$(TEST_LOGS_TMP)" || rm -f $(TEST_LOGS_TMP) - -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) @@ -1258,8 +1079,8 @@ maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am -mostlyclean-am: am--mostlyclean-test-html mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf: pdf-am @@ -1271,22 +1092,21 @@ ps-am: uninstall-am: -.MAKE: check-am check-html install-am install-strip recheck-html +.MAKE: check-am install-am install-strip -.PHONY: CTAGS GTAGS all all-am am--mostlyclean-test-html check \ - check-TESTS check-am check-html clean clean-checkPROGRAMS \ - clean-generic clean-libtool clean-noinstPROGRAMS ctags \ - distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags distdir dvi dvi-am html \ - html-am info info-am install install-am install-data \ - install-data-am install-dvi install-dvi-am install-exec \ - install-exec-am install-html install-html-am install-info \ - install-info-am install-man install-pdf install-pdf-am \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs maintainer-clean \ +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-checkPROGRAMS clean-generic clean-libtool \ + clean-noinstPROGRAMS ctags distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - recheck recheck-html tags uninstall uninstall-am + tags uninstall uninstall-am $(builddir)/auto_check_header_%.c: $(top_srcdir)/include/qb/%.h diff --git a/tests/bmcpt.c b/tests/bmcpt.c index 5f5d1f6..2f2d276 100644 --- a/tests/bmcpt.c +++ b/tests/bmcpt.c @@ -31,6 +31,7 @@ #include #include +#include #include #define ITERATIONS 10000000 @@ -38,43 +39,31 @@ struct bm_ctx { qb_ipcc_connection_t *conn; - struct timeval tv1; - struct timeval tv2; - struct timeval tv_elapsed; + qb_util_stopwatch_t *sw; float mbs; + float secs; int32_t multi; uint32_t counter; }; -#define timersub(a, b, result) \ -do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ -} while (0) - static void bm_start(struct bm_ctx *ctx) { - gettimeofday(&ctx->tv1, NULL); + qb_util_stopwatch_start(ctx->sw); } static void bm_finish(struct bm_ctx *ctx, const char *operation, int32_t size) { - gettimeofday(&ctx->tv2, NULL); - timersub(&ctx->tv2, &ctx->tv1, &ctx->tv_elapsed); + qb_util_stopwatch_stop(ctx->sw); + ctx->secs = qb_util_stopwatch_sec_elapsed_get(ctx->sw); ctx->mbs = - ((((float)ctx->counter) * size) / - (((float)ctx->tv_elapsed.tv_sec) + - (((float)ctx->tv_elapsed.tv_usec) / 1000000.0))) / (1024.0 * - 1024.0); + ((((float)ctx->counter) * size) / ctx->secs) / (1024.0 * + 1024.0); } static void bmc_connect(struct bm_ctx *ctx) { + ctx->sw = qb_util_stopwatch_create(); ctx->conn = qb_ipcc_connect("bm1", QB_MAX(1000 * (100 + THREADS), 1024*1024)); if (ctx->conn == NULL) { @@ -86,6 +75,7 @@ static void bmc_connect(struct bm_ctx *ctx) static void bmc_disconnect(struct bm_ctx *ctx) { qb_ipcc_disconnect(ctx->conn); + qb_util_stopwatch_free(ctx->sw); } struct my_req { diff --git a/tests/bms.c b/tests/bms.c index 60e15be..d71863f 100644 --- a/tests/bms.c +++ b/tests/bms.c @@ -283,15 +283,9 @@ int32_t main(int32_t argc, char *argv[]) case 'm': ipc_type = QB_IPC_SHM; break; - case 's': - ipc_type = QB_IPC_SYSV_MQ; - break; case 'u': ipc_type = QB_IPC_SOCKET; break; - case 'p': - ipc_type = QB_IPC_POSIX_MQ; - break; case 'n': /* non-blocking */ blocking = QB_FALSE; break; diff --git a/tests/check_ipc.c b/tests/check_ipc.c index 87c5a48..c396d61 100644 --- a/tests/check_ipc.c +++ b/tests/check_ipc.c @@ -21,12 +21,8 @@ * along with libqb. If not, see . */ -#include -#include -#include -#include +#include "os_base.h" #include -#include #include #include @@ -46,8 +42,12 @@ enum my_msg_ids { IPC_MSG_RES_TX_RX, IPC_MSG_REQ_DISPATCH, IPC_MSG_RES_DISPATCH, + IPC_MSG_REQ_BULK_EVENTS, + IPC_MSG_RES_BULK_EVENTS, IPC_MSG_REQ_SERVER_FAIL, IPC_MSG_RES_SERVER_FAIL, + IPC_MSG_REQ_SERVER_DISCONNECT, + IPC_MSG_RES_SERVER_DISCONNECT, }; /* Test Cases @@ -72,6 +72,9 @@ static qb_loop_t *my_loop; static qb_ipcs_service_t* s1; static int32_t turn_on_fc = QB_FALSE; static int32_t fc_enabled = 89; +static int32_t send_event_on_created = QB_FALSE; +static int32_t disconnect_after_created = QB_FALSE; +static int32_t num_bulk_events = 10; static int32_t exit_handler(int32_t rsignal, void *data) @@ -108,12 +111,40 @@ s1_msg_process_fn(qb_ipcs_connection_t *c, response.id = IPC_MSG_RES_DISPATCH; response.error = 0; res = qb_ipcs_event_send(c, &response, - sizeof(response)); + sizeof(response)); if (res < 0) { qb_perror(LOG_INFO, "qb_ipcs_event_send"); } + } else if (req_pt->id == IPC_MSG_REQ_BULK_EVENTS) { + int32_t m; + int32_t num; + struct qb_ipcs_connection_stats_2 *stats; + + response.size = sizeof(struct qb_ipc_response_header); + response.error = 0; + + stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE); + num = stats->event_q_length; + free(stats); + + for (m = 0; m < num_bulk_events; m++) { + res = qb_ipcs_event_send(c, &response, + sizeof(response)); + ck_assert_int_eq(res, sizeof(response)); + response.id++; + } + stats = qb_ipcs_connection_stats_get_2(c, QB_FALSE); + ck_assert_int_eq(stats->event_q_length - num, num_bulk_events); + free(stats); + + response.id = IPC_MSG_RES_BULK_EVENTS; + res = qb_ipcs_response_send(c, &response, response.size); + ck_assert_int_eq(res, sizeof(response)); + } else if (req_pt->id == IPC_MSG_REQ_SERVER_FAIL) { exit(0); + } else if (req_pt->id == IPC_MSG_REQ_SERVER_DISCONNECT) { + qb_ipcs_disconnect(c); } return 0; } @@ -146,11 +177,36 @@ my_dispatch_del(int32_t fd) return qb_loop_poll_del(my_loop, fd); } +static int32_t +s1_connection_closed(qb_ipcs_connection_t *c) +{ + qb_enter(); + qb_leave(); + return 0; +} + static void s1_connection_destroyed(qb_ipcs_connection_t *c) { qb_enter(); qb_loop_stop(my_loop); + qb_leave(); +} + +static void +s1_connection_created(qb_ipcs_connection_t *c) +{ + if (send_event_on_created) { + struct qb_ipc_response_header response; + int32_t res; + + response.size = sizeof(struct qb_ipc_response_header); + response.id = IPC_MSG_RES_DISPATCH; + response.error = 0; + res = qb_ipcs_event_send(c, &response, + sizeof(response)); + ck_assert_int_eq(res, response.size); + } } static void @@ -161,10 +217,10 @@ run_ipc_server(void) struct qb_ipcs_service_handlers sh = { .connection_accept = NULL, - .connection_created = NULL, + .connection_created = s1_connection_created, .msg_process = s1_msg_process_fn, .connection_destroyed = s1_connection_destroyed, - .connection_closed = NULL, + .connection_closed = s1_connection_closed, }; struct qb_ipcs_poll_handlers ph = { @@ -226,13 +282,14 @@ struct my_req { static struct my_req request; static int32_t -send_and_check(uint32_t size, int32_t ms_timeout, int32_t expect_perfection) +send_and_check(int32_t req_id, uint32_t size, + int32_t ms_timeout, int32_t expect_perfection) { struct qb_ipc_response_header res_header; int32_t res; int32_t try_times = 0; - request.hdr.id = IPC_MSG_REQ_TX_RX; + request.hdr.id = req_id; request.hdr.size = sizeof(struct qb_ipc_request_header) + size; repeat_send: @@ -251,8 +308,16 @@ repeat_send: return res; } } - res = qb_ipcc_recv(conn, &res_header, - sizeof(struct qb_ipc_response_header), ms_timeout); + + if (req_id == IPC_MSG_REQ_DISPATCH) { + res = qb_ipcc_event_recv(conn, &res_header, + sizeof(struct qb_ipc_response_header), + ms_timeout); + } else { + res = qb_ipcc_recv(conn, &res_header, + sizeof(struct qb_ipc_response_header), + ms_timeout); + } if (res == -EINTR) { return -1; } @@ -263,7 +328,7 @@ repeat_send: } if (expect_perfection) { ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); - ck_assert_int_eq(res_header.id, IPC_MSG_RES_TX_RX); + ck_assert_int_eq(res_header.id, req_id + 1); ck_assert_int_eq(res_header.size, sizeof(struct qb_ipc_response_header)); } return res; @@ -298,7 +363,8 @@ test_ipc_txrx(void) size *= 2; if (size >= MAX_MSG_SIZE) break; - if (send_and_check(size, recv_timeout, QB_TRUE) < 0) { + if (send_and_check(IPC_MSG_REQ_TX_RX, size, + recv_timeout, QB_TRUE) < 0) { break; } } @@ -312,9 +378,12 @@ test_ipc_txrx(void) static void test_ipc_exit(void) { + struct qb_ipc_request_header req_header; + struct qb_ipc_response_header res_header; + struct iovec iov[1]; + int32_t res; int32_t c = 0; int32_t j = 0; - int32_t rc = 0; pid_t pid; pid = run_function_in_new_process(run_ipc_server); @@ -332,9 +401,16 @@ test_ipc_exit(void) } while (conn == NULL && c < 5); fail_if(conn == NULL); - /* confirm we can send one message */ - rc = send_and_check(100, recv_timeout, QB_TRUE); - _ck_assert_int(rc, >=, 0); + req_header.id = IPC_MSG_REQ_TX_RX; + req_header.size = sizeof(struct qb_ipc_request_header); + + iov[0].iov_len = req_header.size; + iov[0].iov_base = &req_header; + + res = qb_ipcc_sendv_recv(conn, iov, 1, + &res_header, + sizeof(struct qb_ipc_response_header), -1); + ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); /* kill the server */ stop_process(pid); @@ -350,91 +426,97 @@ test_ipc_exit(void) qb_ipcc_disconnect(conn); } +START_TEST(test_ipc_exit_us) +{ + qb_enter(); + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + recv_timeout = 5000; + test_ipc_exit(); + qb_leave(); +} +END_TEST START_TEST(test_ipc_exit_shm) { + qb_enter(); ipc_type = QB_IPC_SHM; ipc_name = __func__; recv_timeout = 1000; test_ipc_exit(); + qb_leave(); } END_TEST START_TEST(test_ipc_txrx_shm_tmo) { + qb_enter(); turn_on_fc = QB_FALSE; ipc_type = QB_IPC_SHM; ipc_name = __func__; recv_timeout = 1000; test_ipc_txrx(); + qb_leave(); } END_TEST START_TEST(test_ipc_txrx_shm_block) { + qb_enter(); turn_on_fc = QB_FALSE; ipc_type = QB_IPC_SHM; ipc_name = __func__; recv_timeout = -1; test_ipc_txrx(); -} -END_TEST - -START_TEST(test_ipc_txrx_us_block) -{ - turn_on_fc = QB_FALSE; - ipc_type = QB_IPC_SOCKET; - ipc_name = __func__; - recv_timeout = -1; - test_ipc_txrx(); -} -END_TEST - -START_TEST(test_ipc_txrx_us_tmo) -{ - turn_on_fc = QB_FALSE; - ipc_type = QB_IPC_SOCKET; - ipc_name = __func__; - recv_timeout = 1000; - test_ipc_txrx(); + qb_leave(); } END_TEST START_TEST(test_ipc_fc_shm) { + qb_enter(); turn_on_fc = QB_TRUE; ipc_type = QB_IPC_SHM; recv_timeout = 500; ipc_name = __func__; test_ipc_txrx(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_txrx_us_block) +{ + qb_enter(); + turn_on_fc = QB_FALSE; + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + recv_timeout = -1; + test_ipc_txrx(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_txrx_us_tmo) +{ + qb_enter(); + turn_on_fc = QB_FALSE; + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + recv_timeout = 1000; + test_ipc_txrx(); + qb_leave(); } END_TEST START_TEST(test_ipc_fc_us) { + qb_enter(); turn_on_fc = QB_TRUE; ipc_type = QB_IPC_SOCKET; recv_timeout = 500; ipc_name = __func__; test_ipc_txrx(); -} -END_TEST - -START_TEST(test_ipc_txrx_pmq) -{ - turn_on_fc = QB_FALSE; - ipc_type = QB_IPC_POSIX_MQ; - ipc_name = __func__; - test_ipc_txrx(); -} -END_TEST - -START_TEST(test_ipc_txrx_smq) -{ - turn_on_fc = QB_FALSE; - ipc_type = QB_IPC_SYSV_MQ; - ipc_name = __func__; - test_ipc_txrx(); + qb_leave(); } END_TEST @@ -443,15 +525,13 @@ struct my_res { char message[1024 * 1024]; }; -static struct my_res response; static void test_ipc_dispatch(void) { - int32_t res; int32_t j; int32_t c = 0; pid_t pid; - struct qb_ipc_request_header req_header; + int32_t size; pid = run_function_in_new_process(run_ipc_server); fail_if(pid == -1); @@ -468,54 +548,230 @@ test_ipc_dispatch(void) } while (conn == NULL && c < 5); fail_if(conn == NULL); - req_header.id = IPC_MSG_REQ_DISPATCH; - req_header.size = sizeof(struct qb_ipc_request_header); - - repeat_send: - res = qb_ipcc_send(conn, &req_header, req_header.size); - if (res < 0) { - if (res == -EAGAIN) { - goto repeat_send; - } else if (res == -EINVAL || res == -EINTR) { - qb_perror(LOG_INFO, "qb_ipcc_send"); - return; - } else { - errno = -res; - qb_perror(LOG_INFO, "qb_ipcc_send"); - goto repeat_send; + size = QB_MIN(sizeof(struct qb_ipc_request_header), 64); + for (j = 1; j < 19; j++) { + size *= 2; + if (size >= MAX_MSG_SIZE) + break; + if (send_and_check(IPC_MSG_REQ_DISPATCH, size, + recv_timeout, QB_TRUE) < 0) { + break; } } - repeat_event_recv: - res = qb_ipcc_event_recv(conn, &response, sizeof(struct my_res), 0); - if (res < 0) { - if (res == -EAGAIN || res == -ETIMEDOUT) { - goto repeat_event_recv; - } else { - errno = -res; - qb_perror(LOG_INFO, "qb_ipcc_event_recv"); - goto repeat_send; - } - } - ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); - ck_assert_int_eq(response.hdr.id, IPC_MSG_RES_DISPATCH); qb_ipcc_disconnect(conn); stop_process(pid); } -START_TEST(test_ipc_disp_shm) -{ - ipc_type = QB_IPC_SHM; - ipc_name = __func__; - test_ipc_dispatch(); -} -END_TEST - START_TEST(test_ipc_disp_us) { + qb_enter(); ipc_type = QB_IPC_SOCKET; ipc_name = __func__; test_ipc_dispatch(); + qb_leave(); +} +END_TEST + +static int32_t events_received; + + +static int32_t +count_bulk_events(int32_t fd, int32_t revents, void *data) +{ + qb_loop_t *cl = (qb_loop_t*)data; + + events_received++; + + if (events_received >= num_bulk_events) { + qb_loop_stop(cl); + return -1; + } + return 0; +} + +static void +test_ipc_bulk_events(void) +{ + struct qb_ipc_request_header req_header; + struct qb_ipc_response_header res_header; + struct iovec iov[1]; + int32_t c = 0; + int32_t j = 0; + pid_t pid; + int32_t res; + qb_loop_t *cl; + int32_t fd; + + pid = run_function_in_new_process(run_ipc_server); + fail_if(pid == -1); + sleep(1); + + do { + conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); + if (conn == NULL) { + j = waitpid(pid, NULL, WNOHANG); + ck_assert_int_eq(j, 0); + sleep(1); + c++; + } + } while (conn == NULL && c < 5); + fail_if(conn == NULL); + + events_received = 0; + cl = qb_loop_create(); + res = qb_ipcc_fd_get(conn, &fd), + ck_assert_int_eq(res, 0); + res = qb_loop_poll_add(cl, QB_LOOP_MED, + fd, POLLIN, + cl, count_bulk_events); + ck_assert_int_eq(res, 0); + + res = send_and_check(IPC_MSG_REQ_BULK_EVENTS, + 0, + recv_timeout, QB_TRUE); + ck_assert_int_eq(res, sizeof(struct qb_ipc_response_header)); + + qb_loop_run(cl); + ck_assert_int_eq(events_received, num_bulk_events); + + req_header.id = IPC_MSG_REQ_SERVER_FAIL; + req_header.size = sizeof(struct qb_ipc_request_header); + + iov[0].iov_len = req_header.size; + iov[0].iov_base = &req_header; + res = qb_ipcc_sendv_recv(conn, iov, 1, + &res_header, + sizeof(struct qb_ipc_response_header), -1); + if (res != -ECONNRESET && res != -ENOTCONN) { + qb_log(LOG_ERR, "id:%d size:%d", res_header.id, res_header.size); + ck_assert_int_eq(res, -ENOTCONN); + } + + qb_ipcc_disconnect(conn); + stop_process(pid); +} + +START_TEST(test_ipc_bulk_events_us) +{ + qb_enter(); + send_event_on_created = QB_FALSE; + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + test_ipc_bulk_events(); + qb_leave(); +} +END_TEST + +static void +test_ipc_event_on_created(void) +{ + int32_t c = 0; + int32_t j = 0; + pid_t pid; + int32_t res; + qb_loop_t *cl; + int32_t fd; + + num_bulk_events = 1; + + pid = run_function_in_new_process(run_ipc_server); + fail_if(pid == -1); + sleep(1); + + do { + conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); + if (conn == NULL) { + j = waitpid(pid, NULL, WNOHANG); + ck_assert_int_eq(j, 0); + sleep(1); + c++; + } + } while (conn == NULL && c < 5); + fail_if(conn == NULL); + + events_received = 0; + cl = qb_loop_create(); + res = qb_ipcc_fd_get(conn, &fd), + ck_assert_int_eq(res, 0); + res = qb_loop_poll_add(cl, QB_LOOP_MED, + fd, POLLIN, + cl, count_bulk_events); + ck_assert_int_eq(res, 0); + + qb_loop_run(cl); + ck_assert_int_eq(events_received, num_bulk_events); + + qb_ipcc_disconnect(conn); + stop_process(pid); +} + +START_TEST(test_ipc_event_on_created_us) +{ + qb_enter(); + send_event_on_created = QB_TRUE; + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + test_ipc_event_on_created(); + qb_leave(); +} +END_TEST + +static void +test_ipc_disconnect_after_created(void) +{ + struct qb_ipc_request_header req_header; + struct qb_ipc_response_header res_header; + struct iovec iov[1]; + int32_t c = 0; + int32_t j = 0; + pid_t pid; + int32_t res; + + pid = run_function_in_new_process(run_ipc_server); + fail_if(pid == -1); + sleep(1); + + do { + conn = qb_ipcc_connect(ipc_name, MAX_MSG_SIZE); + if (conn == NULL) { + j = waitpid(pid, NULL, WNOHANG); + ck_assert_int_eq(j, 0); + sleep(1); + c++; + } + } while (conn == NULL && c < 5); + fail_if(conn == NULL); + + ck_assert_int_eq(QB_TRUE, qb_ipcc_is_connected(conn)); + + req_header.id = IPC_MSG_REQ_SERVER_DISCONNECT; + req_header.size = sizeof(struct qb_ipc_request_header); + + iov[0].iov_len = req_header.size; + iov[0].iov_base = &req_header; + + res = qb_ipcc_sendv_recv(conn, iov, 1, + &res_header, + sizeof(struct qb_ipc_response_header), -1); + /* + * confirm we get -ENOTCONN + */ + ck_assert_int_eq(res, -ENOTCONN); + ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn)); + + qb_ipcc_disconnect(conn); + stop_process(pid); +} + +START_TEST(test_ipc_disconnect_after_created_us) +{ + qb_enter(); + disconnect_after_created = QB_TRUE; + ipc_type = QB_IPC_SOCKET; + ipc_name = __func__; + test_ipc_disconnect_after_created(); + qb_leave(); } END_TEST @@ -554,6 +810,8 @@ test_ipc_server_fail(void) iov[0].iov_len = req_header.size; iov[0].iov_base = &req_header; + ck_assert_int_eq(QB_TRUE, qb_ipcc_is_connected(conn)); + res = qb_ipcc_sendv_recv(conn, iov, 1, &res_header, sizeof(struct qb_ipc_response_header), -1); @@ -561,6 +819,7 @@ test_ipc_server_fail(void) * confirm we get -ENOTCONN */ ck_assert_int_eq(res, -ENOTCONN); + ck_assert_int_eq(QB_FALSE, qb_ipcc_is_connected(conn)); qb_ipcc_disconnect(conn); stop_process(pid); @@ -568,37 +827,67 @@ test_ipc_server_fail(void) START_TEST(test_ipc_server_fail_soc) { + qb_enter(); ipc_type = QB_IPC_SOCKET; ipc_name = __func__; test_ipc_server_fail(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_disp_shm) +{ + qb_enter(); + ipc_type = QB_IPC_SHM; + ipc_name = __func__; + test_ipc_dispatch(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_bulk_events_shm) +{ + qb_enter(); + ipc_type = QB_IPC_SHM; + ipc_name = __func__; + test_ipc_bulk_events(); + qb_leave(); +} +END_TEST + +START_TEST(test_ipc_event_on_created_shm) +{ + qb_enter(); + send_event_on_created = QB_TRUE; + ipc_type = QB_IPC_SHM; + ipc_name = __func__; + test_ipc_event_on_created(); + qb_leave(); } END_TEST START_TEST(test_ipc_server_fail_shm) { + qb_enter(); ipc_type = QB_IPC_SHM; ipc_name = __func__; test_ipc_server_fail(); + qb_leave(); } END_TEST + static Suite * -ipc_suite(void) +make_shm_suite(void) { TCase *tc; - uid_t uid; - Suite *s = suite_create("ipc"); + Suite *s = suite_create("shm"); tc = tcase_create("ipc_server_fail_shm"); tcase_add_test(tc, test_ipc_server_fail_shm); tcase_set_timeout(tc, 6); suite_add_tcase(s, tc); - tc = tcase_create("ipc_server_fail_soc"); - tcase_add_test(tc, test_ipc_server_fail_soc); - tcase_set_timeout(tc, 6); - suite_add_tcase(s, tc); - tc = tcase_create("ipc_txrx_shm_block"); tcase_add_test(tc, test_ipc_txrx_shm_block); tcase_set_timeout(tc, 6); @@ -609,6 +898,44 @@ ipc_suite(void) tcase_set_timeout(tc, 6); suite_add_tcase(s, tc); + tc = tcase_create("ipc_fc_shm"); + tcase_add_test(tc, test_ipc_fc_shm); + tcase_set_timeout(tc, 6); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_dispatch_shm"); + tcase_add_test(tc, test_ipc_disp_shm); + tcase_set_timeout(tc, 16); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_bulk_events_shm"); + tcase_add_test(tc, test_ipc_bulk_events_shm); + tcase_set_timeout(tc, 16); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_exit_shm"); + tcase_add_test(tc, test_ipc_exit_shm); + tcase_set_timeout(tc, 3); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_event_on_created_shm"); + tcase_add_test(tc, test_ipc_event_on_created_shm); + suite_add_tcase(s, tc); + + return s; +} + +static Suite * +make_soc_suite(void) +{ + Suite *s = suite_create("socket"); + TCase *tc; + + tc = tcase_create("ipc_server_fail_soc"); + tcase_add_test(tc, test_ipc_server_fail_soc); + tcase_set_timeout(tc, 6); + suite_add_tcase(s, tc); + tc = tcase_create("ipc_txrx_us_block"); tcase_add_test(tc, test_ipc_txrx_us_block); tcase_set_timeout(tc, 6); @@ -619,31 +946,14 @@ ipc_suite(void) tcase_set_timeout(tc, 6); suite_add_tcase(s, tc); - tc = tcase_create("ipc_fc_shm"); - tcase_add_test(tc, test_ipc_fc_shm); - tcase_set_timeout(tc, 6); - suite_add_tcase(s, tc); - tc = tcase_create("ipc_fc_us"); tcase_add_test(tc, test_ipc_fc_us); tcase_set_timeout(tc, 6); suite_add_tcase(s, tc); - uid = geteuid(); - if (uid == 0) { - tc = tcase_create("ipc_txrx_posix_mq"); - tcase_add_test(tc, test_ipc_txrx_pmq); - tcase_set_timeout(tc, 10); - suite_add_tcase(s, tc); - - tc = tcase_create("ipc_txrx_sysv_mq"); - tcase_add_test(tc, test_ipc_txrx_smq); - tcase_set_timeout(tc, 10); - suite_add_tcase(s, tc); - } - tc = tcase_create("ipc_dispatch_shm"); - tcase_add_test(tc, test_ipc_disp_shm); - tcase_set_timeout(tc, 16); + tc = tcase_create("ipc_exit_us"); + tcase_add_test(tc, test_ipc_exit_us); + tcase_set_timeout(tc, 6); suite_add_tcase(s, tc); tc = tcase_create("ipc_dispatch_us"); @@ -651,9 +961,17 @@ ipc_suite(void) tcase_set_timeout(tc, 16); suite_add_tcase(s, tc); - tc = tcase_create("ipc_exit_shm"); - tcase_add_test(tc, test_ipc_exit_shm); - tcase_set_timeout(tc, 3); + tc = tcase_create("ipc_bulk_events_us"); + tcase_add_test(tc, test_ipc_bulk_events_us); + tcase_set_timeout(tc, 16); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_event_on_created_us"); + tcase_add_test(tc, test_ipc_event_on_created_us); + suite_add_tcase(s, tc); + + tc = tcase_create("ipc_disconnect_after_created_us"); + tcase_add_test(tc, test_ipc_disconnect_after_created_us); suite_add_tcase(s, tc); return s; @@ -663,15 +981,27 @@ int32_t main(void) { int32_t number_failed; + SRunner *sr; + Suite *s; + int32_t do_shm_tests = QB_TRUE; - Suite *s = ipc_suite(); - SRunner *sr = srunner_create(s); +#ifdef DISABLE_IPC_SHM + do_shm_tests = QB_FALSE; +#endif /* DISABLE_IPC_SHM */ + + s = make_soc_suite(); + sr = srunner_create(s); + + if (do_shm_tests) { + srunner_add_suite(sr, make_shm_suite()); + } qb_log_init("check", LOG_USER, LOG_EMERG); qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, - QB_LOG_FILTER_FILE, "*", LOG_INFO); + QB_LOG_FILTER_FILE, "*", LOG_TRACE); qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); + qb_log_format_set(QB_LOG_STDERR, "lib/%f|%l| %b"); srunner_run_all(sr, CK_VERBOSE); number_failed = srunner_ntests_failed(sr); diff --git a/tests/check_log.c b/tests/check_log.c index 33210b1..d646222 100644 --- a/tests/check_log.c +++ b/tests/check_log.c @@ -29,7 +29,7 @@ #include #include -extern size_t qb_vsprintf_serialize(char *serialize, const char *fmt, va_list ap); +extern size_t qb_vsnprintf_serialize(char *serialize, size_t max_len, const char *fmt, va_list ap); extern size_t qb_vsnprintf_deserialize(char *string, size_t strlen, const char *buf); @@ -40,18 +40,35 @@ format_this(char *out, const char *fmt, ...) va_list ap; va_start(ap, fmt); - qb_vsprintf_serialize(buf, fmt, ap); + qb_vsnprintf_serialize(buf, QB_LOG_MAX_LEN, fmt, ap); qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf); va_end(ap); } +static void +format_this_up_to(char *out, size_t max_len, const char *fmt, ...) +{ + char buf[QB_LOG_MAX_LEN]; + va_list ap; + + va_start(ap, fmt); + qb_vsnprintf_serialize(buf, max_len, fmt, ap); + qb_vsnprintf_deserialize(out, QB_LOG_MAX_LEN, buf); + va_end(ap); +} START_TEST(test_va_serialize) { char buf[QB_LOG_MAX_LEN]; + char cmp_buf[QB_LOG_MAX_LEN]; + format_this(buf, "one line"); ck_assert_str_eq(buf, "one line"); + format_this(buf, "p1:%p, p2:%p", format_this, buf); + snprintf(cmp_buf, QB_LOG_MAX_LEN, "p1:%p, p2:%p", format_this, buf); + ck_assert_str_eq(buf, cmp_buf); + format_this(buf, "s1:%s, s2:%s", "Yes", "Never"); ck_assert_str_eq(buf, "s1:Yes, s2:Never"); @@ -83,6 +100,9 @@ START_TEST(test_va_serialize) format_this(buf, ":%*d:", 8, 96); ck_assert_str_eq(buf, ": 96:"); + + format_this_up_to(buf, 11, "123456789____"); + ck_assert_str_eq(buf, "123456789_"); } END_TEST @@ -553,16 +573,80 @@ END_TEST START_TEST(test_log_long_msg) { - qb_log_init("test", LOG_USER, LOG_DEBUG); - qb_log_filter_ctl(QB_LOG_SYSLOG, QB_LOG_FILTER_ADD, - QB_LOG_FILTER_FILE, "*", LOG_DEBUG); - qb_log_format_set(QB_LOG_SYSLOG, "%b"); + int lpc; + int rc; + int i, max = 1000; + char *buffer = calloc(1, max); - qb_log(LOG_ERR, "QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07 QMF Agent Initialized: broker=localhost:49000 interval=5 storeFile=.cloudpolicyengine-data-cpe name=cloudpolicyengine.org:cpe:04eabb39-89cf-47dd-9d14-7e77d864be07"); + qb_log_init("test", LOG_USER, LOG_DEBUG); + rc = qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); + ck_assert_int_eq(rc, 0); + rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024); + ck_assert_int_eq(rc, 0); + rc = qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); + ck_assert_int_eq(rc, 0); + rc = qb_log_filter_ctl(QB_LOG_BLACKBOX, QB_LOG_FILTER_ADD, + QB_LOG_FILTER_FILE, "*", LOG_TRACE); + ck_assert_int_eq(rc, 0); + + for (lpc = 500; lpc < max; lpc++) { + lpc++; + for(i = 0; i < max; i++) { + buffer[i] = 'a' + (i % 10); + } + buffer[lpc%600] = 0; + qb_log(LOG_INFO, "Message %d %d - %s", lpc, lpc%600, buffer); + } + + qb_log_blackbox_write_to_file("blackbox.dump"); + qb_log_blackbox_print_from_file("blackbox.dump"); + unlink("blackbox.dump"); + qb_log_fini(); } END_TEST -static Suite *log_suite(void) +START_TEST(test_threaded_logging) +{ + int32_t t; + int32_t rc; + + qb_log_init("test", LOG_USER, LOG_EMERG); + qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); + + t = qb_log_custom_open(_test_logger, NULL, NULL, NULL); + rc = qb_log_filter_ctl(t, QB_LOG_FILTER_ADD, + QB_LOG_FILTER_FILE, "*", LOG_INFO); + ck_assert_int_eq(rc, 0); + qb_log_format_set(t, "%b"); + rc = qb_log_ctl(t, QB_LOG_CONF_ENABLED, QB_TRUE); + ck_assert_int_eq(rc, 0); + rc = qb_log_ctl(t, QB_LOG_CONF_THREADED, QB_TRUE); + ck_assert_int_eq(rc, 0); + qb_log_thread_start(); + + memset(test_buf, 0, sizeof(test_buf)); + test_priority = 0; + num_msgs = 0; + + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + qb_log(LOG_INFO, "Yoda how old are you? - %d", __LINE__); + + qb_log_fini(); + + ck_assert_int_eq(num_msgs, 10); +} +END_TEST + +static Suite * +log_suite(void) { TCase *tc; Suite *s = suite_create("logging"); @@ -600,6 +684,10 @@ static Suite *log_suite(void) tcase_add_test(tc, test_log_filter_fn); suite_add_tcase(s, tc); + tc = tcase_create("threaded_logging"); + tcase_add_test(tc, test_threaded_logging); + suite_add_tcase(s, tc); + return s; } diff --git a/tests/check_rb.c b/tests/check_rb.c index 97b6dd4..f72f647 100644 --- a/tests/check_rb.c +++ b/tests/check_rb.c @@ -105,10 +105,6 @@ START_TEST(test_ring_buffer2) } for (i = 0; i < 100; i++) { l = qb_rb_chunk_peek(t, (void **)&new_data, 0); - if (l < 0) { - /* no more to read */ - break; - } ck_assert_int_eq(l, sizeof(v)); fail_unless(v == *new_data); qb_rb_chunk_reclaim(t); diff --git a/tests/rbreader.c b/tests/rbreader.c index 6b5356b..406bbd8 100644 --- a/tests/rbreader.c +++ b/tests/rbreader.c @@ -28,9 +28,10 @@ #include #include -#define BUFFER_CHUNK_SIZE (50*50*10) +#define ONE_MEG 1048576 static qb_ringbuffer_t *rb = NULL; static int keep_reading = QB_TRUE; +int8_t buffer[ONE_MEG]; static void sigterm_handler(int32_t num) @@ -42,18 +43,18 @@ static void sigterm_handler(int32_t num) int32_t main(int32_t argc, char *argv[]) { ssize_t num_read; - int8_t buffer[BUFFER_CHUNK_SIZE]; signal(SIGINT, sigterm_handler); qb_log_init("rbreader", LOG_USER, LOG_EMERG); qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_FALSE); qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, - QB_LOG_FILTER_FILE, "*", LOG_INFO); + QB_LOG_FILTER_FILE, "*", LOG_TRACE); qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); - rb = qb_rb_open("tester", BUFFER_CHUNK_SIZE * 3, - QB_RB_FLAG_SHARED_PROCESS | QB_RB_FLAG_CREATE, 0); + rb = qb_rb_open("tester", ONE_MEG * 3, + QB_RB_FLAG_SHARED_PROCESS | + QB_RB_FLAG_CREATE, 0); if (rb == NULL) { qb_perror(LOG_ERR, "failed to create ringbuffer"); @@ -61,8 +62,11 @@ int32_t main(int32_t argc, char *argv[]) } while (keep_reading) { num_read = qb_rb_chunk_read(rb, buffer, - BUFFER_CHUNK_SIZE, 5500); - if (num_read < 0) { + ONE_MEG, 0); + if (num_read == -ETIMEDOUT) { + usleep(100000); + } else if (num_read < 0) { + errno = -num_read; qb_perror(LOG_ERR, "nothing to read"); } } diff --git a/tests/rbwriter.c b/tests/rbwriter.c index d105398..4e684a0 100644 --- a/tests/rbwriter.c +++ b/tests/rbwriter.c @@ -35,21 +35,16 @@ #include #include +static int alarm_notice = 0; static qb_ringbuffer_t *rb = NULL; -#define ITERATIONS 100000 -#define BUFFER_CHUNK_SIZE (50*50*10) +static qb_util_stopwatch_t *sw; +#define ONE_MEG 1048576 +static char buffer[ONE_MEG * 3]; -static struct timeval tv1, tv2, tv_elapsed; - -#define timersub(a, b, result) \ -do { \ - (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ - (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) { \ - --(result)->tv_sec; \ - (result)->tv_usec += 1000000; \ - } \ -} while (0) +static void sigalrm_handler (int num) +{ + alarm_notice = 1; +} static void sigterm_handler(int32_t num) { @@ -58,53 +53,56 @@ static void sigterm_handler(int32_t num) exit(0); } -static void bm_start(void) +static void +_benchmark(ssize_t write_size) { - gettimeofday(&tv1, NULL); -} + ssize_t res; + int write_count = 0; + float secs; -static void bm_finish(const char *operation, int32_t size) -{ - float ops_per_sec; - float mbs_per_sec; + alarm_notice = 0; - gettimeofday(&tv2, NULL); - timersub(&tv2, &tv1, &tv_elapsed); + alarm (10); - ops_per_sec = - ((float)ITERATIONS) / (((float)tv_elapsed.tv_sec) + - (((float)tv_elapsed.tv_usec) / 1000000.0)); - - mbs_per_sec = - ((((float)ITERATIONS) * size) / - (((float)tv_elapsed.tv_sec) + - (((float)tv_elapsed.tv_usec) / 1000000.0))) / (1024.0 * 1024.0); - - qb_log(LOG_INFO, "write size %d OPs/sec %9.3f MB/sec %9.3f", - size, ops_per_sec, mbs_per_sec); -} - -static void bmc_connect(void) -{ - rb = qb_rb_open("tester", BUFFER_CHUNK_SIZE * 3, - QB_RB_FLAG_SHARED_PROCESS, 0); - - if (rb == NULL) { - qb_perror(LOG_ERR, "failed to create ringbuffer"); - exit(1); + qb_util_stopwatch_start(sw); + do { + res = qb_rb_chunk_write(rb, buffer, write_size); + if (res == write_size) { + write_count++; + } + } while (alarm_notice == 0 && (res == write_size || res == -EAGAIN)); + if (res < 0) { + perror("qb_ipcc_sendv"); } + qb_util_stopwatch_stop(sw); + secs = qb_util_stopwatch_sec_elapsed_get(sw); + printf ("%5d messages sent ", write_count); + printf ("%5ld bytes per write ", (long int) write_size); + printf ("%7.3f Seconds runtime ", secs); + printf ("%9.3f TP/s ", + ((float)write_count) / secs); + printf ("%7.3f MB/s.\n", + ((float)write_count) * ((float)write_size) / secs); } -static char buffer[1024 * 1024]; -static void bmc_send_nozc(size_t size) -{ - ssize_t res = 0; -repeat_send: - res = qb_rb_chunk_write(rb, buffer, size); - if (res < size) { - goto repeat_send; +static void +do_throughput_benchmark(void) +{ + ssize_t size = 64; + int i; + + signal (SIGALRM, sigalrm_handler); + sw = qb_util_stopwatch_create(); + + for (i = 0; i < 10; i++) { /* number of repetitions - up to 50k */ + _benchmark(size); + signal (SIGALRM, sigalrm_handler); + size *= 5; + if (size >= ONE_MEG) { + break; + } } } @@ -125,8 +123,6 @@ int32_t main(int32_t argc, char *argv[]) { const char *options = "vh"; int32_t opt; - int32_t i, j; - int32_t size; int32_t verbose = 0; while ((opt = getopt(argc, argv, options)) != -1) { @@ -150,21 +146,9 @@ int32_t main(int32_t argc, char *argv[]) QB_LOG_FILTER_FILE, "*", LOG_INFO + verbose); qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); - bmc_connect(); - - for (j = 1; j < 49; j++) { - bm_start(); - size = 7 * (j + 1) * j; - - if (size > BUFFER_CHUNK_SIZE) { - size = BUFFER_CHUNK_SIZE; - } - - for (i = 0; i < ITERATIONS; i++) { - bmc_send_nozc(size); - } - bm_finish("ringbuffer", size); - } + rb = qb_rb_open("tester", ONE_MEG * 3, + QB_RB_FLAG_SHARED_PROCESS, 0); + do_throughput_benchmark(); qb_rb_close(rb); return EXIT_SUCCESS; } diff --git a/tests/resources.test b/tests/resources.test index 0eadc4d..4a1de14 100755 --- a/tests/resources.test +++ b/tests/resources.test @@ -1,13 +1,17 @@ -#!/bin/bash +#!/bin/sh RETURN=0 -ls /dev/shm/qb-test* 2>/dev/null -if [ $? -eq 0 ] -then - echo - echo "Error: shared memory segments not closed/unlinked" - echo - RETURN=1 -fi + +for d in /dev/shm /var/run +do + ls $d/qb-test* 2>/dev/null + if [ $? -eq 0 ] + then + echo + echo "Error: shared memory segments not closed/unlinked" + echo + RETURN=1 + fi +done ps aux | grep -v grep | grep lt-check if [ $? -eq 0 ] then @@ -16,4 +20,3 @@ then fi exit $RETURN - diff --git a/tools/Makefile.am b/tools/Makefile.am new file mode 100644 index 0000000..a790fd9 --- /dev/null +++ b/tools/Makefile.am @@ -0,0 +1,28 @@ +# Copyright (c) 2011 Red Hat, Inc. +# +# Authors: Angus Salkeld +# +# This file is part of libqb. +# +# libqb is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2.1 of the License, or +# (at your option) any later version. +# +# libqb 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with libqb. If not, see . +# +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = +CLEANFILES = + +sbin_PROGRAMS = qb-blackbox + +qb_blackbox_SOURCES = qb_blackbox.c $(top_builddir)/include/qb/qblog.h +qb_blackbox_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include +qb_blackbox_LDADD = $(top_builddir)/lib/libqb.la diff --git a/tools/Makefile.in b/tools/Makefile.in new file mode 100644 index 0000000..e055e7b --- /dev/null +++ b/tools/Makefile.in @@ -0,0 +1,590 @@ +# Makefile.in generated by automake 1.11.3 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software +# Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +sbin_PROGRAMS = qb-blackbox$(EXEEXT) +subdir = tools +DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \ + $(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/include/config.h \ + $(top_builddir)/include/qb/qbconfig.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__installdirs = "$(DESTDIR)$(sbindir)" +PROGRAMS = $(sbin_PROGRAMS) +am_qb_blackbox_OBJECTS = qb_blackbox-qb_blackbox.$(OBJEXT) +qb_blackbox_OBJECTS = $(am_qb_blackbox_OBJECTS) +qb_blackbox_DEPENDENCIES = $(top_builddir)/lib/libqb.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/include -I$(top_builddir)/include/qb +depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +SOURCES = $(qb_blackbox_SOURCES) +DIST_SOURCES = $(qb_blackbox_SOURCES) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +CP = @CP@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOXYGEN = @DOXYGEN@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LINT_FLAGS = @LINT_FLAGS@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PKGCONFIG = @PKGCONFIG@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SOCKETDIR = @SOCKETDIR@ +SPLINT = @SPLINT@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Copyright (c) 2011 Red Hat, Inc. +# +# Authors: Angus Salkeld +# +# This file is part of libqb. +# +# libqb is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 2.1 of the License, or +# (at your option) any later version. +# +# libqb 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 Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with libqb. If not, see . +# +MAINTAINERCLEANFILES = Makefile.in +EXTRA_DIST = +CLEANFILES = +qb_blackbox_SOURCES = qb_blackbox.c $(top_builddir)/include/qb/qblog.h +qb_blackbox_CPPFLAGS = -I$(top_builddir)/include -I$(top_srcdir)/include +qb_blackbox_LDADD = $(top_builddir)/lib/libqb.la +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tools/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu tools/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + for p in $$list; do echo "$$p $$p"; done | \ + sed 's/$(EXEEXT)$$//' | \ + while read p p1; do if test -f $$p || test -f $$p1; \ + then echo "$$p"; echo "$$p"; else :; fi; \ + done | \ + sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ + -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ + sed 'N;N;N;s,\n, ,g' | \ + $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ + { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ + if ($$2 == $$4) files[d] = files[d] " " $$1; \ + else { print "f", $$3 "/" $$4, $$1; } } \ + END { for (d in files) print "f", d, files[d] }' | \ + while read type dir files; do \ + if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ + test -z "$$files" || { \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(sbindir)$$dir'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(sbindir)$$dir" || exit $$?; \ + } \ + ; done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \ + files=`for p in $$list; do echo "$$p"; done | \ + sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ + -e 's/$$/$(EXEEXT)/' `; \ + test -n "$$list" || exit 0; \ + echo " ( cd '$(DESTDIR)$(sbindir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(sbindir)" && rm -f $$files + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +qb-blackbox$(EXEEXT): $(qb_blackbox_OBJECTS) $(qb_blackbox_DEPENDENCIES) $(EXTRA_qb_blackbox_DEPENDENCIES) + @rm -f qb-blackbox$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(qb_blackbox_OBJECTS) $(qb_blackbox_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qb_blackbox-qb_blackbox.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +qb_blackbox-qb_blackbox.o: qb_blackbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qb_blackbox-qb_blackbox.o -MD -MP -MF $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo -c -o qb_blackbox-qb_blackbox.o `test -f 'qb_blackbox.c' || echo '$(srcdir)/'`qb_blackbox.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo $(DEPDIR)/qb_blackbox-qb_blackbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qb_blackbox.c' object='qb_blackbox-qb_blackbox.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qb_blackbox-qb_blackbox.o `test -f 'qb_blackbox.c' || echo '$(srcdir)/'`qb_blackbox.c + +qb_blackbox-qb_blackbox.obj: qb_blackbox.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT qb_blackbox-qb_blackbox.obj -MD -MP -MF $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo -c -o qb_blackbox-qb_blackbox.obj `if test -f 'qb_blackbox.c'; then $(CYGPATH_W) 'qb_blackbox.c'; else $(CYGPATH_W) '$(srcdir)/qb_blackbox.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/qb_blackbox-qb_blackbox.Tpo $(DEPDIR)/qb_blackbox-qb_blackbox.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='qb_blackbox.c' object='qb_blackbox-qb_blackbox.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(qb_blackbox_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o qb_blackbox-qb_blackbox.obj `if test -f 'qb_blackbox.c'; then $(CYGPATH_W) 'qb_blackbox.c'; else $(CYGPATH_W) '$(srcdir)/qb_blackbox.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + set x; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: + for dir in "$(DESTDIR)$(sbindir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES) +clean: clean-am + +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: install-sbinPROGRAMS + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-sbinPROGRAMS + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ + clean-libtool clean-sbinPROGRAMS ctags distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am uninstall-sbinPROGRAMS + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/tools/qb_blackbox.c b/tools/qb_blackbox.c new file mode 100644 index 0000000..e39f6bf --- /dev/null +++ b/tools/qb_blackbox.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2012 Andrew Beekhof + * + * libqb is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * libqb 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with libqb. If not, see . + */ + +#include + +int +main(int argc, char **argv) +{ + int lpc = 0; + + qb_log_init("qb_blackbox", LOG_USER, LOG_TRACE); + qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE); + qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD, QB_LOG_FILTER_FILE, "*", LOG_TRACE); + + for(lpc = 1; lpc < argc && argv[lpc] != NULL; lpc++) { + printf("Dumping the contents of %s\n", argv[lpc]); + qb_log_blackbox_print_from_file(argv[lpc]); + } + return 0; +}