diff options
Diffstat (limited to 'deps/libeio')
-rw-r--r-- | deps/libeio/Changes | 11 | ||||
-rw-r--r-- | deps/libeio/LICENSE | 36 | ||||
-rw-r--r-- | deps/libeio/Makefile.am | 15 | ||||
-rw-r--r-- | deps/libeio/aclocal.m4 | 7243 | ||||
-rwxr-xr-x | deps/libeio/autogen.sh | 5 | ||||
-rw-r--r-- | deps/libeio/config.h.in | 73 | ||||
-rw-r--r-- | deps/libeio/configure.ac | 22 | ||||
-rw-r--r-- | deps/libeio/demo.c | 194 | ||||
-rw-r--r-- | deps/libeio/eio.3 | 3428 | ||||
-rw-r--r-- | deps/libeio/eio.c | 1555 | ||||
-rw-r--r-- | deps/libeio/eio.h | 246 | ||||
-rw-r--r-- | deps/libeio/eio.pod | 282 | ||||
-rw-r--r-- | deps/libeio/libeio.m4 | 107 | ||||
-rw-r--r-- | deps/libeio/xthread.h | 154 |
14 files changed, 13371 insertions, 0 deletions
diff --git a/deps/libeio/Changes b/deps/libeio/Changes new file mode 100644 index 0000000000..d98deefdd0 --- /dev/null +++ b/deps/libeio/Changes @@ -0,0 +1,11 @@ +Revision history for libeio + +TODO: maybe add mincore support? available on at leats darwin, solaris, linux, freebsd + +1.0 + - added msync, mtouch support (untested). + - added sync_file_range (untested). + - fixed custom support. + - use a more robust feed-add detection method. + - "outbundled" from IO::AIO. + diff --git a/deps/libeio/LICENSE b/deps/libeio/LICENSE new file mode 100644 index 0000000000..1ed1324d30 --- /dev/null +++ b/deps/libeio/LICENSE @@ -0,0 +1,36 @@ +All files in libeio are Copyright (C)2007,2008 Marc Alexander Lehmann. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Alternatively, the contents of this package may be used under the terms +of the GNU General Public License ("GPL") version 2 or any later version, +in which case the provisions of the GPL are applicable instead of the +above. If you wish to allow the use of your version of this package only +under the terms of the GPL and not to allow others to use your version of +this file under the BSD license, indicate your decision by deleting the +provisions above and replace them with the notice and other provisions +required by the GPL in this and the other files of this package. If you do +not delete the provisions above, a recipient may use your version of this +file under either the BSD or the GPL. diff --git a/deps/libeio/Makefile.am b/deps/libeio/Makefile.am new file mode 100644 index 0000000000..857d26b619 --- /dev/null +++ b/deps/libeio/Makefile.am @@ -0,0 +1,15 @@ +AUTOMAKE_OPTIONS = foreign no-dependencies + +VERSION_INFO = 1:0 + +EXTRA_DIST = LICENSE Changes autogen.sh + +#man_MANS = ev.3 + +include_HEADERS = eio.h + +lib_LTLIBRARIES = libeio.la + +libeio_la_SOURCES = eio.c xthread.h config.h +libeio_la_LDFLAGS = -version-info $(VERSION_INFO) + diff --git a/deps/libeio/aclocal.m4 b/deps/libeio/aclocal.m4 new file mode 100644 index 0000000000..67b09cfd74 --- /dev/null +++ b/deps/libeio/aclocal.m4 @@ -0,0 +1,7243 @@ +# generated automatically by aclocal 1.7.9 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002 +# Free Software Foundation, Inc. +# This file 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. + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 10 + +AC_PREREQ([2.54]) + +# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow +# the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl + AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +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 +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_MISSING_PROG(AMTAR, tar) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl + +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.7"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.7.9])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# 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". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# -*- Autoconf -*- + + +# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_AUX_DIR_EXPAND + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +# Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50]) + +AC_DEFUN([AM_AUX_DIR_EXPAND], [ +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# 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. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[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 +AC_SUBST([am__leading_dot])]) + +# serial 5 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[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'. + 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_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + 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 + : > sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + 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 + ;; + none) break ;; + esac + # 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. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} 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 + # (even with -Werror). So we grep stderr for any message + # that says an option was ignored. + if grep 'ignoring option' conftest.err >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking Speeds up one-time builds + --enable-dependency-tracking Do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue + # Extract the definition of DEP_FILES from the Makefile without + # running `make'. + DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"` + test -z "$DEPDIR" && continue + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n -e '/^U = / s///p' < "$mf"` + test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR" + # We invoke sed twice because it is the simplest approach to + # changing $(DEPDIR) to its actual value in the expansion. + for file in `sed -n -e ' + /^DEP_FILES = .*\\\\$/ { + s/^DEP_FILES = // + :loop + s/\\\\$// + p + n + /\\\\$/ b loop + p + } + /^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright 1997, 2000, 2001 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 5 + +AC_PREREQ(2.52) + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]) +fi])]) + +# Add --enable-maintainer-mode option to configure. +# From Jim Meyering + +# Copyright 1996, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program 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 General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- + +# serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[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 avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat <<EOF +[$]* +EOF + exit 0 +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# --------------------------------------------------------------------- +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext <<EOF +[#line __oline__ "configure" +#include "confdefs.h" + +#if HAVE_DLFCN_H +#include <dlfcn.h> +#endif + +#include <stdio.h> + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ---------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib<name>.so + # instead of lib<name>.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +# set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <<EOF 1>&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in + *GNU* | *'with BFD'*) + test "$with_gnu_ld" != no && break + ;; + *) + test "$with_gnu_ld" != yes && break + ;; + esac + fi + done + IFS="$lt_save_ifs" +else + lt_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$lt_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +])# AC_PROG_LD + + +# AC_PROG_LD_GNU +# -------------- +AC_DEFUN([AC_PROG_LD_GNU], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_CACHE_CHECK([if the linker ($LD) is GNU ld], lt_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU lds only accept -v. +case `$LD -v 2>&1 </dev/null` in +*GNU* | *'with BFD'*) + lt_cv_prog_gnu_ld=yes + ;; +*) + lt_cv_prog_gnu_ld=no + ;; +esac]) +with_gnu_ld=$lt_cv_prog_gnu_ld +])# AC_PROG_LD_GNU + + +# AC_PROG_LD_RELOAD_FLAG +# ---------------------- +# find reload flag for linker +# -- PORTME Some linkers may need a different reload flag. +AC_DEFUN([AC_PROG_LD_RELOAD_FLAG], +[AC_CACHE_CHECK([for $LD option to reload object files], + lt_cv_ld_reload_flag, + [lt_cv_ld_reload_flag='-r']) +reload_flag=$lt_cv_ld_reload_flag +case $reload_flag in +"" | " "*) ;; +*) reload_flag=" $reload_flag" ;; +esac +reload_cmds='$LD$reload_flag -o $output$reload_objs' +case $host_os in + darwin*) + if test "$GCC" = yes; then + reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' + else + reload_cmds='$LD$reload_flag -o $output$reload_objs' + fi + ;; +esac +])# AC_PROG_LD_RELOAD_FLAG + + +# AC_DEPLIBS_CHECK_METHOD +# ----------------------- +# how to check for library dependencies +# -- PORTME fill in with the dynamic library characteristics +AC_DEFUN([AC_DEPLIBS_CHECK_METHOD], +[AC_CACHE_CHECK([how to recognise dependent libraries], +lt_cv_deplibs_check_method, +[lt_cv_file_magic_cmd='$MAGIC_CMD' +lt_cv_file_magic_test_file= +lt_cv_deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [[regex]]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given extended regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. + +case $host_os in +aix4* | aix5*) + lt_cv_deplibs_check_method=pass_all + ;; + +beos*) + lt_cv_deplibs_check_method=pass_all + ;; + +bsdi[[45]]*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' + lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_test_file=/shlib/libc.so + ;; + +cygwin*) + # func_win32_libid is a shell function defined in ltmain.sh + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + ;; + +mingw* | pw32*) + # Base MSYS/MinGW do not provide the 'file' command needed by + # func_win32_libid shell function, so use a weaker test based on 'objdump'. + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + ;; + +darwin* | rhapsody*) + lt_cv_deplibs_check_method=pass_all + ;; + +freebsd* | dragonfly*) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext <<EOF +int a; +void foo (void) { a = 0; } +EOF +],[$1],[CXX],[cat > conftest.$ac_ext <<EOF +class Foo +{ +public: + Foo (void) { a = 0; } +private: + int a; +}; +EOF +],[$1],[F77],[cat > conftest.$ac_ext <<EOF + subroutine foo + implicit none + integer*4 a + a=0 + return + end +EOF +],[$1],[GCJ],[cat > conftest.$ac_ext <<EOF +public class foo { + private int a; + public void bar (void) { + a = 0; + } +}; +EOF +]) +dnl Parse the compiler output and extract the necessary +dnl objects, libraries and library flags. +if AC_TRY_EVAL(ac_compile); then + # Parse the compiler output and extract the necessary + # objects, libraries and library flags. + + # Sentinel used to keep track of whether or not we are before + # the conftest object file. + pre_test_object_deps_done=no + + # The `*' in the case matches for architectures that use `case' in + # $output_verbose_cmd can trigger glob expansion during the loop + # eval without this substitution. + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` + + for p in `eval $output_verbose_link_cmd`; do + case $p in + + -L* | -R* | -l*) + # Some compilers place space between "-{L,R}" and the path. + # Remove the space. + if test $p = "-L" \ + || test $p = "-R"; then + prev=$p + continue + else + prev= + fi + + if test "$pre_test_object_deps_done" = no; then + case $p in + -L* | -R*) + # Internal compiler library paths should come after those + # provided the user. The postdeps already come after the + # user supplied libs so there is no need to process them. + if test -z "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" + else + _LT_AC_TAGVAR(compiler_lib_search_path, $1)="${_LT_AC_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" + fi + ;; + # The "-l" case would never come before the object being + # linked, so don't bother handling this case. + esac + else + if test -z "$_LT_AC_TAGVAR(postdeps, $1)"; then + _LT_AC_TAGVAR(postdeps, $1)="${prev}${p}" + else + _LT_AC_TAGVAR(postdeps, $1)="${_LT_AC_TAGVAR(postdeps, $1)} ${prev}${p}" + fi + fi + ;; + + *.$objext) + # This assumes that the test object file only shows up + # once in the compiler output. + if test "$p" = "conftest.$objext"; then + pre_test_object_deps_done=yes + continue + fi + + if test "$pre_test_object_deps_done" = no; then + if test -z "$_LT_AC_TAGVAR(predep_objects, $1)"; then + _LT_AC_TAGVAR(predep_objects, $1)="$p" + else + _LT_AC_TAGVAR(predep_objects, $1)="$_LT_AC_TAGVAR(predep_objects, $1) $p" + fi + else + if test -z "$_LT_AC_TAGVAR(postdep_objects, $1)"; then + _LT_AC_TAGVAR(postdep_objects, $1)="$p" + else + _LT_AC_TAGVAR(postdep_objects, $1)="$_LT_AC_TAGVAR(postdep_objects, $1) $p" + fi + fi + ;; + + *) ;; # Ignore the rest. + + esac + done + + # Clean up. + rm -f a.out a.exe +else + echo "libtool.m4: error: problem compiling $1 test program" +fi + +$rm -f confest.$objext + +# PORTME: override above test on systems where it is broken +ifelse([$1],[CXX], +[case $host_os in +interix3*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_AC_TAGVAR(predep_objects,$1)= + _LT_AC_TAGVAR(postdep_objects,$1)= + _LT_AC_TAGVAR(postdeps,$1)= + ;; + +solaris*) + case $cc_basename in + CC*) + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + _LT_AC_TAGVAR(postdeps,$1)='-lCstd -lCrun' + ;; + esac + ;; +esac +]) + +case " $_LT_AC_TAGVAR(postdeps, $1) " in +*" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; +esac +])# AC_LIBTOOL_POSTDEP_PREDEP + +# AC_LIBTOOL_LANG_F77_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG], [_LT_AC_LANG_F77_CONFIG(F77)]) +AC_DEFUN([_LT_AC_LANG_F77_CONFIG], +[AC_REQUIRE([AC_PROG_F77]) +AC_LANG_PUSH(Fortran 77) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Source file extension for f77 test sources. +ac_ext=f + +# Object file extension for compiled f77 test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code=" subroutine t\n return\n end\n" + +# Code to be used in simple link tests +lt_simple_link_test_code=" program t\n end\n" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${F77-"f77"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +_LT_AC_TAGVAR(GCC, $1)="$G77" +_LT_AC_TAGVAR(LD, $1)="$LD" + +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_F77_CONFIG + + +# AC_LIBTOOL_LANG_GCJ_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG], [_LT_AC_LANG_GCJ_CONFIG(GCJ)]) +AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG], +[AC_LANG_SAVE + +# Source file extension for Java test sources. +ac_ext=java + +# Object file extension for compiled Java test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="class foo {}\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${GCJ-"gcj"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# GCJ did not exist at the time GCC didn't implicitly link libc in. +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds + +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_GCJ_CONFIG + + +# AC_LIBTOOL_LANG_RC_CONFIG +# ------------------------- +# Ensure that the configuration vars for the Windows resource compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG], [_LT_AC_LANG_RC_CONFIG(RC)]) +AC_DEFUN([_LT_AC_LANG_RC_CONFIG], +[AC_LANG_SAVE + +# Source file extension for RC test sources. +ac_ext=rc + +# Object file extension for compiled RC test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' + +# Code to be used in simple link tests +lt_simple_link_test_code="$lt_simple_compile_test_code" + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC="$CC" +CC=${RC-"windres"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) +_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_RESTORE +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_RC_CONFIG + + +# AC_LIBTOOL_CONFIG([TAGNAME]) +# ---------------------------- +# If TAGNAME is not passed, then create an initial libtool script +# with a default configuration from the untagged config vars. Otherwise +# add code to config.status for appending the configuration named by +# TAGNAME from the matching tagged config vars. +AC_DEFUN([AC_LIBTOOL_CONFIG], +[# The else clause should only fire when bootstrapping the +# libtool distribution, otherwise you forgot to ship ltmain.sh +# with your package, and you will get complaints that there are +# no rules to generate ltmain.sh. +if test -f "$ltmain"; then + # See if we are running on zsh, and set the options which allow our commands through + # without removal of \ escapes. + if test -n "${ZSH_VERSION+set}" ; then + setopt NO_GLOB_SUBST + fi + # Now quote all the things that may contain metacharacters while being + # careful not to overquote the AC_SUBSTed values. We take copies of the + # variables and quote the copies for generation of the libtool script. + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ + SED SHELL STRIP \ + libname_spec library_names_spec soname_spec extract_expsyms_cmds \ + old_striplib striplib file_magic_cmd finish_cmds finish_eval \ + deplibs_check_method reload_flag reload_cmds need_locks \ + lt_cv_sys_global_symbol_pipe lt_cv_sys_global_symbol_to_cdecl \ + lt_cv_sys_global_symbol_to_c_name_address \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + old_postinstall_cmds old_postuninstall_cmds \ + _LT_AC_TAGVAR(compiler, $1) \ + _LT_AC_TAGVAR(CC, $1) \ + _LT_AC_TAGVAR(LD, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_static, $1) \ + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) \ + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1) \ + _LT_AC_TAGVAR(thread_safe_flag_spec, $1) \ + _LT_AC_TAGVAR(whole_archive_flag_spec, $1) \ + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) \ + _LT_AC_TAGVAR(old_archive_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) \ + _LT_AC_TAGVAR(predep_objects, $1) \ + _LT_AC_TAGVAR(postdep_objects, $1) \ + _LT_AC_TAGVAR(predeps, $1) \ + _LT_AC_TAGVAR(postdeps, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(archive_cmds, $1) \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ + _LT_AC_TAGVAR(postinstall_cmds, $1) \ + _LT_AC_TAGVAR(postuninstall_cmds, $1) \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) \ + _LT_AC_TAGVAR(allow_undefined_flag, $1) \ + _LT_AC_TAGVAR(no_undefined_flag, $1) \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) \ + _LT_AC_TAGVAR(hardcode_libdir_separator, $1) \ + _LT_AC_TAGVAR(hardcode_automatic, $1) \ + _LT_AC_TAGVAR(module_cmds, $1) \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) \ + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(exclude_expsyms, $1) \ + _LT_AC_TAGVAR(include_expsyms, $1); do + + case $var in + _LT_AC_TAGVAR(old_archive_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_new_cmds, $1) | \ + _LT_AC_TAGVAR(archive_cmds, $1) | \ + _LT_AC_TAGVAR(archive_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(module_cmds, $1) | \ + _LT_AC_TAGVAR(module_expsym_cmds, $1) | \ + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) | \ + _LT_AC_TAGVAR(export_symbols_cmds, $1) | \ + extract_expsyms_cmds | reload_cmds | finish_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "lt_$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case $lt_echo in + *'\[$]0 --fallback-echo"') + lt_echo=`$echo "X$lt_echo" | $Xsed -e 's/\\\\\\\[$]0 --fallback-echo"[$]/[$]0 --fallback-echo"/'` + ;; + esac + +ifelse([$1], [], + [cfgfile="${ofile}T" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + $rm -f "$cfgfile" + AC_MSG_NOTICE([creating $ofile])], + [cfgfile="$ofile"]) + + cat <<__EOF__ >> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program 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 +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext <<EOF +#ifdef __cplusplus +extern "C" { +#endif +char nm_test_var; +void nm_test_func(){} +#ifdef __cplusplus +} +#endif +int main(){nm_test_var='a';nm_test_func();return(0);} +EOF + + if AC_TRY_EVAL(ac_compile); then + # Now try to grab the symbols. + nlist=conftest.nm + if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat <<EOF > conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <<EOF >> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<EOF 1>&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach <jrb3@best.com> says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<EOF 1>&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include <windows.h> +# #undef WIN32_LEAN_AND_MEAN +# #include <stdio.h> +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include <cygwin/cygwin_dll.h> +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) + diff --git a/deps/libeio/autogen.sh b/deps/libeio/autogen.sh new file mode 100755 index 0000000000..bd3387c46c --- /dev/null +++ b/deps/libeio/autogen.sh @@ -0,0 +1,5 @@ +libtoolize +aclocal +automake --add-missing +autoconf +autoheader diff --git a/deps/libeio/config.h.in b/deps/libeio/config.h.in new file mode 100644 index 0000000000..5841743626 --- /dev/null +++ b/deps/libeio/config.h.in @@ -0,0 +1,73 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the <dlfcn.h> header file. */ +#undef HAVE_DLFCN_H + +/* fdatasync(2) is available */ +#undef HAVE_FDATASYNC + +/* futimes(2) is available */ +#undef HAVE_FUTIMES + +/* Define to 1 if you have the <inttypes.h> header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the <memory.h> header file. */ +#undef HAVE_MEMORY_H + +/* pread(2) and pwrite(2) are available */ +#undef HAVE_PREADWRITE + +/* readahead(2) is available (linux) */ +#undef HAVE_READAHEAD + +/* sendfile(2) is available and supported */ +#undef HAVE_SENDFILE + +/* Define to 1 if you have the <stdint.h> header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the <stdlib.h> header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the <strings.h> header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the <string.h> header file. */ +#undef HAVE_STRING_H + +/* sync_file_range(2) is available */ +#undef HAVE_SYNC_FILE_RANGE + +/* Define to 1 if you have the <sys/stat.h> header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the <sys/types.h> header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the <unistd.h> header file. */ +#undef HAVE_UNISTD_H + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION diff --git a/deps/libeio/configure.ac b/deps/libeio/configure.ac new file mode 100644 index 0000000000..f55f47acce --- /dev/null +++ b/deps/libeio/configure.ac @@ -0,0 +1,22 @@ +AC_PREREQ(2.59) +AC_INIT +AC_CONFIG_SRCDIR([eio.h]) +AC_CONFIG_HEADERS([config.h]) + +AM_INIT_AUTOMAKE(libeio,1.0) +AM_MAINTAINER_MODE +AC_PROG_LIBTOOL + +AC_PROG_CC + +if test "x$GCC" = xyes ; then + CFLAGS="$CFLAGS -O3" +fi + +dnl somebody will forgive me +CFLAGS="-D_GNU_SOURCE" + +m4_include([libeio.m4]) + +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/deps/libeio/demo.c b/deps/libeio/demo.c new file mode 100644 index 0000000000..439ae7f91b --- /dev/null +++ b/deps/libeio/demo.c @@ -0,0 +1,194 @@ +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <poll.h> +#include <string.h> +#include <assert.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "eio.h" + +int respipe [2]; + +void +want_poll (void) +{ + char dummy; + printf ("want_poll ()\n"); + write (respipe [1], &dummy, 1); +} + +void +done_poll (void) +{ + char dummy; + printf ("done_poll ()\n"); + read (respipe [0], &dummy, 1); +} + +void +event_loop (void) +{ + // an event loop. yeah. + struct pollfd pfd; + pfd.fd = respipe [0]; + pfd.events = POLLIN; + + printf ("\nentering event loop\n"); + while (eio_nreqs ()) + { + poll (&pfd, 1, -1); + printf ("eio_poll () = %d\n", eio_poll ()); + } + printf ("leaving event loop\n"); +} + +int +res_cb (eio_req *req) +{ + printf ("res_cb(%d|%s) = %d\n", req->type, req->data ? req->data : "?", EIO_RESULT (req)); + + if (req->result < 0) + abort (); + + return 0; +} + +int +readdir_cb (eio_req *req) +{ + char *buf = (char *)EIO_BUF (req); + + printf ("readdir_cb = %d\n", EIO_RESULT (req)); + + if (EIO_RESULT (req) < 0) + return 0; + + while (EIO_RESULT (req)--) + { + printf ("readdir = <%s>\n", buf); + buf += strlen (buf) + 1; + } + + return 0; +} + +int +stat_cb (eio_req *req) +{ + struct stat *buf = EIO_STAT_BUF (req); + + if (req->type == EIO_FSTAT) + printf ("fstat_cb = %d\n", EIO_RESULT (req)); + else + printf ("stat_cb(%s) = %d\n", EIO_PATH (req), EIO_RESULT (req)); + + if (!EIO_RESULT (req)) + printf ("stat size %d perm 0%o\n", buf->st_size, buf->st_mode & 0777); + + return 0; +} + +int +read_cb (eio_req *req) +{ + unsigned char *buf = (unsigned char *)EIO_BUF (req); + + printf ("read_cb = %d (%02x%02x%02x%02x %02x%02x%02x%02x)\n", + EIO_RESULT (req), + buf [0], buf [1], buf [2], buf [3], + buf [4], buf [5], buf [6], buf [7]); + + return 0; +} + +int last_fd; + +int +open_cb (eio_req *req) +{ + printf ("open_cb = %d\n", EIO_RESULT (req)); + + last_fd = EIO_RESULT (req); + + return 0; +} + +int +main (void) +{ + printf ("pipe ()\n"); + if (pipe (respipe)) abort (); + + printf ("eio_init ()\n"); + if (eio_init (want_poll, done_poll)) abort (); + + do + { + /* avoid relative paths yourself(!) */ + eio_mkdir ("eio-test-dir", 0777, 0, res_cb, "mkdir"); + eio_nop (0, res_cb, "nop"); + event_loop (); + + eio_stat ("eio-test-dir", 0, stat_cb, "stat"); + eio_lstat ("eio-test-dir", 0, stat_cb, "stat"); + eio_open ("eio-test-dir/eio-test-file", O_RDWR | O_CREAT, 0777, 0, open_cb, "open"); + eio_symlink ("test", "eio-test-dir/eio-symlink", 0, res_cb, "symlink"); + eio_mknod ("eio-test-dir/eio-fifo", S_IFIFO, 0, 0, res_cb, "mknod"); + event_loop (); + + eio_utime ("eio-test-dir", 12345.678, 23456.789, 0, res_cb, "utime"); + eio_futime (last_fd, 92345.678, 93456.789, 0, res_cb, "futime"); + eio_chown ("eio-test-dir", getuid (), getgid (), 0, res_cb, "chown"); + eio_fchown (last_fd, getuid (), getgid (), 0, res_cb, "fchown"); + eio_fchmod (last_fd, 0123, 0, res_cb, "fchmod"); + eio_readdir ("eio-test-dir", 0, readdir_cb, "readdir"); + eio_readdir ("/nonexistant", 0, readdir_cb, "readdir"); + eio_fstat (last_fd, 0, stat_cb, "stat"); + eio_write (last_fd, "test\nfail\n", 10, 4, 0, res_cb, "write"); + event_loop (); + + eio_read (last_fd, 0, 8, 0, EIO_PRI_DEFAULT, read_cb, "read"); + eio_readlink ("eio-test-dir/eio-symlink", 0, res_cb, "readlink"); + event_loop (); + + eio_dup2 (1, 2, EIO_PRI_DEFAULT, res_cb, "dup"); // dup stdout to stderr + eio_chmod ("eio-test-dir", 0765, 0, res_cb, "chmod"); + eio_ftruncate (last_fd, 9, 0, res_cb, "ftruncate"); + eio_fdatasync (last_fd, 0, res_cb, "fdatasync"); + eio_fsync (last_fd, 0, res_cb, "fsync"); + eio_sync (0, res_cb, "sync"); + eio_busy (0.5, 0, res_cb, "busy"); + event_loop (); + + eio_sendfile (1, last_fd, 4, 5, 0, res_cb, "sendfile"); // write "test\n" to stdout + eio_fstat (last_fd, 0, stat_cb, "stat"); + event_loop (); + + eio_truncate ("eio-test-dir/eio-test-file", 6, 0, res_cb, "truncate"); + eio_readahead (last_fd, 0, 64, 0, res_cb, "readahead"); + event_loop (); + + eio_close (last_fd, 0, res_cb, "close"); + eio_link ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-2", 0, res_cb, "link"); + event_loop (); + + eio_rename ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-renamed", 0, res_cb, "rename"); + event_loop (); + + eio_unlink ("eio-test-dir/eio-fifo", 0, res_cb, "unlink"); + eio_unlink ("eio-test-dir/eio-symlink", 0, res_cb, "unlink"); + eio_unlink ("eio-test-dir/eio-test-file-2", 0, res_cb, "unlink"); + eio_unlink ("eio-test-dir/eio-test-file-renamed", 0, res_cb, "unlink"); + event_loop (); + + eio_rmdir ("eio-test-dir", 0, res_cb, "rmdir"); + event_loop (); + } + while (0); + + return 0; +} + diff --git a/deps/libeio/eio.3 b/deps/libeio/eio.3 new file mode 100644 index 0000000000..ec5bde33e1 --- /dev/null +++ b/deps/libeio/eio.3 @@ -0,0 +1,3428 @@ +.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.05) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.ie \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.el \{\ +. de IX +.. +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "LIBEIO 3" +.TH LIBEIO 3 "2008-05-11" "libeio-1.0" "libeio - truly asynchronous POSIX I/O" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +libev \- a high performance full\-featured event loop written in C +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& #include <ev.h> +.Ve +.Sh "\s-1EXAMPLE\s0 \s-1PROGRAM\s0" +.IX Subsection "EXAMPLE PROGRAM" +.Vb 2 +\& // a single header file is required +\& #include <ev.h> +\& +\& // every watcher type has its own typedef\*(Aqd struct +\& // with the name ev_<type> +\& ev_io stdin_watcher; +\& ev_timer timeout_watcher; +\& +\& // all watcher callbacks have a similar signature +\& // this callback is called when data is readable on stdin +\& static void +\& stdin_cb (EV_P_ struct ev_io *w, int revents) +\& { +\& puts ("stdin ready"); +\& // for one\-shot events, one must manually stop the watcher +\& // with its corresponding stop function. +\& ev_io_stop (EV_A_ w); +\& +\& // this causes all nested ev_loop\*(Aqs to stop iterating +\& ev_unloop (EV_A_ EVUNLOOP_ALL); +\& } +\& +\& // another callback, this time for a time\-out +\& static void +\& timeout_cb (EV_P_ struct ev_timer *w, int revents) +\& { +\& puts ("timeout"); +\& // this causes the innermost ev_loop to stop iterating +\& ev_unloop (EV_A_ EVUNLOOP_ONE); +\& } +\& +\& int +\& main (void) +\& { +\& // use the default event loop unless you have special needs +\& struct ev_loop *loop = ev_default_loop (0); +\& +\& // initialise an io watcher, then start it +\& // this one will watch for stdin to become readable +\& ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); +\& ev_io_start (loop, &stdin_watcher); +\& +\& // initialise a timer watcher, then start it +\& // simple non\-repeating 5.5 second timeout +\& ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); +\& ev_timer_start (loop, &timeout_watcher); +\& +\& // now wait for events to arrive +\& ev_loop (loop, 0); +\& +\& // unloop was called, so exit +\& return 0; +\& } +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +The newest version of this document is also available as an html-formatted +web page you might find easier to navigate when reading it for the first +time: <http://cvs.schmorp.de/libev/ev.html>. +.PP +Libev is an event loop: you register interest in certain events (such as a +file descriptor being readable or a timeout occurring), and it will manage +these event sources and provide your program with events. +.PP +To do this, it must take more or less complete control over your process +(or thread) by executing the \fIevent loop\fR handler, and will then +communicate events via a callback mechanism. +.PP +You register interest in certain events by registering so-called \fIevent +watchers\fR, which are relatively small C structures you initialise with the +details of the event, and then hand it over to libev by \fIstarting\fR the +watcher. +.Sh "\s-1FEATURES\s0" +.IX Subsection "FEATURES" +Libev supports \f(CW\*(C`select\*(C'\fR, \f(CW\*(C`poll\*(C'\fR, the Linux-specific \f(CW\*(C`epoll\*(C'\fR, the +BSD-specific \f(CW\*(C`kqueue\*(C'\fR and the Solaris-specific event port mechanisms +for file descriptor events (\f(CW\*(C`ev_io\*(C'\fR), the Linux \f(CW\*(C`inotify\*(C'\fR interface +(for \f(CW\*(C`ev_stat\*(C'\fR), relative timers (\f(CW\*(C`ev_timer\*(C'\fR), absolute timers +with customised rescheduling (\f(CW\*(C`ev_periodic\*(C'\fR), synchronous signals +(\f(CW\*(C`ev_signal\*(C'\fR), process status change events (\f(CW\*(C`ev_child\*(C'\fR), and event +watchers dealing with the event loop mechanism itself (\f(CW\*(C`ev_idle\*(C'\fR, +\&\f(CW\*(C`ev_embed\*(C'\fR, \f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR watchers) as well as +file watchers (\f(CW\*(C`ev_stat\*(C'\fR) and even limited support for fork events +(\f(CW\*(C`ev_fork\*(C'\fR). +.PP +It also is quite fast (see this +benchmark comparing it to libevent +for example). +.Sh "\s-1CONVENTIONS\s0" +.IX Subsection "CONVENTIONS" +Libev is very configurable. In this manual the default (and most common) +configuration will be described, which supports multiple event loops. For +more info about various configuration options please have a look at +\&\fB\s-1EMBED\s0\fR section in this manual. If libev was configured without support +for multiple event loops, then all functions taking an initial argument of +name \f(CW\*(C`loop\*(C'\fR (which is always of type \f(CW\*(C`struct ev_loop *\*(C'\fR) will not have +this argument. +.Sh "\s-1TIME\s0 \s-1REPRESENTATION\s0" +.IX Subsection "TIME REPRESENTATION" +Libev represents time as a single floating point number, representing the +(fractional) number of seconds since the (\s-1POSIX\s0) epoch (somewhere near +the beginning of 1970, details are complicated, don't ask). This type is +called \f(CW\*(C`ev_tstamp\*(C'\fR, which is what you should use too. It usually aliases +to the \f(CW\*(C`double\*(C'\fR type in C, and when you need to do any calculations on +it, you should treat it as some floatingpoint value. Unlike the name +component \f(CW\*(C`stamp\*(C'\fR might indicate, it is also used for time differences +throughout libev. +.SH "GLOBAL FUNCTIONS" +.IX Header "GLOBAL FUNCTIONS" +These functions can be called anytime, even before initialising the +library in any way. +.IP "ev_tstamp ev_time ()" 4 +.IX Item "ev_tstamp ev_time ()" +Returns the current time as libev would use it. Please note that the +\&\f(CW\*(C`ev_now\*(C'\fR function is usually faster and also often returns the timestamp +you actually want to know. +.IP "ev_sleep (ev_tstamp interval)" 4 +.IX Item "ev_sleep (ev_tstamp interval)" +Sleep for the given interval: The current thread will be blocked until +either it is interrupted or the given time interval has passed. Basically +this is a subsecond-resolution \f(CW\*(C`sleep ()\*(C'\fR. +.IP "int ev_version_major ()" 4 +.IX Item "int ev_version_major ()" +.PD 0 +.IP "int ev_version_minor ()" 4 +.IX Item "int ev_version_minor ()" +.PD +You can find out the major and minor \s-1ABI\s0 version numbers of the library +you linked against by calling the functions \f(CW\*(C`ev_version_major\*(C'\fR and +\&\f(CW\*(C`ev_version_minor\*(C'\fR. If you want, you can compare against the global +symbols \f(CW\*(C`EV_VERSION_MAJOR\*(C'\fR and \f(CW\*(C`EV_VERSION_MINOR\*(C'\fR, which specify the +version of the library your program was compiled against. +.Sp +These version numbers refer to the \s-1ABI\s0 version of the library, not the +release version. +.Sp +Usually, it's a good idea to terminate if the major versions mismatch, +as this indicates an incompatible change. Minor versions are usually +compatible to older versions, so a larger minor version alone is usually +not a problem. +.Sp +Example: Make sure we haven't accidentally been linked against the wrong +version. +.Sp +.Vb 3 +\& assert (("libev version mismatch", +\& ev_version_major () == EV_VERSION_MAJOR +\& && ev_version_minor () >= EV_VERSION_MINOR)); +.Ve +.IP "unsigned int ev_supported_backends ()" 4 +.IX Item "unsigned int ev_supported_backends ()" +Return the set of all backends (i.e. their corresponding \f(CW\*(C`EV_BACKEND_*\*(C'\fR +value) compiled into this binary of libev (independent of their +availability on the system you are running on). See \f(CW\*(C`ev_default_loop\*(C'\fR for +a description of the set values. +.Sp +Example: make sure we have the epoll method, because yeah this is cool and +a must have and can we have a torrent of it please!!!11 +.Sp +.Vb 2 +\& assert (("sorry, no epoll, no sex", +\& ev_supported_backends () & EVBACKEND_EPOLL)); +.Ve +.IP "unsigned int ev_recommended_backends ()" 4 +.IX Item "unsigned int ev_recommended_backends ()" +Return the set of all backends compiled into this binary of libev and also +recommended for this platform. This set is often smaller than the one +returned by \f(CW\*(C`ev_supported_backends\*(C'\fR, as for example kqueue is broken on +most BSDs and will not be autodetected unless you explicitly request it +(assuming you know what you are doing). This is the set of backends that +libev will probe for if you specify no backends explicitly. +.IP "unsigned int ev_embeddable_backends ()" 4 +.IX Item "unsigned int ev_embeddable_backends ()" +Returns the set of backends that are embeddable in other event loops. This +is the theoretical, all-platform, value. To find which backends +might be supported on the current system, you would need to look at +\&\f(CW\*(C`ev_embeddable_backends () & ev_supported_backends ()\*(C'\fR, likewise for +recommended ones. +.Sp +See the description of \f(CW\*(C`ev_embed\*(C'\fR watchers for more info. +.IP "ev_set_allocator (void *(*cb)(void *ptr, long size))" 4 +.IX Item "ev_set_allocator (void *(*cb)(void *ptr, long size))" +Sets the allocation function to use (the prototype is similar \- the +semantics are identical to the \f(CW\*(C`realloc\*(C'\fR C89/SuS/POSIX function). It is +used to allocate and free memory (no surprises here). If it returns zero +when memory needs to be allocated (\f(CW\*(C`size != 0\*(C'\fR), the library might abort +or take some potentially destructive action. +.Sp +Since some systems (at least OpenBSD and Darwin) fail to implement +correct \f(CW\*(C`realloc\*(C'\fR semantics, libev will use a wrapper around the system +\&\f(CW\*(C`realloc\*(C'\fR and \f(CW\*(C`free\*(C'\fR functions by default. +.Sp +You could override this function in high-availability programs to, say, +free some memory if it cannot allocate memory, to use a special allocator, +or even to sleep a while and retry until some memory is available. +.Sp +Example: Replace the libev allocator with one that waits a bit and then +retries (example requires a standards-compliant \f(CW\*(C`realloc\*(C'\fR). +.Sp +.Vb 6 +\& static void * +\& persistent_realloc (void *ptr, size_t size) +\& { +\& for (;;) +\& { +\& void *newptr = realloc (ptr, size); +\& +\& if (newptr) +\& return newptr; +\& +\& sleep (60); +\& } +\& } +\& +\& ... +\& ev_set_allocator (persistent_realloc); +.Ve +.IP "ev_set_syserr_cb (void (*cb)(const char *msg));" 4 +.IX Item "ev_set_syserr_cb (void (*cb)(const char *msg));" +Set the callback function to call on a retryable syscall error (such +as failed select, poll, epoll_wait). The message is a printable string +indicating the system call or subsystem causing the problem. If this +callback is set, then libev will expect it to remedy the sitution, no +matter what, when it returns. That is, libev will generally retry the +requested operation, or, if the condition doesn't go away, do bad stuff +(such as abort). +.Sp +Example: This is basically the same thing that libev does internally, too. +.Sp +.Vb 6 +\& static void +\& fatal_error (const char *msg) +\& { +\& perror (msg); +\& abort (); +\& } +\& +\& ... +\& ev_set_syserr_cb (fatal_error); +.Ve +.SH "FUNCTIONS CONTROLLING THE EVENT LOOP" +.IX Header "FUNCTIONS CONTROLLING THE EVENT LOOP" +An event loop is described by a \f(CW\*(C`struct ev_loop *\*(C'\fR. The library knows two +types of such loops, the \fIdefault\fR loop, which supports signals and child +events, and dynamically created loops which do not. +.IP "struct ev_loop *ev_default_loop (unsigned int flags)" 4 +.IX Item "struct ev_loop *ev_default_loop (unsigned int flags)" +This will initialise the default event loop if it hasn't been initialised +yet and return it. If the default loop could not be initialised, returns +false. If it already was initialised it simply returns it (and ignores the +flags. If that is troubling you, check \f(CW\*(C`ev_backend ()\*(C'\fR afterwards). +.Sp +If you don't know what event loop to use, use the one returned from this +function. +.Sp +Note that this function is \fInot\fR thread-safe, so if you want to use it +from multiple threads, you have to lock (note also that this is unlikely, +as loops cannot bes hared easily between threads anyway). +.Sp +The default loop is the only loop that can handle \f(CW\*(C`ev_signal\*(C'\fR and +\&\f(CW\*(C`ev_child\*(C'\fR watchers, and to do this, it always registers a handler +for \f(CW\*(C`SIGCHLD\*(C'\fR. If this is a problem for your app you can either +create a dynamic loop with \f(CW\*(C`ev_loop_new\*(C'\fR that doesn't do that, or you +can simply overwrite the \f(CW\*(C`SIGCHLD\*(C'\fR signal handler \fIafter\fR calling +\&\f(CW\*(C`ev_default_init\*(C'\fR. +.Sp +The flags argument can be used to specify special behaviour or specific +backends to use, and is usually specified as \f(CW0\fR (or \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). +.Sp +The following flags are supported: +.RS 4 +.ie n .IP """EVFLAG_AUTO""" 4 +.el .IP "\f(CWEVFLAG_AUTO\fR" 4 +.IX Item "EVFLAG_AUTO" +The default flags value. Use this if you have no clue (it's the right +thing, believe me). +.ie n .IP """EVFLAG_NOENV""" 4 +.el .IP "\f(CWEVFLAG_NOENV\fR" 4 +.IX Item "EVFLAG_NOENV" +If this flag bit is ored into the flag value (or the program runs setuid +or setgid) then libev will \fInot\fR look at the environment variable +\&\f(CW\*(C`LIBEV_FLAGS\*(C'\fR. Otherwise (the default), this environment variable will +override the flags completely if it is found in the environment. This is +useful to try out specific backends to test their performance, or to work +around bugs. +.ie n .IP """EVFLAG_FORKCHECK""" 4 +.el .IP "\f(CWEVFLAG_FORKCHECK\fR" 4 +.IX Item "EVFLAG_FORKCHECK" +Instead of calling \f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR manually after +a fork, you can also make libev check for a fork in each iteration by +enabling this flag. +.Sp +This works by calling \f(CW\*(C`getpid ()\*(C'\fR on every iteration of the loop, +and thus this might slow down your event loop if you do a lot of loop +iterations and little real work, but is usually not noticeable (on my +GNU/Linux system for example, \f(CW\*(C`getpid\*(C'\fR is actually a simple 5\-insn sequence +without a syscall and thus \fIvery\fR fast, but my GNU/Linux system also has +\&\f(CW\*(C`pthread_atfork\*(C'\fR which is even faster). +.Sp +The big advantage of this flag is that you can forget about fork (and +forget about forgetting to tell libev about forking) when you use this +flag. +.Sp +This flag setting cannot be overriden or specified in the \f(CW\*(C`LIBEV_FLAGS\*(C'\fR +environment variable. +.ie n .IP """EVBACKEND_SELECT"" (value 1, portable select backend)" 4 +.el .IP "\f(CWEVBACKEND_SELECT\fR (value 1, portable select backend)" 4 +.IX Item "EVBACKEND_SELECT (value 1, portable select backend)" +This is your standard \fIselect\fR\|(2) backend. Not \fIcompletely\fR standard, as +libev tries to roll its own fd_set with no limits on the number of fds, +but if that fails, expect a fairly low limit on the number of fds when +using this backend. It doesn't scale too well (O(highest_fd)), but its +usually the fastest backend for a low number of (low-numbered :) fds. +.Sp +To get good performance out of this backend you need a high amount of +parallelity (most of the file descriptors should be busy). If you are +writing a server, you should \f(CW\*(C`accept ()\*(C'\fR in a loop to accept as many +connections as possible during one iteration. You might also want to have +a look at \f(CW\*(C`ev_set_io_collect_interval ()\*(C'\fR to increase the amount of +readyness notifications you get per iteration. +.ie n .IP """EVBACKEND_POLL"" (value 2, poll backend, available everywhere except on windows)" 4 +.el .IP "\f(CWEVBACKEND_POLL\fR (value 2, poll backend, available everywhere except on windows)" 4 +.IX Item "EVBACKEND_POLL (value 2, poll backend, available everywhere except on windows)" +And this is your standard \fIpoll\fR\|(2) backend. It's more complicated +than select, but handles sparse fds better and has no artificial +limit on the number of fds you can use (except it will slow down +considerably with a lot of inactive fds). It scales similarly to select, +i.e. O(total_fds). See the entry for \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR, above, for +performance tips. +.ie n .IP """EVBACKEND_EPOLL"" (value 4, Linux)" 4 +.el .IP "\f(CWEVBACKEND_EPOLL\fR (value 4, Linux)" 4 +.IX Item "EVBACKEND_EPOLL (value 4, Linux)" +For few fds, this backend is a bit little slower than poll and select, +but it scales phenomenally better. While poll and select usually scale +like O(total_fds) where n is the total number of fds (or the highest fd), +epoll scales either O(1) or O(active_fds). The epoll design has a number +of shortcomings, such as silently dropping events in some hard-to-detect +cases and requiring a syscall per fd change, no fork support and bad +support for dup. +.Sp +While stopping, setting and starting an I/O watcher in the same iteration +will result in some caching, there is still a syscall per such incident +(because the fd could point to a different file description now), so its +best to avoid that. Also, \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors might not work +very well if you register events for both fds. +.Sp +Please note that epoll sometimes generates spurious notifications, so you +need to use non-blocking I/O or other means to avoid blocking when no data +(or space) is available. +.Sp +Best performance from this backend is achieved by not unregistering all +watchers for a file descriptor until it has been closed, if possible, i.e. +keep at least one watcher active per fd at all times. +.Sp +While nominally embeddeble in other event loops, this feature is broken in +all kernel versions tested so far. +.ie n .IP """EVBACKEND_KQUEUE"" (value 8, most \s-1BSD\s0 clones)" 4 +.el .IP "\f(CWEVBACKEND_KQUEUE\fR (value 8, most \s-1BSD\s0 clones)" 4 +.IX Item "EVBACKEND_KQUEUE (value 8, most BSD clones)" +Kqueue deserves special mention, as at the time of this writing, it +was broken on all BSDs except NetBSD (usually it doesn't work reliably +with anything but sockets and pipes, except on Darwin, where of course +it's completely useless). For this reason it's not being \*(L"autodetected\*(R" +unless you explicitly specify it explicitly in the flags (i.e. using +\&\f(CW\*(C`EVBACKEND_KQUEUE\*(C'\fR) or libev was compiled on a known-to-be-good (\-enough) +system like NetBSD. +.Sp +You still can embed kqueue into a normal poll or select backend and use it +only for sockets (after having made sure that sockets work with kqueue on +the target platform). See \f(CW\*(C`ev_embed\*(C'\fR watchers for more info. +.Sp +It scales in the same way as the epoll backend, but the interface to the +kernel is more efficient (which says nothing about its actual speed, of +course). While stopping, setting and starting an I/O watcher does never +cause an extra syscall as with \f(CW\*(C`EVBACKEND_EPOLL\*(C'\fR, it still adds up to +two event changes per incident, support for \f(CW\*(C`fork ()\*(C'\fR is very bad and it +drops fds silently in similarly hard-to-detect cases. +.Sp +This backend usually performs well under most conditions. +.Sp +While nominally embeddable in other event loops, this doesn't work +everywhere, so you might need to test for this. And since it is broken +almost everywhere, you should only use it when you have a lot of sockets +(for which it usually works), by embedding it into another event loop +(e.g. \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR) and using it only for +sockets. +.ie n .IP """EVBACKEND_DEVPOLL"" (value 16, Solaris 8)" 4 +.el .IP "\f(CWEVBACKEND_DEVPOLL\fR (value 16, Solaris 8)" 4 +.IX Item "EVBACKEND_DEVPOLL (value 16, Solaris 8)" +This is not implemented yet (and might never be, unless you send me an +implementation). According to reports, \f(CW\*(C`/dev/poll\*(C'\fR only supports sockets +and is not embeddable, which would limit the usefulness of this backend +immensely. +.ie n .IP """EVBACKEND_PORT"" (value 32, Solaris 10)" 4 +.el .IP "\f(CWEVBACKEND_PORT\fR (value 32, Solaris 10)" 4 +.IX Item "EVBACKEND_PORT (value 32, Solaris 10)" +This uses the Solaris 10 event port mechanism. As with everything on Solaris, +it's really slow, but it still scales very well (O(active_fds)). +.Sp +Please note that solaris event ports can deliver a lot of spurious +notifications, so you need to use non-blocking I/O or other means to avoid +blocking when no data (or space) is available. +.Sp +While this backend scales well, it requires one system call per active +file descriptor per loop iteration. For small and medium numbers of file +descriptors a \*(L"slow\*(R" \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR backend +might perform better. +.Sp +On the positive side, ignoring the spurious readyness notifications, this +backend actually performed to specification in all tests and is fully +embeddable, which is a rare feat among the OS-specific backends. +.ie n .IP """EVBACKEND_ALL""" 4 +.el .IP "\f(CWEVBACKEND_ALL\fR" 4 +.IX Item "EVBACKEND_ALL" +Try all backends (even potentially broken ones that wouldn't be tried +with \f(CW\*(C`EVFLAG_AUTO\*(C'\fR). Since this is a mask, you can do stuff such as +\&\f(CW\*(C`EVBACKEND_ALL & ~EVBACKEND_KQUEUE\*(C'\fR. +.Sp +It is definitely not recommended to use this flag. +.RE +.RS 4 +.Sp +If one or more of these are ored into the flags value, then only these +backends will be tried (in the reverse order as listed here). If none are +specified, all backends in \f(CW\*(C`ev_recommended_backends ()\*(C'\fR will be tried. +.Sp +The most typical usage is like this: +.Sp +.Vb 2 +\& if (!ev_default_loop (0)) +\& fatal ("could not initialise libev, bad $LIBEV_FLAGS in environment?"); +.Ve +.Sp +Restrict libev to the select and poll backends, and do not allow +environment settings to be taken into account: +.Sp +.Vb 1 +\& ev_default_loop (EVBACKEND_POLL | EVBACKEND_SELECT | EVFLAG_NOENV); +.Ve +.Sp +Use whatever libev has to offer, but make sure that kqueue is used if +available (warning, breaks stuff, best use only with your own private +event loop and only if you know the \s-1OS\s0 supports your types of fds): +.Sp +.Vb 1 +\& ev_default_loop (ev_recommended_backends () | EVBACKEND_KQUEUE); +.Ve +.RE +.IP "struct ev_loop *ev_loop_new (unsigned int flags)" 4 +.IX Item "struct ev_loop *ev_loop_new (unsigned int flags)" +Similar to \f(CW\*(C`ev_default_loop\*(C'\fR, but always creates a new event loop that is +always distinct from the default loop. Unlike the default loop, it cannot +handle signal and child watchers, and attempts to do so will be greeted by +undefined behaviour (or a failed assertion if assertions are enabled). +.Sp +Note that this function \fIis\fR thread-safe, and the recommended way to use +libev with threads is indeed to create one loop per thread, and using the +default loop in the \*(L"main\*(R" or \*(L"initial\*(R" thread. +.Sp +Example: Try to create a event loop that uses epoll and nothing else. +.Sp +.Vb 3 +\& struct ev_loop *epoller = ev_loop_new (EVBACKEND_EPOLL | EVFLAG_NOENV); +\& if (!epoller) +\& fatal ("no epoll found here, maybe it hides under your chair"); +.Ve +.IP "ev_default_destroy ()" 4 +.IX Item "ev_default_destroy ()" +Destroys the default loop again (frees all memory and kernel state +etc.). None of the active event watchers will be stopped in the normal +sense, so e.g. \f(CW\*(C`ev_is_active\*(C'\fR might still return true. It is your +responsibility to either stop all watchers cleanly yoursef \fIbefore\fR +calling this function, or cope with the fact afterwards (which is usually +the easiest thing, you can just ignore the watchers and/or \f(CW\*(C`free ()\*(C'\fR them +for example). +.Sp +Note that certain global state, such as signal state, will not be freed by +this function, and related watchers (such as signal and child watchers) +would need to be stopped manually. +.Sp +In general it is not advisable to call this function except in the +rare occasion where you really need to free e.g. the signal handling +pipe fds. If you need dynamically allocated loops it is better to use +\&\f(CW\*(C`ev_loop_new\*(C'\fR and \f(CW\*(C`ev_loop_destroy\*(C'\fR). +.IP "ev_loop_destroy (loop)" 4 +.IX Item "ev_loop_destroy (loop)" +Like \f(CW\*(C`ev_default_destroy\*(C'\fR, but destroys an event loop created by an +earlier call to \f(CW\*(C`ev_loop_new\*(C'\fR. +.IP "ev_default_fork ()" 4 +.IX Item "ev_default_fork ()" +This function sets a flag that causes subsequent \f(CW\*(C`ev_loop\*(C'\fR iterations +to reinitialise the kernel state for backends that have one. Despite the +name, you can call it anytime, but it makes most sense after forking, in +the child process (or both child and parent, but that again makes little +sense). You \fImust\fR call it in the child before using any of the libev +functions, and it will only take effect at the next \f(CW\*(C`ev_loop\*(C'\fR iteration. +.Sp +On the other hand, you only need to call this function in the child +process if and only if you want to use the event library in the child. If +you just fork+exec, you don't have to call it at all. +.Sp +The function itself is quite fast and it's usually not a problem to call +it just in case after a fork. To make this easy, the function will fit in +quite nicely into a call to \f(CW\*(C`pthread_atfork\*(C'\fR: +.Sp +.Vb 1 +\& pthread_atfork (0, 0, ev_default_fork); +.Ve +.IP "ev_loop_fork (loop)" 4 +.IX Item "ev_loop_fork (loop)" +Like \f(CW\*(C`ev_default_fork\*(C'\fR, but acts on an event loop created by +\&\f(CW\*(C`ev_loop_new\*(C'\fR. Yes, you have to call this on every allocated event loop +after fork, and how you do this is entirely your own problem. +.IP "int ev_is_default_loop (loop)" 4 +.IX Item "int ev_is_default_loop (loop)" +Returns true when the given loop actually is the default loop, false otherwise. +.IP "unsigned int ev_loop_count (loop)" 4 +.IX Item "unsigned int ev_loop_count (loop)" +Returns the count of loop iterations for the loop, which is identical to +the number of times libev did poll for new events. It starts at \f(CW0\fR and +happily wraps around with enough iterations. +.Sp +This value can sometimes be useful as a generation counter of sorts (it +\&\*(L"ticks\*(R" the number of loop iterations), as it roughly corresponds with +\&\f(CW\*(C`ev_prepare\*(C'\fR and \f(CW\*(C`ev_check\*(C'\fR calls. +.IP "unsigned int ev_backend (loop)" 4 +.IX Item "unsigned int ev_backend (loop)" +Returns one of the \f(CW\*(C`EVBACKEND_*\*(C'\fR flags indicating the event backend in +use. +.IP "ev_tstamp ev_now (loop)" 4 +.IX Item "ev_tstamp ev_now (loop)" +Returns the current \*(L"event loop time\*(R", which is the time the event loop +received events and started processing them. This timestamp does not +change as long as callbacks are being processed, and this is also the base +time used for relative timers. You can treat it as the timestamp of the +event occurring (or more correctly, libev finding out about it). +.IP "ev_loop (loop, int flags)" 4 +.IX Item "ev_loop (loop, int flags)" +Finally, this is it, the event handler. This function usually is called +after you initialised all your watchers and you want to start handling +events. +.Sp +If the flags argument is specified as \f(CW0\fR, it will not return until +either no event watchers are active anymore or \f(CW\*(C`ev_unloop\*(C'\fR was called. +.Sp +Please note that an explicit \f(CW\*(C`ev_unloop\*(C'\fR is usually better than +relying on all watchers to be stopped when deciding when a program has +finished (especially in interactive programs), but having a program that +automatically loops as long as it has to and no longer by virtue of +relying on its watchers stopping correctly is a thing of beauty. +.Sp +A flags value of \f(CW\*(C`EVLOOP_NONBLOCK\*(C'\fR will look for new events, will handle +those events and any outstanding ones, but will not block your process in +case there are no events and will return after one iteration of the loop. +.Sp +A flags value of \f(CW\*(C`EVLOOP_ONESHOT\*(C'\fR will look for new events (waiting if +neccessary) and will handle those and any outstanding ones. It will block +your process until at least one new event arrives, and will return after +one iteration of the loop. This is useful if you are waiting for some +external event in conjunction with something not expressible using other +libev watchers. However, a pair of \f(CW\*(C`ev_prepare\*(C'\fR/\f(CW\*(C`ev_check\*(C'\fR watchers is +usually a better approach for this kind of thing. +.Sp +Here are the gory details of what \f(CW\*(C`ev_loop\*(C'\fR does: +.Sp +.Vb 10 +\& \- Before the first iteration, call any pending watchers. +\& * If EVFLAG_FORKCHECK was used, check for a fork. +\& \- If a fork was detected, queue and call all fork watchers. +\& \- Queue and call all prepare watchers. +\& \- If we have been forked, recreate the kernel state. +\& \- Update the kernel state with all outstanding changes. +\& \- Update the "event loop time". +\& \- Calculate for how long to sleep or block, if at all +\& (active idle watchers, EVLOOP_NONBLOCK or not having +\& any active watchers at all will result in not sleeping). +\& \- Sleep if the I/O and timer collect interval say so. +\& \- Block the process, waiting for any events. +\& \- Queue all outstanding I/O (fd) events. +\& \- Update the "event loop time" and do time jump handling. +\& \- Queue all outstanding timers. +\& \- Queue all outstanding periodics. +\& \- If no events are pending now, queue all idle watchers. +\& \- Queue all check watchers. +\& \- Call all queued watchers in reverse order (i.e. check watchers first). +\& Signals and child watchers are implemented as I/O watchers, and will +\& be handled here by queueing them when their watcher gets executed. +\& \- If ev_unloop has been called, or EVLOOP_ONESHOT or EVLOOP_NONBLOCK +\& were used, or there are no active watchers, return, otherwise +\& continue with step *. +.Ve +.Sp +Example: Queue some jobs and then loop until no events are outstanding +anymore. +.Sp +.Vb 4 +\& ... queue jobs here, make sure they register event watchers as long +\& ... as they still have work to do (even an idle watcher will do..) +\& ev_loop (my_loop, 0); +\& ... jobs done. yeah! +.Ve +.IP "ev_unloop (loop, how)" 4 +.IX Item "ev_unloop (loop, how)" +Can be used to make a call to \f(CW\*(C`ev_loop\*(C'\fR return early (but only after it +has processed all outstanding events). The \f(CW\*(C`how\*(C'\fR argument must be either +\&\f(CW\*(C`EVUNLOOP_ONE\*(C'\fR, which will make the innermost \f(CW\*(C`ev_loop\*(C'\fR call return, or +\&\f(CW\*(C`EVUNLOOP_ALL\*(C'\fR, which will make all nested \f(CW\*(C`ev_loop\*(C'\fR calls return. +.Sp +This \*(L"unloop state\*(R" will be cleared when entering \f(CW\*(C`ev_loop\*(C'\fR again. +.IP "ev_ref (loop)" 4 +.IX Item "ev_ref (loop)" +.PD 0 +.IP "ev_unref (loop)" 4 +.IX Item "ev_unref (loop)" +.PD +Ref/unref can be used to add or remove a reference count on the event +loop: Every watcher keeps one reference, and as long as the reference +count is nonzero, \f(CW\*(C`ev_loop\*(C'\fR will not return on its own. If you have +a watcher you never unregister that should not keep \f(CW\*(C`ev_loop\*(C'\fR from +returning, \fIev_unref()\fR after starting, and \fIev_ref()\fR before stopping it. For +example, libev itself uses this for its internal signal pipe: It is not +visible to the libev user and should not keep \f(CW\*(C`ev_loop\*(C'\fR from exiting if +no event watchers registered by it are active. It is also an excellent +way to do this for generic recurring timers or from within third-party +libraries. Just remember to \fIunref after start\fR and \fIref before stop\fR +(but only if the watcher wasn't active before, or was active before, +respectively). +.Sp +Example: Create a signal watcher, but keep it from keeping \f(CW\*(C`ev_loop\*(C'\fR +running when nothing else is active. +.Sp +.Vb 4 +\& struct ev_signal exitsig; +\& ev_signal_init (&exitsig, sig_cb, SIGINT); +\& ev_signal_start (loop, &exitsig); +\& evf_unref (loop); +.Ve +.Sp +Example: For some weird reason, unregister the above signal handler again. +.Sp +.Vb 2 +\& ev_ref (loop); +\& ev_signal_stop (loop, &exitsig); +.Ve +.IP "ev_set_io_collect_interval (loop, ev_tstamp interval)" 4 +.IX Item "ev_set_io_collect_interval (loop, ev_tstamp interval)" +.PD 0 +.IP "ev_set_timeout_collect_interval (loop, ev_tstamp interval)" 4 +.IX Item "ev_set_timeout_collect_interval (loop, ev_tstamp interval)" +.PD +These advanced functions influence the time that libev will spend waiting +for events. Both are by default \f(CW0\fR, meaning that libev will try to +invoke timer/periodic callbacks and I/O callbacks with minimum latency. +.Sp +Setting these to a higher value (the \f(CW\*(C`interval\*(C'\fR \fImust\fR be >= \f(CW0\fR) +allows libev to delay invocation of I/O and timer/periodic callbacks to +increase efficiency of loop iterations. +.Sp +The background is that sometimes your program runs just fast enough to +handle one (or very few) event(s) per loop iteration. While this makes +the program responsive, it also wastes a lot of \s-1CPU\s0 time to poll for new +events, especially with backends like \f(CW\*(C`select ()\*(C'\fR which have a high +overhead for the actual polling but can deliver many events at once. +.Sp +By setting a higher \fIio collect interval\fR you allow libev to spend more +time collecting I/O events, so you can handle more events per iteration, +at the cost of increasing latency. Timeouts (both \f(CW\*(C`ev_periodic\*(C'\fR and +\&\f(CW\*(C`ev_timer\*(C'\fR) will be not affected. Setting this to a non-null value will +introduce an additional \f(CW\*(C`ev_sleep ()\*(C'\fR call into most loop iterations. +.Sp +Likewise, by setting a higher \fItimeout collect interval\fR you allow libev +to spend more time collecting timeouts, at the expense of increased +latency (the watcher callback will be called later). \f(CW\*(C`ev_io\*(C'\fR watchers +will not be affected. Setting this to a non-null value will not introduce +any overhead in libev. +.Sp +Many (busy) programs can usually benefit by setting the io collect +interval to a value near \f(CW0.1\fR or so, which is often enough for +interactive servers (of course not for games), likewise for timeouts. It +usually doesn't make much sense to set it to a lower value than \f(CW0.01\fR, +as this approsaches the timing granularity of most systems. +.SH "ANATOMY OF A WATCHER" +.IX Header "ANATOMY OF A WATCHER" +A watcher is a structure that you create and register to record your +interest in some event. For instance, if you want to wait for \s-1STDIN\s0 to +become readable, you would create an \f(CW\*(C`ev_io\*(C'\fR watcher for that: +.PP +.Vb 5 +\& static void my_cb (struct ev_loop *loop, struct ev_io *w, int revents) +\& { +\& ev_io_stop (w); +\& ev_unloop (loop, EVUNLOOP_ALL); +\& } +\& +\& struct ev_loop *loop = ev_default_loop (0); +\& struct ev_io stdin_watcher; +\& ev_init (&stdin_watcher, my_cb); +\& ev_io_set (&stdin_watcher, STDIN_FILENO, EV_READ); +\& ev_io_start (loop, &stdin_watcher); +\& ev_loop (loop, 0); +.Ve +.PP +As you can see, you are responsible for allocating the memory for your +watcher structures (and it is usually a bad idea to do this on the stack, +although this can sometimes be quite valid). +.PP +Each watcher structure must be initialised by a call to \f(CW\*(C`ev_init +(watcher *, callback)\*(C'\fR, which expects a callback to be provided. This +callback gets invoked each time the event occurs (or, in the case of io +watchers, each time the event loop detects that the file descriptor given +is readable and/or writable). +.PP +Each watcher type has its own \f(CW\*(C`ev_<type>_set (watcher *, ...)\*(C'\fR macro +with arguments specific to this watcher type. There is also a macro +to combine initialisation and setting in one call: \f(CW\*(C`ev_<type>_init +(watcher *, callback, ...)\*(C'\fR. +.PP +To make the watcher actually watch out for events, you have to start it +with a watcher-specific start function (\f(CW\*(C`ev_<type>_start (loop, watcher +*)\*(C'\fR), and you can stop watching for events at any time by calling the +corresponding stop function (\f(CW\*(C`ev_<type>_stop (loop, watcher *)\*(C'\fR. +.PP +As long as your watcher is active (has been started but not stopped) you +must not touch the values stored in it. Most specifically you must never +reinitialise it or call its \f(CW\*(C`set\*(C'\fR macro. +.PP +Each and every callback receives the event loop pointer as first, the +registered watcher structure as second, and a bitset of received events as +third argument. +.PP +The received events usually include a single bit per event type received +(you can receive multiple events at the same time). The possible bit masks +are: +.ie n .IP """EV_READ""" 4 +.el .IP "\f(CWEV_READ\fR" 4 +.IX Item "EV_READ" +.PD 0 +.ie n .IP """EV_WRITE""" 4 +.el .IP "\f(CWEV_WRITE\fR" 4 +.IX Item "EV_WRITE" +.PD +The file descriptor in the \f(CW\*(C`ev_io\*(C'\fR watcher has become readable and/or +writable. +.ie n .IP """EV_TIMEOUT""" 4 +.el .IP "\f(CWEV_TIMEOUT\fR" 4 +.IX Item "EV_TIMEOUT" +The \f(CW\*(C`ev_timer\*(C'\fR watcher has timed out. +.ie n .IP """EV_PERIODIC""" 4 +.el .IP "\f(CWEV_PERIODIC\fR" 4 +.IX Item "EV_PERIODIC" +The \f(CW\*(C`ev_periodic\*(C'\fR watcher has timed out. +.ie n .IP """EV_SIGNAL""" 4 +.el .IP "\f(CWEV_SIGNAL\fR" 4 +.IX Item "EV_SIGNAL" +The signal specified in the \f(CW\*(C`ev_signal\*(C'\fR watcher has been received by a thread. +.ie n .IP """EV_CHILD""" 4 +.el .IP "\f(CWEV_CHILD\fR" 4 +.IX Item "EV_CHILD" +The pid specified in the \f(CW\*(C`ev_child\*(C'\fR watcher has received a status change. +.ie n .IP """EV_STAT""" 4 +.el .IP "\f(CWEV_STAT\fR" 4 +.IX Item "EV_STAT" +The path specified in the \f(CW\*(C`ev_stat\*(C'\fR watcher changed its attributes somehow. +.ie n .IP """EV_IDLE""" 4 +.el .IP "\f(CWEV_IDLE\fR" 4 +.IX Item "EV_IDLE" +The \f(CW\*(C`ev_idle\*(C'\fR watcher has determined that you have nothing better to do. +.ie n .IP """EV_PREPARE""" 4 +.el .IP "\f(CWEV_PREPARE\fR" 4 +.IX Item "EV_PREPARE" +.PD 0 +.ie n .IP """EV_CHECK""" 4 +.el .IP "\f(CWEV_CHECK\fR" 4 +.IX Item "EV_CHECK" +.PD +All \f(CW\*(C`ev_prepare\*(C'\fR watchers are invoked just \fIbefore\fR \f(CW\*(C`ev_loop\*(C'\fR starts +to gather new events, and all \f(CW\*(C`ev_check\*(C'\fR watchers are invoked just after +\&\f(CW\*(C`ev_loop\*(C'\fR has gathered them, but before it invokes any callbacks for any +received events. Callbacks of both watcher types can start and stop as +many watchers as they want, and all of them will be taken into account +(for example, a \f(CW\*(C`ev_prepare\*(C'\fR watcher might start an idle watcher to keep +\&\f(CW\*(C`ev_loop\*(C'\fR from blocking). +.ie n .IP """EV_EMBED""" 4 +.el .IP "\f(CWEV_EMBED\fR" 4 +.IX Item "EV_EMBED" +The embedded event loop specified in the \f(CW\*(C`ev_embed\*(C'\fR watcher needs attention. +.ie n .IP """EV_FORK""" 4 +.el .IP "\f(CWEV_FORK\fR" 4 +.IX Item "EV_FORK" +The event loop has been resumed in the child process after fork (see +\&\f(CW\*(C`ev_fork\*(C'\fR). +.ie n .IP """EV_ASYNC""" 4 +.el .IP "\f(CWEV_ASYNC\fR" 4 +.IX Item "EV_ASYNC" +The given async watcher has been asynchronously notified (see \f(CW\*(C`ev_async\*(C'\fR). +.ie n .IP """EV_ERROR""" 4 +.el .IP "\f(CWEV_ERROR\fR" 4 +.IX Item "EV_ERROR" +An unspecified error has occured, the watcher has been stopped. This might +happen because the watcher could not be properly started because libev +ran out of memory, a file descriptor was found to be closed or any other +problem. You best act on it by reporting the problem and somehow coping +with the watcher being stopped. +.Sp +Libev will usually signal a few \*(L"dummy\*(R" events together with an error, +for example it might indicate that a fd is readable or writable, and if +your callbacks is well-written it can just attempt the operation and cope +with the error from \fIread()\fR or \fIwrite()\fR. This will not work in multithreaded +programs, though, so beware. +.Sh "\s-1GENERIC\s0 \s-1WATCHER\s0 \s-1FUNCTIONS\s0" +.IX Subsection "GENERIC WATCHER FUNCTIONS" +In the following description, \f(CW\*(C`TYPE\*(C'\fR stands for the watcher type, +e.g. \f(CW\*(C`timer\*(C'\fR for \f(CW\*(C`ev_timer\*(C'\fR watchers and \f(CW\*(C`io\*(C'\fR for \f(CW\*(C`ev_io\*(C'\fR watchers. +.ie n .IP """ev_init"" (ev_TYPE *watcher, callback)" 4 +.el .IP "\f(CWev_init\fR (ev_TYPE *watcher, callback)" 4 +.IX Item "ev_init (ev_TYPE *watcher, callback)" +This macro initialises the generic portion of a watcher. The contents +of the watcher object can be arbitrary (so \f(CW\*(C`malloc\*(C'\fR will do). Only +the generic parts of the watcher are initialised, you \fIneed\fR to call +the type-specific \f(CW\*(C`ev_TYPE_set\*(C'\fR macro afterwards to initialise the +type-specific parts. For each type there is also a \f(CW\*(C`ev_TYPE_init\*(C'\fR macro +which rolls both calls into one. +.Sp +You can reinitialise a watcher at any time as long as it has been stopped +(or never started) and there are no pending events outstanding. +.Sp +The callback is always of type \f(CW\*(C`void (*)(ev_loop *loop, ev_TYPE *watcher, +int revents)\*(C'\fR. +.ie n .IP """ev_TYPE_set"" (ev_TYPE *, [args])" 4 +.el .IP "\f(CWev_TYPE_set\fR (ev_TYPE *, [args])" 4 +.IX Item "ev_TYPE_set (ev_TYPE *, [args])" +This macro initialises the type-specific parts of a watcher. You need to +call \f(CW\*(C`ev_init\*(C'\fR at least once before you call this macro, but you can +call \f(CW\*(C`ev_TYPE_set\*(C'\fR any number of times. You must not, however, call this +macro on a watcher that is active (it can be pending, however, which is a +difference to the \f(CW\*(C`ev_init\*(C'\fR macro). +.Sp +Although some watcher types do not have type-specific arguments +(e.g. \f(CW\*(C`ev_prepare\*(C'\fR) you still need to call its \f(CW\*(C`set\*(C'\fR macro. +.ie n .IP """ev_TYPE_init"" (ev_TYPE *watcher, callback, [args])" 4 +.el .IP "\f(CWev_TYPE_init\fR (ev_TYPE *watcher, callback, [args])" 4 +.IX Item "ev_TYPE_init (ev_TYPE *watcher, callback, [args])" +This convinience macro rolls both \f(CW\*(C`ev_init\*(C'\fR and \f(CW\*(C`ev_TYPE_set\*(C'\fR macro +calls into a single call. This is the most convinient method to initialise +a watcher. The same limitations apply, of course. +.ie n .IP """ev_TYPE_start"" (loop *, ev_TYPE *watcher)" 4 +.el .IP "\f(CWev_TYPE_start\fR (loop *, ev_TYPE *watcher)" 4 +.IX Item "ev_TYPE_start (loop *, ev_TYPE *watcher)" +Starts (activates) the given watcher. Only active watchers will receive +events. If the watcher is already active nothing will happen. +.ie n .IP """ev_TYPE_stop"" (loop *, ev_TYPE *watcher)" 4 +.el .IP "\f(CWev_TYPE_stop\fR (loop *, ev_TYPE *watcher)" 4 +.IX Item "ev_TYPE_stop (loop *, ev_TYPE *watcher)" +Stops the given watcher again (if active) and clears the pending +status. It is possible that stopped watchers are pending (for example, +non-repeating timers are being stopped when they become pending), but +\&\f(CW\*(C`ev_TYPE_stop\*(C'\fR ensures that the watcher is neither active nor pending. If +you want to free or reuse the memory used by the watcher it is therefore a +good idea to always call its \f(CW\*(C`ev_TYPE_stop\*(C'\fR function. +.IP "bool ev_is_active (ev_TYPE *watcher)" 4 +.IX Item "bool ev_is_active (ev_TYPE *watcher)" +Returns a true value iff the watcher is active (i.e. it has been started +and not yet been stopped). As long as a watcher is active you must not modify +it. +.IP "bool ev_is_pending (ev_TYPE *watcher)" 4 +.IX Item "bool ev_is_pending (ev_TYPE *watcher)" +Returns a true value iff the watcher is pending, (i.e. it has outstanding +events but its callback has not yet been invoked). As long as a watcher +is pending (but not active) you must not call an init function on it (but +\&\f(CW\*(C`ev_TYPE_set\*(C'\fR is safe), you must not change its priority, and you must +make sure the watcher is available to libev (e.g. you cannot \f(CW\*(C`free ()\*(C'\fR +it). +.IP "callback ev_cb (ev_TYPE *watcher)" 4 +.IX Item "callback ev_cb (ev_TYPE *watcher)" +Returns the callback currently set on the watcher. +.IP "ev_cb_set (ev_TYPE *watcher, callback)" 4 +.IX Item "ev_cb_set (ev_TYPE *watcher, callback)" +Change the callback. You can change the callback at virtually any time +(modulo threads). +.IP "ev_set_priority (ev_TYPE *watcher, priority)" 4 +.IX Item "ev_set_priority (ev_TYPE *watcher, priority)" +.PD 0 +.IP "int ev_priority (ev_TYPE *watcher)" 4 +.IX Item "int ev_priority (ev_TYPE *watcher)" +.PD +Set and query the priority of the watcher. The priority is a small +integer between \f(CW\*(C`EV_MAXPRI\*(C'\fR (default: \f(CW2\fR) and \f(CW\*(C`EV_MINPRI\*(C'\fR +(default: \f(CW\*(C`\-2\*(C'\fR). Pending watchers with higher priority will be invoked +before watchers with lower priority, but priority will not keep watchers +from being executed (except for \f(CW\*(C`ev_idle\*(C'\fR watchers). +.Sp +This means that priorities are \fIonly\fR used for ordering callback +invocation after new events have been received. This is useful, for +example, to reduce latency after idling, or more often, to bind two +watchers on the same event and make sure one is called first. +.Sp +If you need to suppress invocation when higher priority events are pending +you need to look at \f(CW\*(C`ev_idle\*(C'\fR watchers, which provide this functionality. +.Sp +You \fImust not\fR change the priority of a watcher as long as it is active or +pending. +.Sp +The default priority used by watchers when no priority has been set is +always \f(CW0\fR, which is supposed to not be too high and not be too low :). +.Sp +Setting a priority outside the range of \f(CW\*(C`EV_MINPRI\*(C'\fR to \f(CW\*(C`EV_MAXPRI\*(C'\fR is +fine, as long as you do not mind that the priority value you query might +or might not have been adjusted to be within valid range. +.IP "ev_invoke (loop, ev_TYPE *watcher, int revents)" 4 +.IX Item "ev_invoke (loop, ev_TYPE *watcher, int revents)" +Invoke the \f(CW\*(C`watcher\*(C'\fR with the given \f(CW\*(C`loop\*(C'\fR and \f(CW\*(C`revents\*(C'\fR. Neither +\&\f(CW\*(C`loop\*(C'\fR nor \f(CW\*(C`revents\*(C'\fR need to be valid as long as the watcher callback +can deal with that fact. +.IP "int ev_clear_pending (loop, ev_TYPE *watcher)" 4 +.IX Item "int ev_clear_pending (loop, ev_TYPE *watcher)" +If the watcher is pending, this function returns clears its pending status +and returns its \f(CW\*(C`revents\*(C'\fR bitset (as if its callback was invoked). If the +watcher isn't pending it does nothing and returns \f(CW0\fR. +.Sh "\s-1ASSOCIATING\s0 \s-1CUSTOM\s0 \s-1DATA\s0 \s-1WITH\s0 A \s-1WATCHER\s0" +.IX Subsection "ASSOCIATING CUSTOM DATA WITH A WATCHER" +Each watcher has, by default, a member \f(CW\*(C`void *data\*(C'\fR that you can change +and read at any time, libev will completely ignore it. This can be used +to associate arbitrary data with your watcher. If you need more data and +don't want to allocate memory and store a pointer to it in that data +member, you can also \*(L"subclass\*(R" the watcher type and provide your own +data: +.PP +.Vb 7 +\& struct my_io +\& { +\& struct ev_io io; +\& int otherfd; +\& void *somedata; +\& struct whatever *mostinteresting; +\& } +.Ve +.PP +And since your callback will be called with a pointer to the watcher, you +can cast it back to your own type: +.PP +.Vb 5 +\& static void my_cb (struct ev_loop *loop, struct ev_io *w_, int revents) +\& { +\& struct my_io *w = (struct my_io *)w_; +\& ... +\& } +.Ve +.PP +More interesting and less C\-conformant ways of casting your callback type +instead have been omitted. +.PP +Another common scenario is having some data structure with multiple +watchers: +.PP +.Vb 6 +\& struct my_biggy +\& { +\& int some_data; +\& ev_timer t1; +\& ev_timer t2; +\& } +.Ve +.PP +In this case getting the pointer to \f(CW\*(C`my_biggy\*(C'\fR is a bit more complicated, +you need to use \f(CW\*(C`offsetof\*(C'\fR: +.PP +.Vb 1 +\& #include <stddef.h> +\& +\& static void +\& t1_cb (EV_P_ struct ev_timer *w, int revents) +\& { +\& struct my_biggy big = (struct my_biggy * +\& (((char *)w) \- offsetof (struct my_biggy, t1)); +\& } +\& +\& static void +\& t2_cb (EV_P_ struct ev_timer *w, int revents) +\& { +\& struct my_biggy big = (struct my_biggy * +\& (((char *)w) \- offsetof (struct my_biggy, t2)); +\& } +.Ve +.SH "WATCHER TYPES" +.IX Header "WATCHER TYPES" +This section describes each watcher in detail, but will not repeat +information given in the last section. Any initialisation/set macros, +functions and members specific to the watcher type are explained. +.PP +Members are additionally marked with either \fI[read\-only]\fR, meaning that, +while the watcher is active, you can look at the member and expect some +sensible content, but you must not modify it (you can modify it while the +watcher is stopped to your hearts content), or \fI[read\-write]\fR, which +means you can expect it to have some sensible content while the watcher +is active, but you can also modify it. Modifying it may not do something +sensible or take immediate effect (or do anything at all), but libev will +not crash or malfunction in any way. +.ie n .Sh """ev_io"" \- is this file descriptor readable or writable?" +.el .Sh "\f(CWev_io\fP \- is this file descriptor readable or writable?" +.IX Subsection "ev_io - is this file descriptor readable or writable?" +I/O watchers check whether a file descriptor is readable or writable +in each iteration of the event loop, or, more precisely, when reading +would not block the process and writing would at least be able to write +some data. This behaviour is called level-triggering because you keep +receiving events as long as the condition persists. Remember you can stop +the watcher if you don't want to act on the event and neither want to +receive future events. +.PP +In general you can register as many read and/or write event watchers per +fd as you want (as long as you don't confuse yourself). Setting all file +descriptors to non-blocking mode is also usually a good idea (but not +required if you know what you are doing). +.PP +If you must do this, then force the use of a known-to-be-good backend +(at the time of this writing, this includes only \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR and +\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR). +.PP +Another thing you have to watch out for is that it is quite easy to +receive \*(L"spurious\*(R" readyness notifications, that is your callback might +be called with \f(CW\*(C`EV_READ\*(C'\fR but a subsequent \f(CW\*(C`read\*(C'\fR(2) will actually block +because there is no data. Not only are some backends known to create a +lot of those (for example solaris ports), it is very easy to get into +this situation even with a relatively standard program structure. Thus +it is best to always use non-blocking I/O: An extra \f(CW\*(C`read\*(C'\fR(2) returning +\&\f(CW\*(C`EAGAIN\*(C'\fR is far preferable to a program hanging until some data arrives. +.PP +If you cannot run the fd in non-blocking mode (for example you should not +play around with an Xlib connection), then you have to seperately re-test +whether a file descriptor is really ready with a known-to-be good interface +such as poll (fortunately in our Xlib example, Xlib already does this on +its own, so its quite safe to use). +.PP +\fIThe special problem of disappearing file descriptors\fR +.IX Subsection "The special problem of disappearing file descriptors" +.PP +Some backends (e.g. kqueue, epoll) need to be told about closing a file +descriptor (either by calling \f(CW\*(C`close\*(C'\fR explicitly or by any other means, +such as \f(CW\*(C`dup\*(C'\fR). The reason is that you register interest in some file +descriptor, but when it goes away, the operating system will silently drop +this interest. If another file descriptor with the same number then is +registered with libev, there is no efficient way to see that this is, in +fact, a different file descriptor. +.PP +To avoid having to explicitly tell libev about such cases, libev follows +the following policy: Each time \f(CW\*(C`ev_io_set\*(C'\fR is being called, libev +will assume that this is potentially a new file descriptor, otherwise +it is assumed that the file descriptor stays the same. That means that +you \fIhave\fR to call \f(CW\*(C`ev_io_set\*(C'\fR (or \f(CW\*(C`ev_io_init\*(C'\fR) when you change the +descriptor even if the file descriptor number itself did not change. +.PP +This is how one would do it normally anyway, the important point is that +the libev application should not optimise around libev but should leave +optimisations to libev. +.PP +\fIThe special problem of dup'ed file descriptors\fR +.IX Subsection "The special problem of dup'ed file descriptors" +.PP +Some backends (e.g. epoll), cannot register events for file descriptors, +but only events for the underlying file descriptions. That means when you +have \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors or weirder constellations, and register +events for them, only one file descriptor might actually receive events. +.PP +There is no workaround possible except not registering events +for potentially \f(CW\*(C`dup ()\*(C'\fR'ed file descriptors, or to resort to +\&\f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or \f(CW\*(C`EVBACKEND_POLL\*(C'\fR. +.PP +\fIThe special problem of fork\fR +.IX Subsection "The special problem of fork" +.PP +Some backends (epoll, kqueue) do not support \f(CW\*(C`fork ()\*(C'\fR at all or exhibit +useless behaviour. Libev fully supports fork, but needs to be told about +it in the child. +.PP +To support fork in your programs, you either have to call +\&\f(CW\*(C`ev_default_fork ()\*(C'\fR or \f(CW\*(C`ev_loop_fork ()\*(C'\fR after a fork in the child, +enable \f(CW\*(C`EVFLAG_FORKCHECK\*(C'\fR, or resort to \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR or +\&\f(CW\*(C`EVBACKEND_POLL\*(C'\fR. +.PP +\fIThe special problem of \s-1SIGPIPE\s0\fR +.IX Subsection "The special problem of SIGPIPE" +.PP +While not really specific to libev, it is easy to forget about \s-1SIGPIPE:\s0 +when reading from a pipe whose other end has been closed, your program +gets send a \s-1SIGPIPE\s0, which, by default, aborts your program. For most +programs this is sensible behaviour, for daemons, this is usually +undesirable. +.PP +So when you encounter spurious, unexplained daemon exits, make sure you +ignore \s-1SIGPIPE\s0 (and maybe make sure you log the exit status of your daemon +somewhere, as that would have given you a big clue). +.PP +\fIWatcher-Specific Functions\fR +.IX Subsection "Watcher-Specific Functions" +.IP "ev_io_init (ev_io *, callback, int fd, int events)" 4 +.IX Item "ev_io_init (ev_io *, callback, int fd, int events)" +.PD 0 +.IP "ev_io_set (ev_io *, int fd, int events)" 4 +.IX Item "ev_io_set (ev_io *, int fd, int events)" +.PD +Configures an \f(CW\*(C`ev_io\*(C'\fR watcher. The \f(CW\*(C`fd\*(C'\fR is the file descriptor to +rceeive events for and events is either \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or +\&\f(CW\*(C`EV_READ | EV_WRITE\*(C'\fR to receive the given events. +.IP "int fd [read\-only]" 4 +.IX Item "int fd [read-only]" +The file descriptor being watched. +.IP "int events [read\-only]" 4 +.IX Item "int events [read-only]" +The events being watched. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Call \f(CW\*(C`stdin_readable_cb\*(C'\fR when \s-1STDIN_FILENO\s0 has become, well +readable, but only once. Since it is likely line-buffered, you could +attempt to read a whole line in the callback. +.PP +.Vb 6 +\& static void +\& stdin_readable_cb (struct ev_loop *loop, struct ev_io *w, int revents) +\& { +\& ev_io_stop (loop, w); +\& .. read from stdin here (or from w\->fd) and haqndle any I/O errors +\& } +\& +\& ... +\& struct ev_loop *loop = ev_default_init (0); +\& struct ev_io stdin_readable; +\& ev_io_init (&stdin_readable, stdin_readable_cb, STDIN_FILENO, EV_READ); +\& ev_io_start (loop, &stdin_readable); +\& ev_loop (loop, 0); +.Ve +.ie n .Sh """ev_timer"" \- relative and optionally repeating timeouts" +.el .Sh "\f(CWev_timer\fP \- relative and optionally repeating timeouts" +.IX Subsection "ev_timer - relative and optionally repeating timeouts" +Timer watchers are simple relative timers that generate an event after a +given time, and optionally repeating in regular intervals after that. +.PP +The timers are based on real time, that is, if you register an event that +times out after an hour and you reset your system clock to last years +time, it will still time out after (roughly) and hour. \*(L"Roughly\*(R" because +detecting time jumps is hard, and some inaccuracies are unavoidable (the +monotonic clock option helps a lot here). +.PP +The relative timeouts are calculated relative to the \f(CW\*(C`ev_now ()\*(C'\fR +time. This is usually the right thing as this timestamp refers to the time +of the event triggering whatever timeout you are modifying/starting. If +you suspect event processing to be delayed and you \fIneed\fR to base the timeout +on the current time, use something like this to adjust for this: +.PP +.Vb 1 +\& ev_timer_set (&timer, after + ev_now () \- ev_time (), 0.); +.Ve +.PP +The callback is guarenteed to be invoked only when its timeout has passed, +but if multiple timers become ready during the same loop iteration then +order of execution is undefined. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)" 4 +.IX Item "ev_timer_init (ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)" +.PD 0 +.IP "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)" 4 +.IX Item "ev_timer_set (ev_timer *, ev_tstamp after, ev_tstamp repeat)" +.PD +Configure the timer to trigger after \f(CW\*(C`after\*(C'\fR seconds. If \f(CW\*(C`repeat\*(C'\fR is +\&\f(CW0.\fR, then it will automatically be stopped. If it is positive, then the +timer will automatically be configured to trigger again \f(CW\*(C`repeat\*(C'\fR seconds +later, again, and again, until stopped manually. +.Sp +The timer itself will do a best-effort at avoiding drift, that is, if you +configure a timer to trigger every 10 seconds, then it will trigger at +exactly 10 second intervals. If, however, your program cannot keep up with +the timer (because it takes longer than those 10 seconds to do stuff) the +timer will not fire more than once per event loop iteration. +.IP "ev_timer_again (loop, ev_timer *)" 4 +.IX Item "ev_timer_again (loop, ev_timer *)" +This will act as if the timer timed out and restart it again if it is +repeating. The exact semantics are: +.Sp +If the timer is pending, its pending status is cleared. +.Sp +If the timer is started but nonrepeating, stop it (as if it timed out). +.Sp +If the timer is repeating, either start it if necessary (with the +\&\f(CW\*(C`repeat\*(C'\fR value), or reset the running timer to the \f(CW\*(C`repeat\*(C'\fR value. +.Sp +This sounds a bit complicated, but here is a useful and typical +example: Imagine you have a tcp connection and you want a so-called idle +timeout, that is, you want to be called when there have been, say, 60 +seconds of inactivity on the socket. The easiest way to do this is to +configure an \f(CW\*(C`ev_timer\*(C'\fR with a \f(CW\*(C`repeat\*(C'\fR value of \f(CW60\fR and then call +\&\f(CW\*(C`ev_timer_again\*(C'\fR each time you successfully read or write some data. If +you go into an idle state where you do not expect data to travel on the +socket, you can \f(CW\*(C`ev_timer_stop\*(C'\fR the timer, and \f(CW\*(C`ev_timer_again\*(C'\fR will +automatically restart it if need be. +.Sp +That means you can ignore the \f(CW\*(C`after\*(C'\fR value and \f(CW\*(C`ev_timer_start\*(C'\fR +altogether and only ever use the \f(CW\*(C`repeat\*(C'\fR value and \f(CW\*(C`ev_timer_again\*(C'\fR: +.Sp +.Vb 8 +\& ev_timer_init (timer, callback, 0., 5.); +\& ev_timer_again (loop, timer); +\& ... +\& timer\->again = 17.; +\& ev_timer_again (loop, timer); +\& ... +\& timer\->again = 10.; +\& ev_timer_again (loop, timer); +.Ve +.Sp +This is more slightly efficient then stopping/starting the timer each time +you want to modify its timeout value. +.IP "ev_tstamp repeat [read\-write]" 4 +.IX Item "ev_tstamp repeat [read-write]" +The current \f(CW\*(C`repeat\*(C'\fR value. Will be used each time the watcher times out +or \f(CW\*(C`ev_timer_again\*(C'\fR is called and determines the next timeout (if any), +which is also when any modifications are taken into account. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Create a timer that fires after 60 seconds. +.PP +.Vb 5 +\& static void +\& one_minute_cb (struct ev_loop *loop, struct ev_timer *w, int revents) +\& { +\& .. one minute over, w is actually stopped right here +\& } +\& +\& struct ev_timer mytimer; +\& ev_timer_init (&mytimer, one_minute_cb, 60., 0.); +\& ev_timer_start (loop, &mytimer); +.Ve +.PP +Example: Create a timeout timer that times out after 10 seconds of +inactivity. +.PP +.Vb 5 +\& static void +\& timeout_cb (struct ev_loop *loop, struct ev_timer *w, int revents) +\& { +\& .. ten seconds without any activity +\& } +\& +\& struct ev_timer mytimer; +\& ev_timer_init (&mytimer, timeout_cb, 0., 10.); /* note, only repeat used */ +\& ev_timer_again (&mytimer); /* start timer */ +\& ev_loop (loop, 0); +\& +\& // and in some piece of code that gets executed on any "activity": +\& // reset the timeout to start ticking again at 10 seconds +\& ev_timer_again (&mytimer); +.Ve +.ie n .Sh """ev_periodic"" \- to cron or not to cron?" +.el .Sh "\f(CWev_periodic\fP \- to cron or not to cron?" +.IX Subsection "ev_periodic - to cron or not to cron?" +Periodic watchers are also timers of a kind, but they are very versatile +(and unfortunately a bit complex). +.PP +Unlike \f(CW\*(C`ev_timer\*(C'\fR's, they are not based on real time (or relative time) +but on wallclock time (absolute time). You can tell a periodic watcher +to trigger \*(L"at\*(R" some specific point in time. For example, if you tell a +periodic watcher to trigger in 10 seconds (by specifiying e.g. \f(CW\*(C`ev_now () ++ 10.\*(C'\fR) and then reset your system clock to the last year, then it will +take a year to trigger the event (unlike an \f(CW\*(C`ev_timer\*(C'\fR, which would trigger +roughly 10 seconds later). +.PP +They can also be used to implement vastly more complex timers, such as +triggering an event on each midnight, local time or other, complicated, +rules. +.PP +As with timers, the callback is guarenteed to be invoked only when the +time (\f(CW\*(C`at\*(C'\fR) has been passed, but if multiple periodic timers become ready +during the same loop iteration then order of execution is undefined. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb)" 4 +.IX Item "ev_periodic_init (ev_periodic *, callback, ev_tstamp at, ev_tstamp interval, reschedule_cb)" +.PD 0 +.IP "ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb)" 4 +.IX Item "ev_periodic_set (ev_periodic *, ev_tstamp after, ev_tstamp repeat, reschedule_cb)" +.PD +Lots of arguments, lets sort it out... There are basically three modes of +operation, and we will explain them from simplest to complex: +.RS 4 +.IP "\(bu" 4 +absolute timer (at = time, interval = reschedule_cb = 0) +.Sp +In this configuration the watcher triggers an event at the wallclock time +\&\f(CW\*(C`at\*(C'\fR and doesn't repeat. It will not adjust when a time jump occurs, +that is, if it is to be run at January 1st 2011 then it will run when the +system time reaches or surpasses this time. +.IP "\(bu" 4 +repeating interval timer (at = offset, interval > 0, reschedule_cb = 0) +.Sp +In this mode the watcher will always be scheduled to time out at the next +\&\f(CW\*(C`at + N * interval\*(C'\fR time (for some integer N, which can also be negative) +and then repeat, regardless of any time jumps. +.Sp +This can be used to create timers that do not drift with respect to system +time: +.Sp +.Vb 1 +\& ev_periodic_set (&periodic, 0., 3600., 0); +.Ve +.Sp +This doesn't mean there will always be 3600 seconds in between triggers, +but only that the the callback will be called when the system time shows a +full hour (\s-1UTC\s0), or more correctly, when the system time is evenly divisible +by 3600. +.Sp +Another way to think about it (for the mathematically inclined) is that +\&\f(CW\*(C`ev_periodic\*(C'\fR will try to run the callback in this mode at the next possible +time where \f(CW\*(C`time = at (mod interval)\*(C'\fR, regardless of any time jumps. +.Sp +For numerical stability it is preferable that the \f(CW\*(C`at\*(C'\fR value is near +\&\f(CW\*(C`ev_now ()\*(C'\fR (the current time), but there is no range requirement for +this value. +.IP "\(bu" 4 +manual reschedule mode (at and interval ignored, reschedule_cb = callback) +.Sp +In this mode the values for \f(CW\*(C`interval\*(C'\fR and \f(CW\*(C`at\*(C'\fR are both being +ignored. Instead, each time the periodic watcher gets scheduled, the +reschedule callback will be called with the watcher as first, and the +current time as second argument. +.Sp +\&\s-1NOTE:\s0 \fIThis callback \s-1MUST\s0 \s-1NOT\s0 stop or destroy any periodic watcher, +ever, or make any event loop modifications\fR. If you need to stop it, +return \f(CW\*(C`now + 1e30\*(C'\fR (or so, fudge fudge) and stop it afterwards (e.g. by +starting an \f(CW\*(C`ev_prepare\*(C'\fR watcher, which is legal). +.Sp +Its prototype is \f(CW\*(C`ev_tstamp (*reschedule_cb)(struct ev_periodic *w, +ev_tstamp now)\*(C'\fR, e.g.: +.Sp +.Vb 4 +\& static ev_tstamp my_rescheduler (struct ev_periodic *w, ev_tstamp now) +\& { +\& return now + 60.; +\& } +.Ve +.Sp +It must return the next time to trigger, based on the passed time value +(that is, the lowest time value larger than to the second argument). It +will usually be called just before the callback will be triggered, but +might be called at other times, too. +.Sp +\&\s-1NOTE:\s0 \fIThis callback must always return a time that is later than the +passed \f(CI\*(C`now\*(C'\fI value\fR. Not even \f(CW\*(C`now\*(C'\fR itself will do, it \fImust\fR be larger. +.Sp +This can be used to create very complex timers, such as a timer that +triggers on each midnight, local time. To do this, you would calculate the +next midnight after \f(CW\*(C`now\*(C'\fR and return the timestamp value for this. How +you do this is, again, up to you (but it is not trivial, which is the main +reason I omitted it as an example). +.RE +.RS 4 +.RE +.IP "ev_periodic_again (loop, ev_periodic *)" 4 +.IX Item "ev_periodic_again (loop, ev_periodic *)" +Simply stops and restarts the periodic watcher again. This is only useful +when you changed some parameters or the reschedule callback would return +a different time than the last time it was called (e.g. in a crond like +program when the crontabs have changed). +.IP "ev_tstamp ev_periodic_at (ev_periodic *)" 4 +.IX Item "ev_tstamp ev_periodic_at (ev_periodic *)" +When active, returns the absolute time that the watcher is supposed to +trigger next. +.IP "ev_tstamp offset [read\-write]" 4 +.IX Item "ev_tstamp offset [read-write]" +When repeating, this contains the offset value, otherwise this is the +absolute point in time (the \f(CW\*(C`at\*(C'\fR value passed to \f(CW\*(C`ev_periodic_set\*(C'\fR). +.Sp +Can be modified any time, but changes only take effect when the periodic +timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called. +.IP "ev_tstamp interval [read\-write]" 4 +.IX Item "ev_tstamp interval [read-write]" +The current interval value. Can be modified any time, but changes only +take effect when the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being +called. +.IP "ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) [read\-write]" 4 +.IX Item "ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) [read-write]" +The current reschedule callback, or \f(CW0\fR, if this functionality is +switched off. Can be changed any time, but changes only take effect when +the periodic timer fires or \f(CW\*(C`ev_periodic_again\*(C'\fR is being called. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Call a callback every hour, or, more precisely, whenever the +system clock is divisible by 3600. The callback invocation times have +potentially a lot of jittering, but good long-term stability. +.PP +.Vb 5 +\& static void +\& clock_cb (struct ev_loop *loop, struct ev_io *w, int revents) +\& { +\& ... its now a full hour (UTC, or TAI or whatever your clock follows) +\& } +\& +\& struct ev_periodic hourly_tick; +\& ev_periodic_init (&hourly_tick, clock_cb, 0., 3600., 0); +\& ev_periodic_start (loop, &hourly_tick); +.Ve +.PP +Example: The same as above, but use a reschedule callback to do it: +.PP +.Vb 1 +\& #include <math.h> +\& +\& static ev_tstamp +\& my_scheduler_cb (struct ev_periodic *w, ev_tstamp now) +\& { +\& return fmod (now, 3600.) + 3600.; +\& } +\& +\& ev_periodic_init (&hourly_tick, clock_cb, 0., 0., my_scheduler_cb); +.Ve +.PP +Example: Call a callback every hour, starting now: +.PP +.Vb 4 +\& struct ev_periodic hourly_tick; +\& ev_periodic_init (&hourly_tick, clock_cb, +\& fmod (ev_now (loop), 3600.), 3600., 0); +\& ev_periodic_start (loop, &hourly_tick); +.Ve +.ie n .Sh """ev_signal"" \- signal me when a signal gets signalled!" +.el .Sh "\f(CWev_signal\fP \- signal me when a signal gets signalled!" +.IX Subsection "ev_signal - signal me when a signal gets signalled!" +Signal watchers will trigger an event when the process receives a specific +signal one or more times. Even though signals are very asynchronous, libev +will try it's best to deliver signals synchronously, i.e. as part of the +normal event processing, like any other event. +.PP +You can configure as many watchers as you like per signal. Only when the +first watcher gets started will libev actually register a signal watcher +with the kernel (thus it coexists with your own signal handlers as long +as you don't register any with libev). Similarly, when the last signal +watcher for a signal is stopped libev will reset the signal handler to +\&\s-1SIG_DFL\s0 (regardless of what it was set to before). +.PP +If possible and supported, libev will install its handlers with +\&\f(CW\*(C`SA_RESTART\*(C'\fR behaviour enabled, so syscalls should not be unduly +interrupted. If you have a problem with syscalls getting interrupted by +signals you can block all signals in an \f(CW\*(C`ev_check\*(C'\fR watcher and unblock +them in an \f(CW\*(C`ev_prepare\*(C'\fR watcher. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_signal_init (ev_signal *, callback, int signum)" 4 +.IX Item "ev_signal_init (ev_signal *, callback, int signum)" +.PD 0 +.IP "ev_signal_set (ev_signal *, int signum)" 4 +.IX Item "ev_signal_set (ev_signal *, int signum)" +.PD +Configures the watcher to trigger on the given signal number (usually one +of the \f(CW\*(C`SIGxxx\*(C'\fR constants). +.IP "int signum [read\-only]" 4 +.IX Item "int signum [read-only]" +The signal the watcher watches out for. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Try to exit cleanly on \s-1SIGINT\s0 and \s-1SIGTERM\s0. +.PP +.Vb 5 +\& static void +\& sigint_cb (struct ev_loop *loop, struct ev_signal *w, int revents) +\& { +\& ev_unloop (loop, EVUNLOOP_ALL); +\& } +\& +\& struct ev_signal signal_watcher; +\& ev_signal_init (&signal_watcher, sigint_cb, SIGINT); +\& ev_signal_start (loop, &sigint_cb); +.Ve +.ie n .Sh """ev_child"" \- watch out for process status changes" +.el .Sh "\f(CWev_child\fP \- watch out for process status changes" +.IX Subsection "ev_child - watch out for process status changes" +Child watchers trigger when your process receives a \s-1SIGCHLD\s0 in response to +some child status changes (most typically when a child of yours dies). It +is permissible to install a child watcher \fIafter\fR the child has been +forked (which implies it might have already exited), as long as the event +loop isn't entered (or is continued from a watcher). +.PP +Only the default event loop is capable of handling signals, and therefore +you can only rgeister child watchers in the default event loop. +.PP +\fIProcess Interaction\fR +.IX Subsection "Process Interaction" +.PP +Libev grabs \f(CW\*(C`SIGCHLD\*(C'\fR as soon as the default event loop is +initialised. This is necessary to guarantee proper behaviour even if +the first child watcher is started after the child exits. The occurance +of \f(CW\*(C`SIGCHLD\*(C'\fR is recorded asynchronously, but child reaping is done +synchronously as part of the event loop processing. Libev always reaps all +children, even ones not watched. +.PP +\fIOverriding the Built-In Processing\fR +.IX Subsection "Overriding the Built-In Processing" +.PP +Libev offers no special support for overriding the built-in child +processing, but if your application collides with libev's default child +handler, you can override it easily by installing your own handler for +\&\f(CW\*(C`SIGCHLD\*(C'\fR after initialising the default loop, and making sure the +default loop never gets destroyed. You are encouraged, however, to use an +event-based approach to child reaping and thus use libev's support for +that, so other libev users can use \f(CW\*(C`ev_child\*(C'\fR watchers freely. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_child_init (ev_child *, callback, int pid, int trace)" 4 +.IX Item "ev_child_init (ev_child *, callback, int pid, int trace)" +.PD 0 +.IP "ev_child_set (ev_child *, int pid, int trace)" 4 +.IX Item "ev_child_set (ev_child *, int pid, int trace)" +.PD +Configures the watcher to wait for status changes of process \f(CW\*(C`pid\*(C'\fR (or +\&\fIany\fR process if \f(CW\*(C`pid\*(C'\fR is specified as \f(CW0\fR). The callback can look +at the \f(CW\*(C`rstatus\*(C'\fR member of the \f(CW\*(C`ev_child\*(C'\fR watcher structure to see +the status word (use the macros from \f(CW\*(C`sys/wait.h\*(C'\fR and see your systems +\&\f(CW\*(C`waitpid\*(C'\fR documentation). The \f(CW\*(C`rpid\*(C'\fR member contains the pid of the +process causing the status change. \f(CW\*(C`trace\*(C'\fR must be either \f(CW0\fR (only +activate the watcher when the process terminates) or \f(CW1\fR (additionally +activate the watcher when the process is stopped or continued). +.IP "int pid [read\-only]" 4 +.IX Item "int pid [read-only]" +The process id this watcher watches out for, or \f(CW0\fR, meaning any process id. +.IP "int rpid [read\-write]" 4 +.IX Item "int rpid [read-write]" +The process id that detected a status change. +.IP "int rstatus [read\-write]" 4 +.IX Item "int rstatus [read-write]" +The process exit/trace status caused by \f(CW\*(C`rpid\*(C'\fR (see your systems +\&\f(CW\*(C`waitpid\*(C'\fR and \f(CW\*(C`sys/wait.h\*(C'\fR documentation for details). +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: \f(CW\*(C`fork()\*(C'\fR a new process and install a child handler to wait for +its completion. +.PP +.Vb 1 +\& ev_child cw; +\& +\& static void +\& child_cb (EV_P_ struct ev_child *w, int revents) +\& { +\& ev_child_stop (EV_A_ w); +\& printf ("process %d exited with status %x\en", w\->rpid, w\->rstatus); +\& } +\& +\& pid_t pid = fork (); +\& +\& if (pid < 0) +\& // error +\& else if (pid == 0) +\& { +\& // the forked child executes here +\& exit (1); +\& } +\& else +\& { +\& ev_child_init (&cw, child_cb, pid, 0); +\& ev_child_start (EV_DEFAULT_ &cw); +\& } +.Ve +.ie n .Sh """ev_stat"" \- did the file attributes just change?" +.el .Sh "\f(CWev_stat\fP \- did the file attributes just change?" +.IX Subsection "ev_stat - did the file attributes just change?" +This watches a filesystem path for attribute changes. That is, it calls +\&\f(CW\*(C`stat\*(C'\fR regularly (or when the \s-1OS\s0 says it changed) and sees if it changed +compared to the last time, invoking the callback if it did. +.PP +The path does not need to exist: changing from \*(L"path exists\*(R" to \*(L"path does +not exist\*(R" is a status change like any other. The condition \*(L"path does +not exist\*(R" is signified by the \f(CW\*(C`st_nlink\*(C'\fR field being zero (which is +otherwise always forced to be at least one) and all the other fields of +the stat buffer having unspecified contents. +.PP +The path \fIshould\fR be absolute and \fImust not\fR end in a slash. If it is +relative and your working directory changes, the behaviour is undefined. +.PP +Since there is no standard to do this, the portable implementation simply +calls \f(CW\*(C`stat (2)\*(C'\fR regularly on the path to see if it changed somehow. You +can specify a recommended polling interval for this case. If you specify +a polling interval of \f(CW0\fR (highly recommended!) then a \fIsuitable, +unspecified default\fR value will be used (which you can expect to be around +five seconds, although this might change dynamically). Libev will also +impose a minimum interval which is currently around \f(CW0.1\fR, but thats +usually overkill. +.PP +This watcher type is not meant for massive numbers of stat watchers, +as even with OS-supported change notifications, this can be +resource-intensive. +.PP +At the time of this writing, only the Linux inotify interface is +implemented (implementing kqueue support is left as an exercise for the +reader, note, however, that the author sees no way of implementing ev_stat +semantics with kqueue). Inotify will be used to give hints only and should +not change the semantics of \f(CW\*(C`ev_stat\*(C'\fR watchers, which means that libev +sometimes needs to fall back to regular polling again even with inotify, +but changes are usually detected immediately, and if the file exists there +will be no polling. +.PP +\fI\s-1ABI\s0 Issues (Largefile Support)\fR +.IX Subsection "ABI Issues (Largefile Support)" +.PP +Libev by default (unless the user overrides this) uses the default +compilation environment, which means that on systems with optionally +disabled large file support, you get the 32 bit version of the stat +structure. When using the library from programs that change the \s-1ABI\s0 to +use 64 bit file offsets the programs will fail. In that case you have to +compile libev with the same flags to get binary compatibility. This is +obviously the case with any flags that change the \s-1ABI\s0, but the problem is +most noticably with ev_stat and largefile support. +.PP +\fIInotify\fR +.IX Subsection "Inotify" +.PP +When \f(CW\*(C`inotify (7)\*(C'\fR support has been compiled into libev (generally only +available on Linux) and present at runtime, it will be used to speed up +change detection where possible. The inotify descriptor will be created lazily +when the first \f(CW\*(C`ev_stat\*(C'\fR watcher is being started. +.PP +Inotify presence does not change the semantics of \f(CW\*(C`ev_stat\*(C'\fR watchers +except that changes might be detected earlier, and in some cases, to avoid +making regular \f(CW\*(C`stat\*(C'\fR calls. Even in the presence of inotify support +there are many cases where libev has to resort to regular \f(CW\*(C`stat\*(C'\fR polling. +.PP +(There is no support for kqueue, as apparently it cannot be used to +implement this functionality, due to the requirement of having a file +descriptor open on the object at all times). +.PP +\fIThe special problem of stat time resolution\fR +.IX Subsection "The special problem of stat time resolution" +.PP +The \f(CW\*(C`stat ()\*(C'\fR syscall only supports full-second resolution portably, and +even on systems where the resolution is higher, many filesystems still +only support whole seconds. +.PP +That means that, if the time is the only thing that changes, you can +easily miss updates: on the first update, \f(CW\*(C`ev_stat\*(C'\fR detects a change and +calls your callback, which does something. When there is another update +within the same second, \f(CW\*(C`ev_stat\*(C'\fR will be unable to detect it as the stat +data does not change. +.PP +The solution to this is to delay acting on a change for slightly more +than second (or till slightly after the next full second boundary), using +a roughly one-second-delay \f(CW\*(C`ev_timer\*(C'\fR (e.g. \f(CW\*(C`ev_timer_set (w, 0., 1.02); +ev_timer_again (loop, w)\*(C'\fR). +.PP +The \f(CW.02\fR offset is added to work around small timing inconsistencies +of some operating systems (where the second counter of the current time +might be be delayed. One such system is the Linux kernel, where a call to +\&\f(CW\*(C`gettimeofday\*(C'\fR might return a timestamp with a full second later than +a subsequent \f(CW\*(C`time\*(C'\fR call \- if the equivalent of \f(CW\*(C`time ()\*(C'\fR is used to +update file times then there will be a small window where the kernel uses +the previous second to update file times but libev might already execute +the timer callback). +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)" 4 +.IX Item "ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval)" +.PD 0 +.IP "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)" 4 +.IX Item "ev_stat_set (ev_stat *, const char *path, ev_tstamp interval)" +.PD +Configures the watcher to wait for status changes of the given +\&\f(CW\*(C`path\*(C'\fR. The \f(CW\*(C`interval\*(C'\fR is a hint on how quickly a change is expected to +be detected and should normally be specified as \f(CW0\fR to let libev choose +a suitable value. The memory pointed to by \f(CW\*(C`path\*(C'\fR must point to the same +path for as long as the watcher is active. +.Sp +The callback will receive \f(CW\*(C`EV_STAT\*(C'\fR when a change was detected, relative +to the attributes at the time the watcher was started (or the last change +was detected). +.IP "ev_stat_stat (loop, ev_stat *)" 4 +.IX Item "ev_stat_stat (loop, ev_stat *)" +Updates the stat buffer immediately with new values. If you change the +watched path in your callback, you could call this function to avoid +detecting this change (while introducing a race condition if you are not +the only one changing the path). Can also be useful simply to find out the +new values. +.IP "ev_statdata attr [read\-only]" 4 +.IX Item "ev_statdata attr [read-only]" +The most-recently detected attributes of the file. Although the type is +\&\f(CW\*(C`ev_statdata\*(C'\fR, this is usually the (or one of the) \f(CW\*(C`struct stat\*(C'\fR types +suitable for your system, but you can only rely on the POSIX-standardised +members to be present. If the \f(CW\*(C`st_nlink\*(C'\fR member is \f(CW0\fR, then there was +some error while \f(CW\*(C`stat\*(C'\fRing the file. +.IP "ev_statdata prev [read\-only]" 4 +.IX Item "ev_statdata prev [read-only]" +The previous attributes of the file. The callback gets invoked whenever +\&\f(CW\*(C`prev\*(C'\fR != \f(CW\*(C`attr\*(C'\fR, or, more precisely, one or more of these members +differ: \f(CW\*(C`st_dev\*(C'\fR, \f(CW\*(C`st_ino\*(C'\fR, \f(CW\*(C`st_mode\*(C'\fR, \f(CW\*(C`st_nlink\*(C'\fR, \f(CW\*(C`st_uid\*(C'\fR, +\&\f(CW\*(C`st_gid\*(C'\fR, \f(CW\*(C`st_rdev\*(C'\fR, \f(CW\*(C`st_size\*(C'\fR, \f(CW\*(C`st_atime\*(C'\fR, \f(CW\*(C`st_mtime\*(C'\fR, \f(CW\*(C`st_ctime\*(C'\fR. +.IP "ev_tstamp interval [read\-only]" 4 +.IX Item "ev_tstamp interval [read-only]" +The specified interval. +.IP "const char *path [read\-only]" 4 +.IX Item "const char *path [read-only]" +The filesystem path that is being watched. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Watch \f(CW\*(C`/etc/passwd\*(C'\fR for attribute changes. +.PP +.Vb 10 +\& static void +\& passwd_cb (struct ev_loop *loop, ev_stat *w, int revents) +\& { +\& /* /etc/passwd changed in some way */ +\& if (w\->attr.st_nlink) +\& { +\& printf ("passwd current size %ld\en", (long)w\->attr.st_size); +\& printf ("passwd current atime %ld\en", (long)w\->attr.st_mtime); +\& printf ("passwd current mtime %ld\en", (long)w\->attr.st_mtime); +\& } +\& else +\& /* you shalt not abuse printf for puts */ +\& puts ("wow, /etc/passwd is not there, expect problems. " +\& "if this is windows, they already arrived\en"); +\& } +\& +\& ... +\& ev_stat passwd; +\& +\& ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.); +\& ev_stat_start (loop, &passwd); +.Ve +.PP +Example: Like above, but additionally use a one-second delay so we do not +miss updates (however, frequent updates will delay processing, too, so +one might do the work both on \f(CW\*(C`ev_stat\*(C'\fR callback invocation \fIand\fR on +\&\f(CW\*(C`ev_timer\*(C'\fR callback invocation). +.PP +.Vb 2 +\& static ev_stat passwd; +\& static ev_timer timer; +\& +\& static void +\& timer_cb (EV_P_ ev_timer *w, int revents) +\& { +\& ev_timer_stop (EV_A_ w); +\& +\& /* now it\*(Aqs one second after the most recent passwd change */ +\& } +\& +\& static void +\& stat_cb (EV_P_ ev_stat *w, int revents) +\& { +\& /* reset the one\-second timer */ +\& ev_timer_again (EV_A_ &timer); +\& } +\& +\& ... +\& ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.); +\& ev_stat_start (loop, &passwd); +\& ev_timer_init (&timer, timer_cb, 0., 1.02); +.Ve +.ie n .Sh """ev_idle"" \- when you've got nothing better to do..." +.el .Sh "\f(CWev_idle\fP \- when you've got nothing better to do..." +.IX Subsection "ev_idle - when you've got nothing better to do..." +Idle watchers trigger events when no other events of the same or higher +priority are pending (prepare, check and other idle watchers do not +count). +.PP +That is, as long as your process is busy handling sockets or timeouts +(or even signals, imagine) of the same or higher priority it will not be +triggered. But when your process is idle (or only lower-priority watchers +are pending), the idle watchers are being called once per event loop +iteration \- until stopped, that is, or your process receives more events +and becomes busy again with higher priority stuff. +.PP +The most noteworthy effect is that as long as any idle watchers are +active, the process will not block when waiting for new events. +.PP +Apart from keeping your process non-blocking (which is a useful +effect on its own sometimes), idle watchers are a good place to do +\&\*(L"pseudo-background processing\*(R", or delay processing stuff to after the +event loop has handled all outstanding events. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_idle_init (ev_signal *, callback)" 4 +.IX Item "ev_idle_init (ev_signal *, callback)" +Initialises and configures the idle watcher \- it has no parameters of any +kind. There is a \f(CW\*(C`ev_idle_set\*(C'\fR macro, but using it is utterly pointless, +believe me. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Dynamically allocate an \f(CW\*(C`ev_idle\*(C'\fR watcher, start it, and in the +callback, free it. Also, use no error checking, as usual. +.PP +.Vb 7 +\& static void +\& idle_cb (struct ev_loop *loop, struct ev_idle *w, int revents) +\& { +\& free (w); +\& // now do something you wanted to do when the program has +\& // no longer anything immediate to do. +\& } +\& +\& struct ev_idle *idle_watcher = malloc (sizeof (struct ev_idle)); +\& ev_idle_init (idle_watcher, idle_cb); +\& ev_idle_start (loop, idle_cb); +.Ve +.ie n .Sh """ev_prepare""\fP and \f(CW""ev_check"" \- customise your event loop!" +.el .Sh "\f(CWev_prepare\fP and \f(CWev_check\fP \- customise your event loop!" +.IX Subsection "ev_prepare and ev_check - customise your event loop!" +Prepare and check watchers are usually (but not always) used in tandem: +prepare watchers get invoked before the process blocks and check watchers +afterwards. +.PP +You \fImust not\fR call \f(CW\*(C`ev_loop\*(C'\fR or similar functions that enter +the current event loop from either \f(CW\*(C`ev_prepare\*(C'\fR or \f(CW\*(C`ev_check\*(C'\fR +watchers. Other loops than the current one are fine, however. The +rationale behind this is that you do not need to check for recursion in +those watchers, i.e. the sequence will always be \f(CW\*(C`ev_prepare\*(C'\fR, blocking, +\&\f(CW\*(C`ev_check\*(C'\fR so if you have one watcher of each kind they will always be +called in pairs bracketing the blocking call. +.PP +Their main purpose is to integrate other event mechanisms into libev and +their use is somewhat advanced. This could be used, for example, to track +variable changes, implement your own watchers, integrate net-snmp or a +coroutine library and lots more. They are also occasionally useful if +you cache some data and want to flush it before blocking (for example, +in X programs you might want to do an \f(CW\*(C`XFlush ()\*(C'\fR in an \f(CW\*(C`ev_prepare\*(C'\fR +watcher). +.PP +This is done by examining in each prepare call which file descriptors need +to be watched by the other library, registering \f(CW\*(C`ev_io\*(C'\fR watchers for +them and starting an \f(CW\*(C`ev_timer\*(C'\fR watcher for any timeouts (many libraries +provide just this functionality). Then, in the check watcher you check for +any events that occured (by checking the pending status of all watchers +and stopping them) and call back into the library. The I/O and timer +callbacks will never actually be called (but must be valid nevertheless, +because you never know, you know?). +.PP +As another example, the Perl Coro module uses these hooks to integrate +coroutines into libev programs, by yielding to other active coroutines +during each prepare and only letting the process block if no coroutines +are ready to run (it's actually more complicated: it only runs coroutines +with priority higher than or equal to the event loop and one coroutine +of lower priority, but only once, using idle watchers to keep the event +loop from blocking if lower-priority coroutines are active, thus mapping +low-priority coroutines to idle/background tasks). +.PP +It is recommended to give \f(CW\*(C`ev_check\*(C'\fR watchers highest (\f(CW\*(C`EV_MAXPRI\*(C'\fR) +priority, to ensure that they are being run before any other watchers +after the poll. Also, \f(CW\*(C`ev_check\*(C'\fR watchers (and \f(CW\*(C`ev_prepare\*(C'\fR watchers, +too) should not activate (\*(L"feed\*(R") events into libev. While libev fully +supports this, they might get executed before other \f(CW\*(C`ev_check\*(C'\fR watchers +did their job. As \f(CW\*(C`ev_check\*(C'\fR watchers are often used to embed other +(non-libev) event loops those other event loops might be in an unusable +state until their \f(CW\*(C`ev_check\*(C'\fR watcher ran (always remind yourself to +coexist peacefully with others). +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_prepare_init (ev_prepare *, callback)" 4 +.IX Item "ev_prepare_init (ev_prepare *, callback)" +.PD 0 +.IP "ev_check_init (ev_check *, callback)" 4 +.IX Item "ev_check_init (ev_check *, callback)" +.PD +Initialises and configures the prepare or check watcher \- they have no +parameters of any kind. There are \f(CW\*(C`ev_prepare_set\*(C'\fR and \f(CW\*(C`ev_check_set\*(C'\fR +macros, but using them is utterly, utterly and completely pointless. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +There are a number of principal ways to embed other event loops or modules +into libev. Here are some ideas on how to include libadns into libev +(there is a Perl module named \f(CW\*(C`EV::ADNS\*(C'\fR that does this, which you could +use as a working example. Another Perl module named \f(CW\*(C`EV::Glib\*(C'\fR embeds a +Glib main context into libev, and finally, \f(CW\*(C`Glib::EV\*(C'\fR embeds \s-1EV\s0 into the +Glib event loop). +.PP +Method 1: Add \s-1IO\s0 watchers and a timeout watcher in a prepare handler, +and in a check watcher, destroy them and call into libadns. What follows +is pseudo-code only of course. This requires you to either use a low +priority for the check watcher or use \f(CW\*(C`ev_clear_pending\*(C'\fR explicitly, as +the callbacks for the IO/timeout watchers might not have been called yet. +.PP +.Vb 2 +\& static ev_io iow [nfd]; +\& static ev_timer tw; +\& +\& static void +\& io_cb (ev_loop *loop, ev_io *w, int revents) +\& { +\& } +\& +\& // create io watchers for each fd and a timer before blocking +\& static void +\& adns_prepare_cb (ev_loop *loop, ev_prepare *w, int revents) +\& { +\& int timeout = 3600000; +\& struct pollfd fds [nfd]; +\& // actual code will need to loop here and realloc etc. +\& adns_beforepoll (ads, fds, &nfd, &timeout, timeval_from (ev_time ())); +\& +\& /* the callback is illegal, but won\*(Aqt be called as we stop during check */ +\& ev_timer_init (&tw, 0, timeout * 1e\-3); +\& ev_timer_start (loop, &tw); +\& +\& // create one ev_io per pollfd +\& for (int i = 0; i < nfd; ++i) +\& { +\& ev_io_init (iow + i, io_cb, fds [i].fd, +\& ((fds [i].events & POLLIN ? EV_READ : 0) +\& | (fds [i].events & POLLOUT ? EV_WRITE : 0))); +\& +\& fds [i].revents = 0; +\& ev_io_start (loop, iow + i); +\& } +\& } +\& +\& // stop all watchers after blocking +\& static void +\& adns_check_cb (ev_loop *loop, ev_check *w, int revents) +\& { +\& ev_timer_stop (loop, &tw); +\& +\& for (int i = 0; i < nfd; ++i) +\& { +\& // set the relevant poll flags +\& // could also call adns_processreadable etc. here +\& struct pollfd *fd = fds + i; +\& int revents = ev_clear_pending (iow + i); +\& if (revents & EV_READ ) fd\->revents |= fd\->events & POLLIN; +\& if (revents & EV_WRITE) fd\->revents |= fd\->events & POLLOUT; +\& +\& // now stop the watcher +\& ev_io_stop (loop, iow + i); +\& } +\& +\& adns_afterpoll (adns, fds, nfd, timeval_from (ev_now (loop)); +\& } +.Ve +.PP +Method 2: This would be just like method 1, but you run \f(CW\*(C`adns_afterpoll\*(C'\fR +in the prepare watcher and would dispose of the check watcher. +.PP +Method 3: If the module to be embedded supports explicit event +notification (adns does), you can also make use of the actual watcher +callbacks, and only destroy/create the watchers in the prepare watcher. +.PP +.Vb 5 +\& static void +\& timer_cb (EV_P_ ev_timer *w, int revents) +\& { +\& adns_state ads = (adns_state)w\->data; +\& update_now (EV_A); +\& +\& adns_processtimeouts (ads, &tv_now); +\& } +\& +\& static void +\& io_cb (EV_P_ ev_io *w, int revents) +\& { +\& adns_state ads = (adns_state)w\->data; +\& update_now (EV_A); +\& +\& if (revents & EV_READ ) adns_processreadable (ads, w\->fd, &tv_now); +\& if (revents & EV_WRITE) adns_processwriteable (ads, w\->fd, &tv_now); +\& } +\& +\& // do not ever call adns_afterpoll +.Ve +.PP +Method 4: Do not use a prepare or check watcher because the module you +want to embed is too inflexible to support it. Instead, youc na override +their poll function. The drawback with this solution is that the main +loop is now no longer controllable by \s-1EV\s0. The \f(CW\*(C`Glib::EV\*(C'\fR module does +this. +.PP +.Vb 4 +\& static gint +\& event_poll_func (GPollFD *fds, guint nfds, gint timeout) +\& { +\& int got_events = 0; +\& +\& for (n = 0; n < nfds; ++n) +\& // create/start io watcher that sets the relevant bits in fds[n] and increment got_events +\& +\& if (timeout >= 0) +\& // create/start timer +\& +\& // poll +\& ev_loop (EV_A_ 0); +\& +\& // stop timer again +\& if (timeout >= 0) +\& ev_timer_stop (EV_A_ &to); +\& +\& // stop io watchers again \- their callbacks should have set +\& for (n = 0; n < nfds; ++n) +\& ev_io_stop (EV_A_ iow [n]); +\& +\& return got_events; +\& } +.Ve +.ie n .Sh """ev_embed"" \- when one backend isn't enough..." +.el .Sh "\f(CWev_embed\fP \- when one backend isn't enough..." +.IX Subsection "ev_embed - when one backend isn't enough..." +This is a rather advanced watcher type that lets you embed one event loop +into another (currently only \f(CW\*(C`ev_io\*(C'\fR events are supported in the embedded +loop, other types of watchers might be handled in a delayed or incorrect +fashion and must not be used). +.PP +There are primarily two reasons you would want that: work around bugs and +prioritise I/O. +.PP +As an example for a bug workaround, the kqueue backend might only support +sockets on some platform, so it is unusable as generic backend, but you +still want to make use of it because you have many sockets and it scales +so nicely. In this case, you would create a kqueue-based loop and embed it +into your default loop (which might use e.g. poll). Overall operation will +be a bit slower because first libev has to poll and then call kevent, but +at least you can use both at what they are best. +.PP +As for prioritising I/O: rarely you have the case where some fds have +to be watched and handled very quickly (with low latency), and even +priorities and idle watchers might have too much overhead. In this case +you would put all the high priority stuff in one loop and all the rest in +a second one, and embed the second one in the first. +.PP +As long as the watcher is active, the callback will be invoked every time +there might be events pending in the embedded loop. The callback must then +call \f(CW\*(C`ev_embed_sweep (mainloop, watcher)\*(C'\fR to make a single sweep and invoke +their callbacks (you could also start an idle watcher to give the embedded +loop strictly lower priority for example). You can also set the callback +to \f(CW0\fR, in which case the embed watcher will automatically execute the +embedded loop sweep. +.PP +As long as the watcher is started it will automatically handle events. The +callback will be invoked whenever some events have been handled. You can +set the callback to \f(CW0\fR to avoid having to specify one if you are not +interested in that. +.PP +Also, there have not currently been made special provisions for forking: +when you fork, you not only have to call \f(CW\*(C`ev_loop_fork\*(C'\fR on both loops, +but you will also have to stop and restart any \f(CW\*(C`ev_embed\*(C'\fR watchers +yourself. +.PP +Unfortunately, not all backends are embeddable, only the ones returned by +\&\f(CW\*(C`ev_embeddable_backends\*(C'\fR are, which, unfortunately, does not include any +portable one. +.PP +So when you want to use this feature you will always have to be prepared +that you cannot get an embeddable loop. The recommended way to get around +this is to have a separate variables for your embeddable loop, try to +create it, and if that fails, use the normal loop for everything. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" 4 +.IX Item "ev_embed_init (ev_embed *, callback, struct ev_loop *embedded_loop)" +.PD 0 +.IP "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" 4 +.IX Item "ev_embed_set (ev_embed *, callback, struct ev_loop *embedded_loop)" +.PD +Configures the watcher to embed the given loop, which must be +embeddable. If the callback is \f(CW0\fR, then \f(CW\*(C`ev_embed_sweep\*(C'\fR will be +invoked automatically, otherwise it is the responsibility of the callback +to invoke it (it will continue to be called until the sweep has been done, +if you do not want thta, you need to temporarily stop the embed watcher). +.IP "ev_embed_sweep (loop, ev_embed *)" 4 +.IX Item "ev_embed_sweep (loop, ev_embed *)" +Make a single, non-blocking sweep over the embedded loop. This works +similarly to \f(CW\*(C`ev_loop (embedded_loop, EVLOOP_NONBLOCK)\*(C'\fR, but in the most +apropriate way for embedded loops. +.IP "struct ev_loop *other [read\-only]" 4 +.IX Item "struct ev_loop *other [read-only]" +The embedded event loop. +.PP +\fIExamples\fR +.IX Subsection "Examples" +.PP +Example: Try to get an embeddable event loop and embed it into the default +event loop. If that is not possible, use the default loop. The default +loop is stored in \f(CW\*(C`loop_hi\*(C'\fR, while the mebeddable loop is stored in +\&\f(CW\*(C`loop_lo\*(C'\fR (which is \f(CW\*(C`loop_hi\*(C'\fR in the acse no embeddable loop can be +used). +.PP +.Vb 3 +\& struct ev_loop *loop_hi = ev_default_init (0); +\& struct ev_loop *loop_lo = 0; +\& struct ev_embed embed; +\& +\& // see if there is a chance of getting one that works +\& // (remember that a flags value of 0 means autodetection) +\& loop_lo = ev_embeddable_backends () & ev_recommended_backends () +\& ? ev_loop_new (ev_embeddable_backends () & ev_recommended_backends ()) +\& : 0; +\& +\& // if we got one, then embed it, otherwise default to loop_hi +\& if (loop_lo) +\& { +\& ev_embed_init (&embed, 0, loop_lo); +\& ev_embed_start (loop_hi, &embed); +\& } +\& else +\& loop_lo = loop_hi; +.Ve +.PP +Example: Check if kqueue is available but not recommended and create +a kqueue backend for use with sockets (which usually work with any +kqueue implementation). Store the kqueue/socket\-only event loop in +\&\f(CW\*(C`loop_socket\*(C'\fR. (One might optionally use \f(CW\*(C`EVFLAG_NOENV\*(C'\fR, too). +.PP +.Vb 3 +\& struct ev_loop *loop = ev_default_init (0); +\& struct ev_loop *loop_socket = 0; +\& struct ev_embed embed; +\& +\& if (ev_supported_backends () & ~ev_recommended_backends () & EVBACKEND_KQUEUE) +\& if ((loop_socket = ev_loop_new (EVBACKEND_KQUEUE)) +\& { +\& ev_embed_init (&embed, 0, loop_socket); +\& ev_embed_start (loop, &embed); +\& } +\& +\& if (!loop_socket) +\& loop_socket = loop; +\& +\& // now use loop_socket for all sockets, and loop for everything else +.Ve +.ie n .Sh """ev_fork"" \- the audacity to resume the event loop after a fork" +.el .Sh "\f(CWev_fork\fP \- the audacity to resume the event loop after a fork" +.IX Subsection "ev_fork - the audacity to resume the event loop after a fork" +Fork watchers are called when a \f(CW\*(C`fork ()\*(C'\fR was detected (usually because +whoever is a good citizen cared to tell libev about it by calling +\&\f(CW\*(C`ev_default_fork\*(C'\fR or \f(CW\*(C`ev_loop_fork\*(C'\fR). The invocation is done before the +event loop blocks next and before \f(CW\*(C`ev_check\*(C'\fR watchers are being called, +and only in the child after the fork. If whoever good citizen calling +\&\f(CW\*(C`ev_default_fork\*(C'\fR cheats and calls it in the wrong process, the fork +handlers will be invoked, too, of course. +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_fork_init (ev_signal *, callback)" 4 +.IX Item "ev_fork_init (ev_signal *, callback)" +Initialises and configures the fork watcher \- it has no parameters of any +kind. There is a \f(CW\*(C`ev_fork_set\*(C'\fR macro, but using it is utterly pointless, +believe me. +.ie n .Sh """ev_async"" \- how to wake up another event loop" +.el .Sh "\f(CWev_async\fP \- how to wake up another event loop" +.IX Subsection "ev_async - how to wake up another event loop" +In general, you cannot use an \f(CW\*(C`ev_loop\*(C'\fR from multiple threads or other +asynchronous sources such as signal handlers (as opposed to multiple event +loops \- those are of course safe to use in different threads). +.PP +Sometimes, however, you need to wake up another event loop you do not +control, for example because it belongs to another thread. This is what +\&\f(CW\*(C`ev_async\*(C'\fR watchers do: as long as the \f(CW\*(C`ev_async\*(C'\fR watcher is active, you +can signal it by calling \f(CW\*(C`ev_async_send\*(C'\fR, which is thread\- and signal +safe. +.PP +This functionality is very similar to \f(CW\*(C`ev_signal\*(C'\fR watchers, as signals, +too, are asynchronous in nature, and signals, too, will be compressed +(i.e. the number of callback invocations may be less than the number of +\&\f(CW\*(C`ev_async_sent\*(C'\fR calls). +.PP +Unlike \f(CW\*(C`ev_signal\*(C'\fR watchers, \f(CW\*(C`ev_async\*(C'\fR works with any event loop, not +just the default loop. +.PP +\fIQueueing\fR +.IX Subsection "Queueing" +.PP +\&\f(CW\*(C`ev_async\*(C'\fR does not support queueing of data in any way. The reason +is that the author does not know of a simple (or any) algorithm for a +multiple-writer-single-reader queue that works in all cases and doesn't +need elaborate support such as pthreads. +.PP +That means that if you want to queue data, you have to provide your own +queue. But at least I can tell you would implement locking around your +queue: +.IP "queueing from a signal handler context" 4 +.IX Item "queueing from a signal handler context" +To implement race-free queueing, you simply add to the queue in the signal +handler but you block the signal handler in the watcher callback. Here is an example that does that for +some fictitiuous \s-1SIGUSR1\s0 handler: +.Sp +.Vb 1 +\& static ev_async mysig; +\& +\& static void +\& sigusr1_handler (void) +\& { +\& sometype data; +\& +\& // no locking etc. +\& queue_put (data); +\& ev_async_send (EV_DEFAULT_ &mysig); +\& } +\& +\& static void +\& mysig_cb (EV_P_ ev_async *w, int revents) +\& { +\& sometype data; +\& sigset_t block, prev; +\& +\& sigemptyset (&block); +\& sigaddset (&block, SIGUSR1); +\& sigprocmask (SIG_BLOCK, &block, &prev); +\& +\& while (queue_get (&data)) +\& process (data); +\& +\& if (sigismember (&prev, SIGUSR1) +\& sigprocmask (SIG_UNBLOCK, &block, 0); +\& } +.Ve +.Sp +(Note: pthreads in theory requires you to use \f(CW\*(C`pthread_setmask\*(C'\fR +instead of \f(CW\*(C`sigprocmask\*(C'\fR when you use threads, but libev doesn't do it +either...). +.IP "queueing from a thread context" 4 +.IX Item "queueing from a thread context" +The strategy for threads is different, as you cannot (easily) block +threads but you can easily preempt them, so to queue safely you need to +employ a traditional mutex lock, such as in this pthread example: +.Sp +.Vb 2 +\& static ev_async mysig; +\& static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; +\& +\& static void +\& otherthread (void) +\& { +\& // only need to lock the actual queueing operation +\& pthread_mutex_lock (&mymutex); +\& queue_put (data); +\& pthread_mutex_unlock (&mymutex); +\& +\& ev_async_send (EV_DEFAULT_ &mysig); +\& } +\& +\& static void +\& mysig_cb (EV_P_ ev_async *w, int revents) +\& { +\& pthread_mutex_lock (&mymutex); +\& +\& while (queue_get (&data)) +\& process (data); +\& +\& pthread_mutex_unlock (&mymutex); +\& } +.Ve +.PP +\fIWatcher-Specific Functions and Data Members\fR +.IX Subsection "Watcher-Specific Functions and Data Members" +.IP "ev_async_init (ev_async *, callback)" 4 +.IX Item "ev_async_init (ev_async *, callback)" +Initialises and configures the async watcher \- it has no parameters of any +kind. There is a \f(CW\*(C`ev_asynd_set\*(C'\fR macro, but using it is utterly pointless, +believe me. +.IP "ev_async_send (loop, ev_async *)" 4 +.IX Item "ev_async_send (loop, ev_async *)" +Sends/signals/activates the given \f(CW\*(C`ev_async\*(C'\fR watcher, that is, feeds +an \f(CW\*(C`EV_ASYNC\*(C'\fR event on the watcher into the event loop. Unlike +\&\f(CW\*(C`ev_feed_event\*(C'\fR, this call is safe to do in other threads, signal or +similar contexts (see the dicusssion of \f(CW\*(C`EV_ATOMIC_T\*(C'\fR in the embedding +section below on what exactly this means). +.Sp +This call incurs the overhead of a syscall only once per loop iteration, +so while the overhead might be noticable, it doesn't apply to repeated +calls to \f(CW\*(C`ev_async_send\*(C'\fR. +.IP "bool = ev_async_pending (ev_async *)" 4 +.IX Item "bool = ev_async_pending (ev_async *)" +Returns a non-zero value when \f(CW\*(C`ev_async_send\*(C'\fR has been called on the +watcher but the event has not yet been processed (or even noted) by the +event loop. +.Sp +\&\f(CW\*(C`ev_async_send\*(C'\fR sets a flag in the watcher and wakes up the loop. When +the loop iterates next and checks for the watcher to have become active, +it will reset the flag again. \f(CW\*(C`ev_async_pending\*(C'\fR can be used to very +quickly check wether invoking the loop might be a good idea. +.Sp +Not that this does \fInot\fR check wether the watcher itself is pending, only +wether it has been requested to make this watcher pending. +.SH "OTHER FUNCTIONS" +.IX Header "OTHER FUNCTIONS" +There are some other functions of possible interest. Described. Here. Now. +.IP "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)" 4 +.IX Item "ev_once (loop, int fd, int events, ev_tstamp timeout, callback)" +This function combines a simple timer and an I/O watcher, calls your +callback on whichever event happens first and automatically stop both +watchers. This is useful if you want to wait for a single event on an fd +or timeout without having to allocate/configure/start/stop/free one or +more watchers yourself. +.Sp +If \f(CW\*(C`fd\*(C'\fR is less than 0, then no I/O watcher will be started and events +is being ignored. Otherwise, an \f(CW\*(C`ev_io\*(C'\fR watcher for the given \f(CW\*(C`fd\*(C'\fR and +\&\f(CW\*(C`events\*(C'\fR set will be craeted and started. +.Sp +If \f(CW\*(C`timeout\*(C'\fR is less than 0, then no timeout watcher will be +started. Otherwise an \f(CW\*(C`ev_timer\*(C'\fR watcher with after = \f(CW\*(C`timeout\*(C'\fR (and +repeat = 0) will be started. While \f(CW0\fR is a valid timeout, it is of +dubious value. +.Sp +The callback has the type \f(CW\*(C`void (*cb)(int revents, void *arg)\*(C'\fR and gets +passed an \f(CW\*(C`revents\*(C'\fR set like normal event callbacks (a combination of +\&\f(CW\*(C`EV_ERROR\*(C'\fR, \f(CW\*(C`EV_READ\*(C'\fR, \f(CW\*(C`EV_WRITE\*(C'\fR or \f(CW\*(C`EV_TIMEOUT\*(C'\fR) and the \f(CW\*(C`arg\*(C'\fR +value passed to \f(CW\*(C`ev_once\*(C'\fR: +.Sp +.Vb 7 +\& static void stdin_ready (int revents, void *arg) +\& { +\& if (revents & EV_TIMEOUT) +\& /* doh, nothing entered */; +\& else if (revents & EV_READ) +\& /* stdin might have data for us, joy! */; +\& } +\& +\& ev_once (STDIN_FILENO, EV_READ, 10., stdin_ready, 0); +.Ve +.IP "ev_feed_event (ev_loop *, watcher *, int revents)" 4 +.IX Item "ev_feed_event (ev_loop *, watcher *, int revents)" +Feeds the given event set into the event loop, as if the specified event +had happened for the specified watcher (which must be a pointer to an +initialised but not necessarily started event watcher). +.IP "ev_feed_fd_event (ev_loop *, int fd, int revents)" 4 +.IX Item "ev_feed_fd_event (ev_loop *, int fd, int revents)" +Feed an event on the given fd, as if a file descriptor backend detected +the given events it. +.IP "ev_feed_signal_event (ev_loop *loop, int signum)" 4 +.IX Item "ev_feed_signal_event (ev_loop *loop, int signum)" +Feed an event as if the given signal occured (\f(CW\*(C`loop\*(C'\fR must be the default +loop!). +.SH "LIBEVENT EMULATION" +.IX Header "LIBEVENT EMULATION" +Libev offers a compatibility emulation layer for libevent. It cannot +emulate the internals of libevent, so here are some usage hints: +.IP "\(bu" 4 +Use it by including <event.h>, as usual. +.IP "\(bu" 4 +The following members are fully supported: ev_base, ev_callback, +ev_arg, ev_fd, ev_res, ev_events. +.IP "\(bu" 4 +Avoid using ev_flags and the EVLIST_*\-macros, while it is +maintained by libev, it does not work exactly the same way as in libevent (consider +it a private \s-1API\s0). +.IP "\(bu" 4 +Priorities are not currently supported. Initialising priorities +will fail and all watchers will have the same priority, even though there +is an ev_pri field. +.IP "\(bu" 4 +In libevent, the last base created gets the signals, in libev, the +first base created (== the default loop) gets the signals. +.IP "\(bu" 4 +Other members are not supported. +.IP "\(bu" 4 +The libev emulation is \fInot\fR \s-1ABI\s0 compatible to libevent, you need +to use the libev header file and library. +.SH "\*(C+ SUPPORT" +.IX Header " SUPPORT" +Libev comes with some simplistic wrapper classes for \*(C+ that mainly allow +you to use some convinience methods to start/stop watchers and also change +the callback model to a model using method callbacks on objects. +.PP +To use it, +.PP +.Vb 1 +\& #include <ev++.h> +.Ve +.PP +This automatically includes \fIev.h\fR and puts all of its definitions (many +of them macros) into the global namespace. All \*(C+ specific things are +put into the \f(CW\*(C`ev\*(C'\fR namespace. It should support all the same embedding +options as \fIev.h\fR, most notably \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR. +.PP +Care has been taken to keep the overhead low. The only data member the \*(C+ +classes add (compared to plain C\-style watchers) is the event loop pointer +that the watcher is associated with (or no additional members at all if +you disable \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR when embedding libev). +.PP +Currently, functions, and static and non-static member functions can be +used as callbacks. Other types should be easy to add as long as they only +need one additional pointer for context. If you need support for other +types of functors please contact the author (preferably after implementing +it). +.PP +Here is a list of things available in the \f(CW\*(C`ev\*(C'\fR namespace: +.ie n .IP """ev::READ""\fR, \f(CW""ev::WRITE"" etc." 4 +.el .IP "\f(CWev::READ\fR, \f(CWev::WRITE\fR etc." 4 +.IX Item "ev::READ, ev::WRITE etc." +These are just enum values with the same values as the \f(CW\*(C`EV_READ\*(C'\fR etc. +macros from \fIev.h\fR. +.ie n .IP """ev::tstamp""\fR, \f(CW""ev::now""" 4 +.el .IP "\f(CWev::tstamp\fR, \f(CWev::now\fR" 4 +.IX Item "ev::tstamp, ev::now" +Aliases to the same types/functions as with the \f(CW\*(C`ev_\*(C'\fR prefix. +.ie n .IP """ev::io""\fR, \f(CW""ev::timer""\fR, \f(CW""ev::periodic""\fR, \f(CW""ev::idle""\fR, \f(CW""ev::sig"" etc." 4 +.el .IP "\f(CWev::io\fR, \f(CWev::timer\fR, \f(CWev::periodic\fR, \f(CWev::idle\fR, \f(CWev::sig\fR etc." 4 +.IX Item "ev::io, ev::timer, ev::periodic, ev::idle, ev::sig etc." +For each \f(CW\*(C`ev_TYPE\*(C'\fR watcher in \fIev.h\fR there is a corresponding class of +the same name in the \f(CW\*(C`ev\*(C'\fR namespace, with the exception of \f(CW\*(C`ev_signal\*(C'\fR +which is called \f(CW\*(C`ev::sig\*(C'\fR to avoid clashes with the \f(CW\*(C`signal\*(C'\fR macro +defines by many implementations. +.Sp +All of those classes have these methods: +.RS 4 +.IP "ev::TYPE::TYPE ()" 4 +.IX Item "ev::TYPE::TYPE ()" +.PD 0 +.IP "ev::TYPE::TYPE (struct ev_loop *)" 4 +.IX Item "ev::TYPE::TYPE (struct ev_loop *)" +.IP "ev::TYPE::~TYPE" 4 +.IX Item "ev::TYPE::~TYPE" +.PD +The constructor (optionally) takes an event loop to associate the watcher +with. If it is omitted, it will use \f(CW\*(C`EV_DEFAULT\*(C'\fR. +.Sp +The constructor calls \f(CW\*(C`ev_init\*(C'\fR for you, which means you have to call the +\&\f(CW\*(C`set\*(C'\fR method before starting it. +.Sp +It will not set a callback, however: You have to call the templated \f(CW\*(C`set\*(C'\fR +method to set a callback before you can start the watcher. +.Sp +(The reason why you have to use a method is a limitation in \*(C+ which does +not allow explicit template arguments for constructors). +.Sp +The destructor automatically stops the watcher if it is active. +.IP "w\->set<class, &class::method> (object *)" 4 +.IX Item "w->set<class, &class::method> (object *)" +This method sets the callback method to call. The method has to have a +signature of \f(CW\*(C`void (*)(ev_TYPE &, int)\*(C'\fR, it receives the watcher as +first argument and the \f(CW\*(C`revents\*(C'\fR as second. The object must be given as +parameter and is stored in the \f(CW\*(C`data\*(C'\fR member of the watcher. +.Sp +This method synthesizes efficient thunking code to call your method from +the C callback that libev requires. If your compiler can inline your +callback (i.e. it is visible to it at the place of the \f(CW\*(C`set\*(C'\fR call and +your compiler is good :), then the method will be fully inlined into the +thunking function, making it as fast as a direct C callback. +.Sp +Example: simple class declaration and watcher initialisation +.Sp +.Vb 4 +\& struct myclass +\& { +\& void io_cb (ev::io &w, int revents) { } +\& } +\& +\& myclass obj; +\& ev::io iow; +\& iow.set <myclass, &myclass::io_cb> (&obj); +.Ve +.IP "w\->set<function> (void *data = 0)" 4 +.IX Item "w->set<function> (void *data = 0)" +Also sets a callback, but uses a static method or plain function as +callback. The optional \f(CW\*(C`data\*(C'\fR argument will be stored in the watcher's +\&\f(CW\*(C`data\*(C'\fR member and is free for you to use. +.Sp +The prototype of the \f(CW\*(C`function\*(C'\fR must be \f(CW\*(C`void (*)(ev::TYPE &w, int)\*(C'\fR. +.Sp +See the method\-\f(CW\*(C`set\*(C'\fR above for more details. +.Sp +Example: +.Sp +.Vb 2 +\& static void io_cb (ev::io &w, int revents) { } +\& iow.set <io_cb> (); +.Ve +.IP "w\->set (struct ev_loop *)" 4 +.IX Item "w->set (struct ev_loop *)" +Associates a different \f(CW\*(C`struct ev_loop\*(C'\fR with this watcher. You can only +do this when the watcher is inactive (and not pending either). +.IP "w\->set ([args])" 4 +.IX Item "w->set ([args])" +Basically the same as \f(CW\*(C`ev_TYPE_set\*(C'\fR, with the same args. Must be +called at least once. Unlike the C counterpart, an active watcher gets +automatically stopped and restarted when reconfiguring it with this +method. +.IP "w\->start ()" 4 +.IX Item "w->start ()" +Starts the watcher. Note that there is no \f(CW\*(C`loop\*(C'\fR argument, as the +constructor already stores the event loop. +.IP "w\->stop ()" 4 +.IX Item "w->stop ()" +Stops the watcher if it is active. Again, no \f(CW\*(C`loop\*(C'\fR argument. +.ie n .IP "w\->again () (""ev::timer""\fR, \f(CW""ev::periodic"" only)" 4 +.el .IP "w\->again () (\f(CWev::timer\fR, \f(CWev::periodic\fR only)" 4 +.IX Item "w->again () (ev::timer, ev::periodic only)" +For \f(CW\*(C`ev::timer\*(C'\fR and \f(CW\*(C`ev::periodic\*(C'\fR, this invokes the corresponding +\&\f(CW\*(C`ev_TYPE_again\*(C'\fR function. +.ie n .IP "w\->sweep () (""ev::embed"" only)" 4 +.el .IP "w\->sweep () (\f(CWev::embed\fR only)" 4 +.IX Item "w->sweep () (ev::embed only)" +Invokes \f(CW\*(C`ev_embed_sweep\*(C'\fR. +.ie n .IP "w\->update () (""ev::stat"" only)" 4 +.el .IP "w\->update () (\f(CWev::stat\fR only)" 4 +.IX Item "w->update () (ev::stat only)" +Invokes \f(CW\*(C`ev_stat_stat\*(C'\fR. +.RE +.RS 4 +.RE +.PP +Example: Define a class with an \s-1IO\s0 and idle watcher, start one of them in +the constructor. +.PP +.Vb 4 +\& class myclass +\& { +\& ev::io io; void io_cb (ev::io &w, int revents); +\& ev:idle idle void idle_cb (ev::idle &w, int revents); +\& +\& myclass (int fd) +\& { +\& io .set <myclass, &myclass::io_cb > (this); +\& idle.set <myclass, &myclass::idle_cb> (this); +\& +\& io.start (fd, ev::READ); +\& } +\& }; +.Ve +.SH "OTHER LANGUAGE BINDINGS" +.IX Header "OTHER LANGUAGE BINDINGS" +Libev does not offer other language bindings itself, but bindings for a +numbe rof languages exist in the form of third-party packages. If you know +any interesting language binding in addition to the ones listed here, drop +me a note. +.IP "Perl" 4 +.IX Item "Perl" +The \s-1EV\s0 module implements the full libev \s-1API\s0 and is actually used to test +libev. \s-1EV\s0 is developed together with libev. Apart from the \s-1EV\s0 core module, +there are additional modules that implement libev-compatible interfaces +to \f(CW\*(C`libadns\*(C'\fR (\f(CW\*(C`EV::ADNS\*(C'\fR), \f(CW\*(C`Net::SNMP\*(C'\fR (\f(CW\*(C`Net::SNMP::EV\*(C'\fR) and the +\&\f(CW\*(C`libglib\*(C'\fR event core (\f(CW\*(C`Glib::EV\*(C'\fR and \f(CW\*(C`EV::Glib\*(C'\fR). +.Sp +It can be found and installed via \s-1CPAN\s0, its homepage is found at +<http://software.schmorp.de/pkg/EV>. +.IP "Ruby" 4 +.IX Item "Ruby" +Tony Arcieri has written a ruby extension that offers access to a subset +of the libev \s-1API\s0 and adds filehandle abstractions, asynchronous \s-1DNS\s0 and +more on top of it. It can be found via gem servers. Its homepage is at +<http://rev.rubyforge.org/>. +.IP "D" 4 +.IX Item "D" +Leandro Lucarella has written a D language binding (\fIev.d\fR) for libev, to +be found at <http://git.llucax.com.ar/?p=software/ev.d.git;a=summary>. +.SH "MACRO MAGIC" +.IX Header "MACRO MAGIC" +Libev can be compiled with a variety of options, the most fundamantal +of which is \f(CW\*(C`EV_MULTIPLICITY\*(C'\fR. This option determines whether (most) +functions and callbacks have an initial \f(CW\*(C`struct ev_loop *\*(C'\fR argument. +.PP +To make it easier to write programs that cope with either variant, the +following macros are defined: +.ie n .IP """EV_A""\fR, \f(CW""EV_A_""" 4 +.el .IP "\f(CWEV_A\fR, \f(CWEV_A_\fR" 4 +.IX Item "EV_A, EV_A_" +This provides the loop \fIargument\fR for functions, if one is required (\*(L"ev +loop argument\*(R"). The \f(CW\*(C`EV_A\*(C'\fR form is used when this is the sole argument, +\&\f(CW\*(C`EV_A_\*(C'\fR is used when other arguments are following. Example: +.Sp +.Vb 3 +\& ev_unref (EV_A); +\& ev_timer_add (EV_A_ watcher); +\& ev_loop (EV_A_ 0); +.Ve +.Sp +It assumes the variable \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR is in scope, +which is often provided by the following macro. +.ie n .IP """EV_P""\fR, \f(CW""EV_P_""" 4 +.el .IP "\f(CWEV_P\fR, \f(CWEV_P_\fR" 4 +.IX Item "EV_P, EV_P_" +This provides the loop \fIparameter\fR for functions, if one is required (\*(L"ev +loop parameter\*(R"). The \f(CW\*(C`EV_P\*(C'\fR form is used when this is the sole parameter, +\&\f(CW\*(C`EV_P_\*(C'\fR is used when other parameters are following. Example: +.Sp +.Vb 2 +\& // this is how ev_unref is being declared +\& static void ev_unref (EV_P); +\& +\& // this is how you can declare your typical callback +\& static void cb (EV_P_ ev_timer *w, int revents) +.Ve +.Sp +It declares a parameter \f(CW\*(C`loop\*(C'\fR of type \f(CW\*(C`struct ev_loop *\*(C'\fR, quite +suitable for use with \f(CW\*(C`EV_A\*(C'\fR. +.ie n .IP """EV_DEFAULT""\fR, \f(CW""EV_DEFAULT_""" 4 +.el .IP "\f(CWEV_DEFAULT\fR, \f(CWEV_DEFAULT_\fR" 4 +.IX Item "EV_DEFAULT, EV_DEFAULT_" +Similar to the other two macros, this gives you the value of the default +loop, if multiple loops are supported (\*(L"ev loop default\*(R"). +.ie n .IP """EV_DEFAULT_UC""\fR, \f(CW""EV_DEFAULT_UC_""" 4 +.el .IP "\f(CWEV_DEFAULT_UC\fR, \f(CWEV_DEFAULT_UC_\fR" 4 +.IX Item "EV_DEFAULT_UC, EV_DEFAULT_UC_" +Usage identical to \f(CW\*(C`EV_DEFAULT\*(C'\fR and \f(CW\*(C`EV_DEFAULT_\*(C'\fR, but requires that the +default loop has been initialised (\f(CW\*(C`UC\*(C'\fR == unchecked). Their behaviour +is undefined when the default loop has not been initialised by a previous +execution of \f(CW\*(C`EV_DEFAULT\*(C'\fR, \f(CW\*(C`EV_DEFAULT_\*(C'\fR or \f(CW\*(C`ev_default_init (...)\*(C'\fR. +.Sp +It is often prudent to use \f(CW\*(C`EV_DEFAULT\*(C'\fR when initialising the first +watcher in a function but use \f(CW\*(C`EV_DEFAULT_UC\*(C'\fR afterwards. +.PP +Example: Declare and initialise a check watcher, utilising the above +macros so it will work regardless of whether multiple loops are supported +or not. +.PP +.Vb 5 +\& static void +\& check_cb (EV_P_ ev_timer *w, int revents) +\& { +\& ev_check_stop (EV_A_ w); +\& } +\& +\& ev_check check; +\& ev_check_init (&check, check_cb); +\& ev_check_start (EV_DEFAULT_ &check); +\& ev_loop (EV_DEFAULT_ 0); +.Ve +.SH "EMBEDDING" +.IX Header "EMBEDDING" +Libev can (and often is) directly embedded into host +applications. Examples of applications that embed it include the Deliantra +Game Server, the \s-1EV\s0 perl module, the \s-1GNU\s0 Virtual Private Ethernet (gvpe) +and rxvt-unicode. +.PP +The goal is to enable you to just copy the necessary files into your +source directory without having to change even a single line in them, so +you can easily upgrade by simply copying (or having a checked-out copy of +libev somewhere in your source tree). +.Sh "\s-1FILESETS\s0" +.IX Subsection "FILESETS" +Depending on what features you need you need to include one or more sets of files +in your app. +.PP +\fI\s-1CORE\s0 \s-1EVENT\s0 \s-1LOOP\s0\fR +.IX Subsection "CORE EVENT LOOP" +.PP +To include only the libev core (all the \f(CW\*(C`ev_*\*(C'\fR functions), with manual +configuration (no autoconf): +.PP +.Vb 2 +\& #define EV_STANDALONE 1 +\& #include "ev.c" +.Ve +.PP +This will automatically include \fIev.h\fR, too, and should be done in a +single C source file only to provide the function implementations. To use +it, do the same for \fIev.h\fR in all files wishing to use this \s-1API\s0 (best +done by writing a wrapper around \fIev.h\fR that you can include instead and +where you can put other configuration options): +.PP +.Vb 2 +\& #define EV_STANDALONE 1 +\& #include "ev.h" +.Ve +.PP +Both header files and implementation files can be compiled with a \*(C+ +compiler (at least, thats a stated goal, and breakage will be treated +as a bug). +.PP +You need the following files in your source tree, or in a directory +in your include path (e.g. in libev/ when using \-Ilibev): +.PP +.Vb 4 +\& ev.h +\& ev.c +\& ev_vars.h +\& ev_wrap.h +\& +\& ev_win32.c required on win32 platforms only +\& +\& ev_select.c only when select backend is enabled (which is enabled by default) +\& ev_poll.c only when poll backend is enabled (disabled by default) +\& ev_epoll.c only when the epoll backend is enabled (disabled by default) +\& ev_kqueue.c only when the kqueue backend is enabled (disabled by default) +\& ev_port.c only when the solaris port backend is enabled (disabled by default) +.Ve +.PP +\&\fIev.c\fR includes the backend files directly when enabled, so you only need +to compile this single file. +.PP +\fI\s-1LIBEVENT\s0 \s-1COMPATIBILITY\s0 \s-1API\s0\fR +.IX Subsection "LIBEVENT COMPATIBILITY API" +.PP +To include the libevent compatibility \s-1API\s0, also include: +.PP +.Vb 1 +\& #include "event.c" +.Ve +.PP +in the file including \fIev.c\fR, and: +.PP +.Vb 1 +\& #include "event.h" +.Ve +.PP +in the files that want to use the libevent \s-1API\s0. This also includes \fIev.h\fR. +.PP +You need the following additional files for this: +.PP +.Vb 2 +\& event.h +\& event.c +.Ve +.PP +\fI\s-1AUTOCONF\s0 \s-1SUPPORT\s0\fR +.IX Subsection "AUTOCONF SUPPORT" +.PP +Instead of using \f(CW\*(C`EV_STANDALONE=1\*(C'\fR and providing your config in +whatever way you want, you can also \f(CW\*(C`m4_include([libev.m4])\*(C'\fR in your +\&\fIconfigure.ac\fR and leave \f(CW\*(C`EV_STANDALONE\*(C'\fR undefined. \fIev.c\fR will then +include \fIconfig.h\fR and configure itself accordingly. +.PP +For this of course you need the m4 file: +.PP +.Vb 1 +\& libev.m4 +.Ve +.Sh "\s-1PREPROCESSOR\s0 \s-1SYMBOLS/MACROS\s0" +.IX Subsection "PREPROCESSOR SYMBOLS/MACROS" +Libev can be configured via a variety of preprocessor symbols you have to +define before including any of its files. The default in the absense of +autoconf is noted for every option. +.IP "\s-1EV_STANDALONE\s0" 4 +.IX Item "EV_STANDALONE" +Must always be \f(CW1\fR if you do not use autoconf configuration, which +keeps libev from including \fIconfig.h\fR, and it also defines dummy +implementations for some libevent functions (such as logging, which is not +supported). It will also not define any of the structs usually found in +\&\fIevent.h\fR that are not directly supported by the libev core alone. +.IP "\s-1EV_USE_MONOTONIC\s0" 4 +.IX Item "EV_USE_MONOTONIC" +If defined to be \f(CW1\fR, libev will try to detect the availability of the +monotonic clock option at both compiletime and runtime. Otherwise no use +of the monotonic clock option will be attempted. If you enable this, you +usually have to link against librt or something similar. Enabling it when +the functionality isn't available is safe, though, although you have +to make sure you link against any libraries where the \f(CW\*(C`clock_gettime\*(C'\fR +function is hiding in (often \fI\-lrt\fR). +.IP "\s-1EV_USE_REALTIME\s0" 4 +.IX Item "EV_USE_REALTIME" +If defined to be \f(CW1\fR, libev will try to detect the availability of the +realtime clock option at compiletime (and assume its availability at +runtime if successful). Otherwise no use of the realtime clock option will +be attempted. This effectively replaces \f(CW\*(C`gettimeofday\*(C'\fR by \f(CW\*(C`clock_get +(CLOCK_REALTIME, ...)\*(C'\fR and will not normally affect correctness. See the +note about libraries in the description of \f(CW\*(C`EV_USE_MONOTONIC\*(C'\fR, though. +.IP "\s-1EV_USE_NANOSLEEP\s0" 4 +.IX Item "EV_USE_NANOSLEEP" +If defined to be \f(CW1\fR, libev will assume that \f(CW\*(C`nanosleep ()\*(C'\fR is available +and will use it for delays. Otherwise it will use \f(CW\*(C`select ()\*(C'\fR. +.IP "\s-1EV_USE_EVENTFD\s0" 4 +.IX Item "EV_USE_EVENTFD" +If defined to be \f(CW1\fR, then libev will assume that \f(CW\*(C`eventfd ()\*(C'\fR is +available and will probe for kernel support at runtime. This will improve +\&\f(CW\*(C`ev_signal\*(C'\fR and \f(CW\*(C`ev_async\*(C'\fR performance and reduce resource consumption. +If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc +2.7 or newer, otherwise disabled. +.IP "\s-1EV_USE_SELECT\s0" 4 +.IX Item "EV_USE_SELECT" +If undefined or defined to be \f(CW1\fR, libev will compile in support for the +\&\f(CW\*(C`select\*(C'\fR(2) backend. No attempt at autodetection will be done: if no +other method takes over, select will be it. Otherwise the select backend +will not be compiled in. +.IP "\s-1EV_SELECT_USE_FD_SET\s0" 4 +.IX Item "EV_SELECT_USE_FD_SET" +If defined to \f(CW1\fR, then the select backend will use the system \f(CW\*(C`fd_set\*(C'\fR +structure. This is useful if libev doesn't compile due to a missing +\&\f(CW\*(C`NFDBITS\*(C'\fR or \f(CW\*(C`fd_mask\*(C'\fR definition or it misguesses the bitset layout on +exotic systems. This usually limits the range of file descriptors to some +low limit such as 1024 or might have other limitations (winsocket only +allows 64 sockets). The \f(CW\*(C`FD_SETSIZE\*(C'\fR macro, set before compilation, might +influence the size of the \f(CW\*(C`fd_set\*(C'\fR used. +.IP "\s-1EV_SELECT_IS_WINSOCKET\s0" 4 +.IX Item "EV_SELECT_IS_WINSOCKET" +When defined to \f(CW1\fR, the select backend will assume that +select/socket/connect etc. don't understand file descriptors but +wants osf handles on win32 (this is the case when the select to +be used is the winsock select). This means that it will call +\&\f(CW\*(C`_get_osfhandle\*(C'\fR on the fd to convert it to an \s-1OS\s0 handle. Otherwise, +it is assumed that all these functions actually work on fds, even +on win32. Should not be defined on non\-win32 platforms. +.IP "\s-1EV_FD_TO_WIN32_HANDLE\s0" 4 +.IX Item "EV_FD_TO_WIN32_HANDLE" +If \f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR is enabled, then libev needs a way to map +file descriptors to socket handles. When not defining this symbol (the +default), then libev will call \f(CW\*(C`_get_osfhandle\*(C'\fR, which is usually +correct. In some cases, programs use their own file descriptor management, +in which case they can provide this function to map fds to socket handles. +.IP "\s-1EV_USE_POLL\s0" 4 +.IX Item "EV_USE_POLL" +If defined to be \f(CW1\fR, libev will compile in support for the \f(CW\*(C`poll\*(C'\fR(2) +backend. Otherwise it will be enabled on non\-win32 platforms. It +takes precedence over select. +.IP "\s-1EV_USE_EPOLL\s0" 4 +.IX Item "EV_USE_EPOLL" +If defined to be \f(CW1\fR, libev will compile in support for the Linux +\&\f(CW\*(C`epoll\*(C'\fR(7) backend. Its availability will be detected at runtime, +otherwise another method will be used as fallback. This is the preferred +backend for GNU/Linux systems. If undefined, it will be enabled if the +headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled. +.IP "\s-1EV_USE_KQUEUE\s0" 4 +.IX Item "EV_USE_KQUEUE" +If defined to be \f(CW1\fR, libev will compile in support for the \s-1BSD\s0 style +\&\f(CW\*(C`kqueue\*(C'\fR(2) backend. Its actual availability will be detected at runtime, +otherwise another method will be used as fallback. This is the preferred +backend for \s-1BSD\s0 and BSD-like systems, although on most BSDs kqueue only +supports some types of fds correctly (the only platform we found that +supports ptys for example was NetBSD), so kqueue might be compiled in, but +not be used unless explicitly requested. The best way to use it is to find +out whether kqueue supports your type of fd properly and use an embedded +kqueue loop. +.IP "\s-1EV_USE_PORT\s0" 4 +.IX Item "EV_USE_PORT" +If defined to be \f(CW1\fR, libev will compile in support for the Solaris +10 port style backend. Its availability will be detected at runtime, +otherwise another method will be used as fallback. This is the preferred +backend for Solaris 10 systems. +.IP "\s-1EV_USE_DEVPOLL\s0" 4 +.IX Item "EV_USE_DEVPOLL" +reserved for future expansion, works like the \s-1USE\s0 symbols above. +.IP "\s-1EV_USE_INOTIFY\s0" 4 +.IX Item "EV_USE_INOTIFY" +If defined to be \f(CW1\fR, libev will compile in support for the Linux inotify +interface to speed up \f(CW\*(C`ev_stat\*(C'\fR watchers. Its actual availability will +be detected at runtime. If undefined, it will be enabled if the headers +indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled. +.IP "\s-1EV_ATOMIC_T\s0" 4 +.IX Item "EV_ATOMIC_T" +Libev requires an integer type (suitable for storing \f(CW0\fR or \f(CW1\fR) whose +access is atomic with respect to other threads or signal contexts. No such +type is easily found in the C language, so you can provide your own type +that you know is safe for your purposes. It is used both for signal handler \*(L"locking\*(R" +as well as for signal and thread safety in \f(CW\*(C`ev_async\*(C'\fR watchers. +.Sp +In the absense of this define, libev will use \f(CW\*(C`sig_atomic_t volatile\*(C'\fR +(from \fIsignal.h\fR), which is usually good enough on most platforms. +.IP "\s-1EV_H\s0" 4 +.IX Item "EV_H" +The name of the \fIev.h\fR header file used to include it. The default if +undefined is \f(CW"ev.h"\fR in \fIevent.h\fR, \fIev.c\fR and \fIev++.h\fR. This can be +used to virtually rename the \fIev.h\fR header file in case of conflicts. +.IP "\s-1EV_CONFIG_H\s0" 4 +.IX Item "EV_CONFIG_H" +If \f(CW\*(C`EV_STANDALONE\*(C'\fR isn't \f(CW1\fR, this variable can be used to override +\&\fIev.c\fR's idea of where to find the \fIconfig.h\fR file, similarly to +\&\f(CW\*(C`EV_H\*(C'\fR, above. +.IP "\s-1EV_EVENT_H\s0" 4 +.IX Item "EV_EVENT_H" +Similarly to \f(CW\*(C`EV_H\*(C'\fR, this macro can be used to override \fIevent.c\fR's idea +of how the \fIevent.h\fR header can be found, the default is \f(CW"event.h"\fR. +.IP "\s-1EV_PROTOTYPES\s0" 4 +.IX Item "EV_PROTOTYPES" +If defined to be \f(CW0\fR, then \fIev.h\fR will not define any function +prototypes, but still define all the structs and other symbols. This is +occasionally useful if you want to provide your own wrapper functions +around libev functions. +.IP "\s-1EV_MULTIPLICITY\s0" 4 +.IX Item "EV_MULTIPLICITY" +If undefined or defined to \f(CW1\fR, then all event-loop-specific functions +will have the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument, and you can create +additional independent event loops. Otherwise there will be no support +for multiple event loops and there is no first event loop pointer +argument. Instead, all functions act on the single default loop. +.IP "\s-1EV_MINPRI\s0" 4 +.IX Item "EV_MINPRI" +.PD 0 +.IP "\s-1EV_MAXPRI\s0" 4 +.IX Item "EV_MAXPRI" +.PD +The range of allowed priorities. \f(CW\*(C`EV_MINPRI\*(C'\fR must be smaller or equal to +\&\f(CW\*(C`EV_MAXPRI\*(C'\fR, but otherwise there are no non-obvious limitations. You can +provide for more priorities by overriding those symbols (usually defined +to be \f(CW\*(C`\-2\*(C'\fR and \f(CW2\fR, respectively). +.Sp +When doing priority-based operations, libev usually has to linearly search +all the priorities, so having many of them (hundreds) uses a lot of space +and time, so using the defaults of five priorities (\-2 .. +2) is usually +fine. +.Sp +If your embedding app does not need any priorities, defining these both to +\&\f(CW0\fR will save some memory and cpu. +.IP "\s-1EV_PERIODIC_ENABLE\s0" 4 +.IX Item "EV_PERIODIC_ENABLE" +If undefined or defined to be \f(CW1\fR, then periodic timers are supported. If +defined to be \f(CW0\fR, then they are not. Disabling them saves a few kB of +code. +.IP "\s-1EV_IDLE_ENABLE\s0" 4 +.IX Item "EV_IDLE_ENABLE" +If undefined or defined to be \f(CW1\fR, then idle watchers are supported. If +defined to be \f(CW0\fR, then they are not. Disabling them saves a few kB of +code. +.IP "\s-1EV_EMBED_ENABLE\s0" 4 +.IX Item "EV_EMBED_ENABLE" +If undefined or defined to be \f(CW1\fR, then embed watchers are supported. If +defined to be \f(CW0\fR, then they are not. +.IP "\s-1EV_STAT_ENABLE\s0" 4 +.IX Item "EV_STAT_ENABLE" +If undefined or defined to be \f(CW1\fR, then stat watchers are supported. If +defined to be \f(CW0\fR, then they are not. +.IP "\s-1EV_FORK_ENABLE\s0" 4 +.IX Item "EV_FORK_ENABLE" +If undefined or defined to be \f(CW1\fR, then fork watchers are supported. If +defined to be \f(CW0\fR, then they are not. +.IP "\s-1EV_ASYNC_ENABLE\s0" 4 +.IX Item "EV_ASYNC_ENABLE" +If undefined or defined to be \f(CW1\fR, then async watchers are supported. If +defined to be \f(CW0\fR, then they are not. +.IP "\s-1EV_MINIMAL\s0" 4 +.IX Item "EV_MINIMAL" +If you need to shave off some kilobytes of code at the expense of some +speed, define this symbol to \f(CW1\fR. Currently this is used to override some +inlining decisions, saves roughly 30% codesize of amd64. It also selects a +much smaller 2\-heap for timer management over the default 4\-heap. +.IP "\s-1EV_PID_HASHSIZE\s0" 4 +.IX Item "EV_PID_HASHSIZE" +\&\f(CW\*(C`ev_child\*(C'\fR watchers use a small hash table to distribute workload by +pid. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_MINIMAL\*(C'\fR), usually more +than enough. If you need to manage thousands of children you might want to +increase this value (\fImust\fR be a power of two). +.IP "\s-1EV_INOTIFY_HASHSIZE\s0" 4 +.IX Item "EV_INOTIFY_HASHSIZE" +\&\f(CW\*(C`ev_stat\*(C'\fR watchers use a small hash table to distribute workload by +inotify watch id. The default size is \f(CW16\fR (or \f(CW1\fR with \f(CW\*(C`EV_MINIMAL\*(C'\fR), +usually more than enough. If you need to manage thousands of \f(CW\*(C`ev_stat\*(C'\fR +watchers you might want to increase this value (\fImust\fR be a power of +two). +.IP "\s-1EV_USE_4HEAP\s0" 4 +.IX Item "EV_USE_4HEAP" +Heaps are not very cache-efficient. To improve the cache-efficiency of the +timer and periodics heap, libev uses a 4\-heap when this symbol is defined +to \f(CW1\fR. The 4\-heap uses more complicated (longer) code but has a +noticable after performance with many (thousands) of watchers. +.Sp +The default is \f(CW1\fR unless \f(CW\*(C`EV_MINIMAL\*(C'\fR is set in which case it is \f(CW0\fR +(disabled). +.IP "\s-1EV_HEAP_CACHE_AT\s0" 4 +.IX Item "EV_HEAP_CACHE_AT" +Heaps are not very cache-efficient. To improve the cache-efficiency of the +timer and periodics heap, libev can cache the timestamp (\fIat\fR) within +the heap structure (selected by defining \f(CW\*(C`EV_HEAP_CACHE_AT\*(C'\fR to \f(CW1\fR), +which uses 8\-12 bytes more per watcher and a few hundred bytes more code, +but avoids random read accesses on heap changes. This noticably improves +performance noticably with with many (hundreds) of watchers. +.Sp +The default is \f(CW1\fR unless \f(CW\*(C`EV_MINIMAL\*(C'\fR is set in which case it is \f(CW0\fR +(disabled). +.IP "\s-1EV_COMMON\s0" 4 +.IX Item "EV_COMMON" +By default, all watchers have a \f(CW\*(C`void *data\*(C'\fR member. By redefining +this macro to a something else you can include more and other types of +members. You have to define it each time you include one of the files, +though, and it must be identical each time. +.Sp +For example, the perl \s-1EV\s0 module uses something like this: +.Sp +.Vb 3 +\& #define EV_COMMON \e +\& SV *self; /* contains this struct */ \e +\& SV *cb_sv, *fh /* note no trailing ";" */ +.Ve +.IP "\s-1EV_CB_DECLARE\s0 (type)" 4 +.IX Item "EV_CB_DECLARE (type)" +.PD 0 +.IP "\s-1EV_CB_INVOKE\s0 (watcher, revents)" 4 +.IX Item "EV_CB_INVOKE (watcher, revents)" +.IP "ev_set_cb (ev, cb)" 4 +.IX Item "ev_set_cb (ev, cb)" +.PD +Can be used to change the callback member declaration in each watcher, +and the way callbacks are invoked and set. Must expand to a struct member +definition and a statement, respectively. See the \fIev.h\fR header file for +their default definitions. One possible use for overriding these is to +avoid the \f(CW\*(C`struct ev_loop *\*(C'\fR as first argument in all cases, or to use +method calls instead of plain function calls in \*(C+. +.Sh "\s-1EXPORTED\s0 \s-1API\s0 \s-1SYMBOLS\s0" +.IX Subsection "EXPORTED API SYMBOLS" +If you need to re-export the \s-1API\s0 (e.g. via a dll) and you need a list of +exported symbols, you can use the provided \fISymbol.*\fR files which list +all public symbols, one per line: +.PP +.Vb 2 +\& Symbols.ev for libev proper +\& Symbols.event for the libevent emulation +.Ve +.PP +This can also be used to rename all public symbols to avoid clashes with +multiple versions of libev linked together (which is obviously bad in +itself, but sometimes it is inconvinient to avoid this). +.PP +A sed command like this will create wrapper \f(CW\*(C`#define\*(C'\fR's that you need to +include before including \fIev.h\fR: +.PP +.Vb 1 +\& <Symbols.ev sed \-e "s/.*/#define & myprefix_&/" >wrap.h +.Ve +.PP +This would create a file \fIwrap.h\fR which essentially looks like this: +.PP +.Vb 4 +\& #define ev_backend myprefix_ev_backend +\& #define ev_check_start myprefix_ev_check_start +\& #define ev_check_stop myprefix_ev_check_stop +\& ... +.Ve +.Sh "\s-1EXAMPLES\s0" +.IX Subsection "EXAMPLES" +For a real-world example of a program the includes libev +verbatim, you can have a look at the \s-1EV\s0 perl module +(<http://software.schmorp.de/pkg/EV.html>). It has the libev files in +the \fIlibev/\fR subdirectory and includes them in the \fI\s-1EV/EVAPI\s0.h\fR (public +interface) and \fI\s-1EV\s0.xs\fR (implementation) files. Only the \fI\s-1EV\s0.xs\fR file +will be compiled. It is pretty complex because it provides its own header +file. +.PP +The usage in rxvt-unicode is simpler. It has a \fIev_cpp.h\fR header file +that everybody includes and which overrides some configure choices: +.PP +.Vb 9 +\& #define EV_MINIMAL 1 +\& #define EV_USE_POLL 0 +\& #define EV_MULTIPLICITY 0 +\& #define EV_PERIODIC_ENABLE 0 +\& #define EV_STAT_ENABLE 0 +\& #define EV_FORK_ENABLE 0 +\& #define EV_CONFIG_H <config.h> +\& #define EV_MINPRI 0 +\& #define EV_MAXPRI 0 +\& +\& #include "ev++.h" +.Ve +.PP +And a \fIev_cpp.C\fR implementation file that contains libev proper and is compiled: +.PP +.Vb 2 +\& #include "ev_cpp.h" +\& #include "ev.c" +.Ve +.SH "THREADS AND COROUTINES" +.IX Header "THREADS AND COROUTINES" +.Sh "\s-1THREADS\s0" +.IX Subsection "THREADS" +Libev itself is completely threadsafe, but it uses no locking. This +means that you can use as many loops as you want in parallel, as long as +only one thread ever calls into one libev function with the same loop +parameter. +.PP +Or put differently: calls with different loop parameters can be done in +parallel from multiple threads, calls with the same loop parameter must be +done serially (but can be done from different threads, as long as only one +thread ever is inside a call at any point in time, e.g. by using a mutex +per loop). +.PP +If you want to know which design is best for your problem, then I cannot +help you but by giving some generic advice: +.IP "\(bu" 4 +most applications have a main thread: use the default libev loop +in that thread, or create a seperate thread running only the default loop. +.Sp +This helps integrating other libraries or software modules that use libev +themselves and don't care/know about threading. +.IP "\(bu" 4 +one loop per thread is usually a good model. +.Sp +Doing this is almost never wrong, sometimes a better-performance model +exists, but it is always a good start. +.IP "\(bu" 4 +other models exist, such as the leader/follower pattern, where one +loop is handed through multiple threads in a kind of round-robbin fashion. +.Sp +Chosing a model is hard \- look around, learn, know that usually you cna do +better than you currently do :\-) +.IP "\(bu" 4 +often you need to talk to some other thread which blocks in the +event loop \- \f(CW\*(C`ev_async\*(C'\fR watchers can be used to wake them up from other +threads safely (or from signal contexts...). +.Sh "\s-1COROUTINES\s0" +.IX Subsection "COROUTINES" +Libev is much more accomodating to coroutines (\*(L"cooperative threads\*(R"): +libev fully supports nesting calls to it's functions from different +coroutines (e.g. you can call \f(CW\*(C`ev_loop\*(C'\fR on the same loop from two +different coroutines and switch freely between both coroutines running the +loop, as long as you don't confuse yourself). The only exception is that +you must not do this from \f(CW\*(C`ev_periodic\*(C'\fR reschedule callbacks. +.PP +Care has been invested into making sure that libev does not keep local +state inside \f(CW\*(C`ev_loop\*(C'\fR, and other calls do not usually allow coroutine +switches. +.SH "COMPLEXITIES" +.IX Header "COMPLEXITIES" +In this section the complexities of (many of) the algorithms used inside +libev will be explained. For complexity discussions about backends see the +documentation for \f(CW\*(C`ev_default_init\*(C'\fR. +.PP +All of the following are about amortised time: If an array needs to be +extended, libev needs to realloc and move the whole array, but this +happens asymptotically never with higher number of elements, so O(1) might +mean it might do a lengthy realloc operation in rare cases, but on average +it is much faster and asymptotically approaches constant time. +.IP "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)" 4 +.IX Item "Starting and stopping timer/periodic watchers: O(log skipped_other_timers)" +This means that, when you have a watcher that triggers in one hour and +there are 100 watchers that would trigger before that then inserting will +have to skip roughly seven (\f(CW\*(C`ld 100\*(C'\fR) of these watchers. +.IP "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)" 4 +.IX Item "Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers)" +That means that changing a timer costs less than removing/adding them +as only the relative motion in the event queue has to be paid for. +.IP "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)" 4 +.IX Item "Starting io/check/prepare/idle/signal/child/fork/async watchers: O(1)" +These just add the watcher into an array or at the head of a list. +.IP "Stopping check/prepare/idle/fork/async watchers: O(1)" 4 +.IX Item "Stopping check/prepare/idle/fork/async watchers: O(1)" +.PD 0 +.IP "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % \s-1EV_PID_HASHSIZE\s0))" 4 +.IX Item "Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE))" +.PD +These watchers are stored in lists then need to be walked to find the +correct watcher to remove. The lists are usually short (you don't usually +have many watchers waiting for the same fd or signal). +.IP "Finding the next timer in each loop iteration: O(1)" 4 +.IX Item "Finding the next timer in each loop iteration: O(1)" +By virtue of using a binary or 4\-heap, the next timer is always found at a +fixed position in the storage array. +.IP "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)" 4 +.IX Item "Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd)" +A change means an I/O watcher gets started or stopped, which requires +libev to recalculate its status (and possibly tell the kernel, depending +on backend and wether \f(CW\*(C`ev_io_set\*(C'\fR was used). +.IP "Activating one watcher (putting it into the pending state): O(1)" 4 +.IX Item "Activating one watcher (putting it into the pending state): O(1)" +.PD 0 +.IP "Priority handling: O(number_of_priorities)" 4 +.IX Item "Priority handling: O(number_of_priorities)" +.PD +Priorities are implemented by allocating some space for each +priority. When doing priority-based operations, libev usually has to +linearly search all the priorities, but starting/stopping and activating +watchers becomes O(1) w.r.t. priority handling. +.IP "Sending an ev_async: O(1)" 4 +.IX Item "Sending an ev_async: O(1)" +.PD 0 +.IP "Processing ev_async_send: O(number_of_async_watchers)" 4 +.IX Item "Processing ev_async_send: O(number_of_async_watchers)" +.IP "Processing signals: O(max_signal_number)" 4 +.IX Item "Processing signals: O(max_signal_number)" +.PD +Sending involves a syscall \fIiff\fR there were no other \f(CW\*(C`ev_async_send\*(C'\fR +calls in the current loop iteration. Checking for async and signal events +involves iterating over all running async watchers or all signal numbers. +.SH "Win32 platform limitations and workarounds" +.IX Header "Win32 platform limitations and workarounds" +Win32 doesn't support any of the standards (e.g. \s-1POSIX\s0) that libev +requires, and its I/O model is fundamentally incompatible with the \s-1POSIX\s0 +model. Libev still offers limited functionality on this platform in +the form of the \f(CW\*(C`EVBACKEND_SELECT\*(C'\fR backend, and only supports socket +descriptors. This only applies when using Win32 natively, not when using +e.g. cygwin. +.PP +Lifting these limitations would basically require the full +re-implementation of the I/O system. If you are into these kinds of +things, then note that glib does exactly that for you in a very portable +way (note also that glib is the slowest event library known to man). +.PP +There is no supported compilation method available on windows except +embedding it into other applications. +.PP +Due to the many, low, and arbitrary limits on the win32 platform and +the abysmal performance of winsockets, using a large number of sockets +is not recommended (and not reasonable). If your program needs to use +more than a hundred or so sockets, then likely it needs to use a totally +different implementation for windows, as libev offers the \s-1POSIX\s0 readyness +notification model, which cannot be implemented efficiently on windows +(microsoft monopoly games). +.IP "The winsocket select function" 4 +.IX Item "The winsocket select function" +The winsocket \f(CW\*(C`select\*(C'\fR function doesn't follow \s-1POSIX\s0 in that it requires +socket \fIhandles\fR and not socket \fIfile descriptors\fR. This makes select +very inefficient, and also requires a mapping from file descriptors +to socket handles. See the discussion of the \f(CW\*(C`EV_SELECT_USE_FD_SET\*(C'\fR, +\&\f(CW\*(C`EV_SELECT_IS_WINSOCKET\*(C'\fR and \f(CW\*(C`EV_FD_TO_WIN32_HANDLE\*(C'\fR preprocessor +symbols for more info. +.Sp +The configuration for a \*(L"naked\*(R" win32 using the microsoft runtime +libraries and raw winsocket select is: +.Sp +.Vb 2 +\& #define EV_USE_SELECT 1 +\& #define EV_SELECT_IS_WINSOCKET 1 /* forces EV_SELECT_USE_FD_SET, too */ +.Ve +.Sp +Note that winsockets handling of fd sets is O(n), so you can easily get a +complexity in the O(nA\*^X) range when using win32. +.IP "Limited number of file descriptors" 4 +.IX Item "Limited number of file descriptors" +Windows has numerous arbitrary (and low) limits on things. +.Sp +Early versions of winsocket's select only supported waiting for a maximum +of \f(CW64\fR handles (probably owning to the fact that all windows kernels +can only wait for \f(CW64\fR things at the same time internally; microsoft +recommends spawning a chain of threads and wait for 63 handles and the +previous thread in each. Great). +.Sp +Newer versions support more handles, but you need to define \f(CW\*(C`FD_SETSIZE\*(C'\fR +to some high number (e.g. \f(CW2048\fR) before compiling the winsocket select +call (which might be in libev or elsewhere, for example, perl does its own +select emulation on windows). +.Sp +Another limit is the number of file descriptors in the microsoft runtime +libraries, which by default is \f(CW64\fR (there must be a hidden \fI64\fR fetish +or something like this inside microsoft). You can increase this by calling +\&\f(CW\*(C`_setmaxstdio\*(C'\fR, which can increase this limit to \f(CW2048\fR (another +arbitrary limit), but is broken in many versions of the microsoft runtime +libraries. +.Sp +This might get you to about \f(CW512\fR or \f(CW2048\fR sockets (depending on +windows version and/or the phase of the moon). To get more, you need to +wrap all I/O functions and provide your own fd management, but the cost of +calling select (O(nA\*^X)) will likely make this unworkable. +.SH "PORTABILITY REQUIREMENTS" +.IX Header "PORTABILITY REQUIREMENTS" +In addition to a working ISO-C implementation, libev relies on a few +additional extensions: +.ie n .IP """sig_atomic_t volatile"" must be thread-atomic as well" 4 +.el .IP "\f(CWsig_atomic_t volatile\fR must be thread-atomic as well" 4 +.IX Item "sig_atomic_t volatile must be thread-atomic as well" +The type \f(CW\*(C`sig_atomic_t volatile\*(C'\fR (or whatever is defined as +\&\f(CW\*(C`EV_ATOMIC_T\*(C'\fR) must be atomic w.r.t. accesses from different +threads. This is not part of the specification for \f(CW\*(C`sig_atomic_t\*(C'\fR, but is +believed to be sufficiently portable. +.ie n .IP """sigprocmask"" must work in a threaded environment" 4 +.el .IP "\f(CWsigprocmask\fR must work in a threaded environment" 4 +.IX Item "sigprocmask must work in a threaded environment" +Libev uses \f(CW\*(C`sigprocmask\*(C'\fR to temporarily block signals. This is not +allowed in a threaded program (\f(CW\*(C`pthread_sigmask\*(C'\fR has to be used). Typical +pthread implementations will either allow \f(CW\*(C`sigprocmask\*(C'\fR in the \*(L"main +thread\*(R" or will block signals process-wide, both behaviours would +be compatible with libev. Interaction between \f(CW\*(C`sigprocmask\*(C'\fR and +\&\f(CW\*(C`pthread_sigmask\*(C'\fR could complicate things, however. +.Sp +The most portable way to handle signals is to block signals in all threads +except the initial one, and run the default loop in the initial thread as +well. +.ie n .IP """long"" must be large enough for common memory allocation sizes" 4 +.el .IP "\f(CWlong\fR must be large enough for common memory allocation sizes" 4 +.IX Item "long must be large enough for common memory allocation sizes" +To improve portability and simplify using libev, libev uses \f(CW\*(C`long\*(C'\fR +internally instead of \f(CW\*(C`size_t\*(C'\fR when allocating its data structures. On +non-POSIX systems (Microsoft...) this might be unexpectedly low, but +is still at least 31 bits everywhere, which is enough for hundreds of +millions of watchers. +.ie n .IP """double"" must hold a time value in seconds with enough accuracy" 4 +.el .IP "\f(CWdouble\fR must hold a time value in seconds with enough accuracy" 4 +.IX Item "double must hold a time value in seconds with enough accuracy" +The type \f(CW\*(C`double\*(C'\fR is used to represent timestamps. It is required to +have at least 51 bits of mantissa (and 9 bits of exponent), which is good +enough for at least into the year 4000. This requirement is fulfilled by +implementations implementing \s-1IEEE\s0 754 (basically all existing ones). +.PP +If you know of other additional requirements drop me a note. +.SH "AUTHOR" +.IX Header "AUTHOR" +Marc Lehmann <libev@schmorp.de>. +.SH "POD ERRORS" +.IX Header "POD ERRORS" +Hey! \fBThe above document had some coding errors, which are explained below:\fR +.IP "Around line 3052:" 4 +.IX Item "Around line 3052:" +You forgot a '=back' before '=head2' diff --git a/deps/libeio/eio.c b/deps/libeio/eio.c new file mode 100644 index 0000000000..e0e172fbf4 --- /dev/null +++ b/deps/libeio/eio.c @@ -0,0 +1,1555 @@ +/* + * libeio implementation + * + * Copyright (c) 2007,2008 Marc Alexander Lehmann <libeio@schmorp.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#include "eio.h" +#include "xthread.h" + +#include <errno.h> +#include <stddef.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <limits.h> +#include <fcntl.h> +#include <assert.h> + +#ifndef EIO_FINISH +# define EIO_FINISH(req) ((req)->finish) && !EIO_CANCELLED (req) ? (req)->finish (req) : 0 +#endif + +#ifndef EIO_DESTROY +# define EIO_DESTROY(req) do { if ((req)->destroy) (req)->destroy (req); } while (0) +#endif + +#ifndef EIO_FEED +# define EIO_FEED(req) do { if ((req)->feed ) (req)->feed (req); } while (0) +#endif + +#ifdef _WIN32 + + /*doh*/ + +#else + +# include "config.h" +# include <sys/time.h> +# include <sys/select.h> +# include <unistd.h> +# include <utime.h> +# include <signal.h> +# include <dirent.h> + +# ifndef EIO_STRUCT_DIRENT +# define EIO_STRUCT_DIRENT struct dirent +# endif + +#endif + +#if HAVE_SENDFILE +# if __linux +# include <sys/sendfile.h> +# elif __freebsd +# include <sys/socket.h> +# include <sys/uio.h> +# elif __hpux +# include <sys/socket.h> +# elif __solaris /* not yet */ +# include <sys/sendfile.h> +# else +# error sendfile support requested but not available +# endif +#endif + +/* number of seconds after which an idle threads exit */ +#define IDLE_TIMEOUT 10 + +/* used for struct dirent, AIX doesn't provide it */ +#ifndef NAME_MAX +# define NAME_MAX 4096 +#endif + +/* buffer size for various temporary buffers */ +#define EIO_BUFSIZE 65536 + +#define dBUF \ + char *eio_buf; \ + ETP_WORKER_LOCK (self); \ + self->dbuf = eio_buf = malloc (EIO_BUFSIZE); \ + ETP_WORKER_UNLOCK (self); \ + errno = ENOMEM; \ + if (!eio_buf) \ + return -1; + +#define EIO_TICKS ((1000000 + 1023) >> 10) + +/*****************************************************************************/ + +#if __GNUC__ >= 3 +# define expect(expr,value) __builtin_expect ((expr),(value)) +#else +# define expect(expr,value) (expr) +#endif + +#define expect_false(expr) expect ((expr) != 0, 0) +#define expect_true(expr) expect ((expr) != 0, 1) + +/*****************************************************************************/ + +#define ETP_PRI_MIN EIO_PRI_MIN +#define ETP_PRI_MAX EIO_PRI_MAX + +struct etp_worker; + +#define ETP_REQ eio_req +#define ETP_DESTROY(req) eio_destroy (req) +static int eio_finish (eio_req *req); +#define ETP_FINISH(req) eio_finish (req) +static void eio_execute (struct etp_worker *self, eio_req *req); +#define ETP_EXECUTE(wrk,req) eio_execute (wrk,req) + +#define ETP_WORKER_CLEAR(req) \ + if (wrk->dbuf) \ + { \ + free (wrk->dbuf); \ + wrk->dbuf = 0; \ + } \ + \ + if (wrk->dirp) \ + { \ + closedir (wrk->dirp); \ + wrk->dirp = 0; \ + } +#define ETP_WORKER_COMMON \ + void *dbuf; \ + DIR *dirp; + +/*****************************************************************************/ + +#define ETP_NUM_PRI (ETP_PRI_MAX - ETP_PRI_MIN + 1) + +/* calculcate time difference in ~1/EIO_TICKS of a second */ +static int tvdiff (struct timeval *tv1, struct timeval *tv2) +{ + return (tv2->tv_sec - tv1->tv_sec ) * EIO_TICKS + + ((tv2->tv_usec - tv1->tv_usec) >> 10); +} + +static unsigned int started, idle, wanted = 4; + +static void (*want_poll_cb) (void); +static void (*done_poll_cb) (void); + +static unsigned int max_poll_time; /* reslock */ +static unsigned int max_poll_reqs; /* reslock */ + +static volatile unsigned int nreqs; /* reqlock */ +static volatile unsigned int nready; /* reqlock */ +static volatile unsigned int npending; /* reqlock */ +static volatile unsigned int max_idle = 4; + +static mutex_t wrklock = X_MUTEX_INIT; +static mutex_t reslock = X_MUTEX_INIT; +static mutex_t reqlock = X_MUTEX_INIT; +static cond_t reqwait = X_COND_INIT; + +#if !HAVE_PREADWRITE +/* + * make our pread/pwrite emulation safe against themselves, but not against + * normal read/write by using a mutex. slows down execution a lot, + * but that's your problem, not mine. + */ +static mutex_t preadwritelock = X_MUTEX_INIT; +#endif + +typedef struct etp_worker +{ + /* locked by wrklock */ + struct etp_worker *prev, *next; + + thread_t tid; + + /* locked by reslock, reqlock or wrklock */ + ETP_REQ *req; /* currently processed request */ + + ETP_WORKER_COMMON +} etp_worker; + +static etp_worker wrk_first = { &wrk_first, &wrk_first, 0 }; /* NOT etp */ + +#define ETP_WORKER_LOCK(wrk) X_LOCK (wrklock) +#define ETP_WORKER_UNLOCK(wrk) X_UNLOCK (wrklock) + +/* worker threads management */ + +static void etp_worker_clear (etp_worker *wrk) +{ + ETP_WORKER_CLEAR (wrk); +} + +static void etp_worker_free (etp_worker *wrk) +{ + wrk->next->prev = wrk->prev; + wrk->prev->next = wrk->next; + + free (wrk); +} + +static unsigned int etp_nreqs (void) +{ + int retval; + if (WORDACCESS_UNSAFE) X_LOCK (reqlock); + retval = nreqs; + if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); + return retval; +} + +static unsigned int etp_nready (void) +{ + unsigned int retval; + + if (WORDACCESS_UNSAFE) X_LOCK (reqlock); + retval = nready; + if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); + + return retval; +} + +static unsigned int etp_npending (void) +{ + unsigned int retval; + + if (WORDACCESS_UNSAFE) X_LOCK (reqlock); + retval = npending; + if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); + + return retval; +} + +static unsigned int etp_nthreads (void) +{ + unsigned int retval; + + if (WORDACCESS_UNSAFE) X_LOCK (reqlock); + retval = started; + if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); + + return retval; +} + +/* + * a somewhat faster data structure might be nice, but + * with 8 priorities this actually needs <20 insns + * per shift, the most expensive operation. + */ +typedef struct { + ETP_REQ *qs[ETP_NUM_PRI], *qe[ETP_NUM_PRI]; /* qstart, qend */ + int size; +} etp_reqq; + +static etp_reqq req_queue; +static etp_reqq res_queue; + +static int reqq_push (etp_reqq *q, ETP_REQ *req) +{ + int pri = req->pri; + req->next = 0; + + if (q->qe[pri]) + { + q->qe[pri]->next = req; + q->qe[pri] = req; + } + else + q->qe[pri] = q->qs[pri] = req; + + return q->size++; +} + +static ETP_REQ *reqq_shift (etp_reqq *q) +{ + int pri; + + if (!q->size) + return 0; + + --q->size; + + for (pri = ETP_NUM_PRI; pri--; ) + { + eio_req *req = q->qs[pri]; + + if (req) + { + if (!(q->qs[pri] = (eio_req *)req->next)) + q->qe[pri] = 0; + + return req; + } + } + + abort (); +} + +static void etp_atfork_prepare (void) +{ + X_LOCK (wrklock); + X_LOCK (reqlock); + X_LOCK (reslock); +#if !HAVE_PREADWRITE + X_LOCK (preadwritelock); +#endif +} + +static void etp_atfork_parent (void) +{ +#if !HAVE_PREADWRITE + X_UNLOCK (preadwritelock); +#endif + X_UNLOCK (reslock); + X_UNLOCK (reqlock); + X_UNLOCK (wrklock); +} + +static void etp_atfork_child (void) +{ + ETP_REQ *prv; + + while ((prv = reqq_shift (&req_queue))) + ETP_DESTROY (prv); + + while ((prv = reqq_shift (&res_queue))) + ETP_DESTROY (prv); + + while (wrk_first.next != &wrk_first) + { + etp_worker *wrk = wrk_first.next; + + if (wrk->req) + ETP_DESTROY (wrk->req); + + etp_worker_clear (wrk); + etp_worker_free (wrk); + } + + started = 0; + idle = 0; + nreqs = 0; + nready = 0; + npending = 0; + + etp_atfork_parent (); +} + +static void +etp_once_init (void) +{ + X_THREAD_ATFORK (etp_atfork_prepare, etp_atfork_parent, etp_atfork_child); +} + +static int +etp_init (void (*want_poll)(void), void (*done_poll)(void)) +{ + static pthread_once_t doinit = PTHREAD_ONCE_INIT; + + pthread_once (&doinit, etp_once_init); + + want_poll_cb = want_poll; + done_poll_cb = done_poll; + + return 0; +} + +X_THREAD_PROC (etp_proc); + +static void etp_start_thread (void) +{ + etp_worker *wrk = calloc (1, sizeof (etp_worker)); + + /*TODO*/ + assert (("unable to allocate worker thread data", wrk)); + + X_LOCK (wrklock); + + if (thread_create (&wrk->tid, etp_proc, (void *)wrk)) + { + wrk->prev = &wrk_first; + wrk->next = wrk_first.next; + wrk_first.next->prev = wrk; + wrk_first.next = wrk; + ++started; + } + else + free (wrk); + + X_UNLOCK (wrklock); +} + +static void etp_maybe_start_thread (void) +{ + if (expect_true (etp_nthreads () >= wanted)) + return; + + /* todo: maybe use idle here, but might be less exact */ + if (expect_true (0 <= (int)etp_nthreads () + (int)etp_npending () - (int)etp_nreqs ())) + return; + + etp_start_thread (); +} + +static void etp_end_thread (void) +{ + eio_req *req = calloc (1, sizeof (eio_req)); + + req->type = -1; + req->pri = ETP_PRI_MAX - ETP_PRI_MIN; + + X_LOCK (reqlock); + reqq_push (&req_queue, req); + X_COND_SIGNAL (reqwait); + X_UNLOCK (reqlock); + + X_LOCK (wrklock); + --started; + X_UNLOCK (wrklock); +} + +static int etp_poll (void) +{ + unsigned int maxreqs; + unsigned int maxtime; + struct timeval tv_start, tv_now; + + X_LOCK (reslock); + maxreqs = max_poll_reqs; + maxtime = max_poll_time; + X_UNLOCK (reslock); + + if (maxtime) + gettimeofday (&tv_start, 0); + + for (;;) + { + ETP_REQ *req; + + etp_maybe_start_thread (); + + X_LOCK (reslock); + req = reqq_shift (&res_queue); + + if (req) + { + --npending; + + if (!res_queue.size && done_poll_cb) + done_poll_cb (); + } + + X_UNLOCK (reslock); + + if (!req) + return 0; + + X_LOCK (reqlock); + --nreqs; + X_UNLOCK (reqlock); + + if (expect_false (req->type == EIO_GROUP && req->size)) + { + req->int1 = 1; /* mark request as delayed */ + continue; + } + else + { + int res = ETP_FINISH (req); + if (expect_false (res)) + return res; + } + + if (expect_false (maxreqs && !--maxreqs)) + break; + + if (maxtime) + { + gettimeofday (&tv_now, 0); + + if (tvdiff (&tv_start, &tv_now) >= maxtime) + break; + } + } + + errno = EAGAIN; + return -1; +} + +static void etp_cancel (ETP_REQ *req) +{ + X_LOCK (wrklock); + req->flags |= EIO_FLAG_CANCELLED; + X_UNLOCK (wrklock); + + eio_grp_cancel (req); +} + +static void etp_submit (ETP_REQ *req) +{ + req->pri -= ETP_PRI_MIN; + + if (expect_false (req->pri < ETP_PRI_MIN - ETP_PRI_MIN)) req->pri = ETP_PRI_MIN - ETP_PRI_MIN; + if (expect_false (req->pri > ETP_PRI_MAX - ETP_PRI_MIN)) req->pri = ETP_PRI_MAX - ETP_PRI_MIN; + + if (expect_false (req->type == EIO_GROUP)) + { + /* I hope this is worth it :/ */ + X_LOCK (reqlock); + ++nreqs; + X_UNLOCK (reqlock); + + X_LOCK (reslock); + + ++npending; + + if (!reqq_push (&res_queue, req) && want_poll_cb) + want_poll_cb (); + + X_UNLOCK (reslock); + } + else + { + X_LOCK (reqlock); + ++nreqs; + ++nready; + reqq_push (&req_queue, req); + X_COND_SIGNAL (reqwait); + X_UNLOCK (reqlock); + + etp_maybe_start_thread (); + } +} + +static void etp_set_max_poll_time (double nseconds) +{ + if (WORDACCESS_UNSAFE) X_LOCK (reslock); + max_poll_time = nseconds; + if (WORDACCESS_UNSAFE) X_UNLOCK (reslock); +} + +static void etp_set_max_poll_reqs (unsigned int maxreqs) +{ + if (WORDACCESS_UNSAFE) X_LOCK (reslock); + max_poll_reqs = maxreqs; + if (WORDACCESS_UNSAFE) X_UNLOCK (reslock); +} + +static void etp_set_max_idle (unsigned int nthreads) +{ + if (WORDACCESS_UNSAFE) X_LOCK (reqlock); + max_idle = nthreads <= 0 ? 1 : nthreads; + if (WORDACCESS_UNSAFE) X_UNLOCK (reqlock); +} + +static void etp_set_min_parallel (unsigned int nthreads) +{ + if (wanted < nthreads) + wanted = nthreads; +} + +static void etp_set_max_parallel (unsigned int nthreads) +{ + if (wanted > nthreads) + wanted = nthreads; + + while (started > wanted) + etp_end_thread (); +} + +/*****************************************************************************/ + +static void grp_try_feed (eio_req *grp) +{ + while (grp->size < grp->int2 && !EIO_CANCELLED (grp)) + { + grp->flags &= ~EIO_FLAG_GROUPADD; + + EIO_FEED (grp); + + /* stop if no progress has been made */ + if (!(grp->flags & EIO_FLAG_GROUPADD)) + { + grp->feed = 0; + break; + } + } +} + +static int grp_dec (eio_req *grp) +{ + --grp->size; + + /* call feeder, if applicable */ + grp_try_feed (grp); + + /* finish, if done */ + if (!grp->size && grp->int1) + return eio_finish (grp); + else + return 0; +} + +void eio_destroy (eio_req *req) +{ + if ((req)->flags & EIO_FLAG_PTR1_FREE) free (req->ptr1); + if ((req)->flags & EIO_FLAG_PTR2_FREE) free (req->ptr2); + + EIO_DESTROY (req); +} + +static int eio_finish (eio_req *req) +{ + int res = EIO_FINISH (req); + + if (req->grp) + { + int res2; + eio_req *grp = req->grp; + + /* unlink request */ + if (req->grp_next) req->grp_next->grp_prev = req->grp_prev; + if (req->grp_prev) req->grp_prev->grp_next = req->grp_next; + + if (grp->grp_first == req) + grp->grp_first = req->grp_next; + + res2 = grp_dec (grp); + + if (!res && res2) + res = res2; + } + + eio_destroy (req); + + return res; +} + +void eio_grp_cancel (eio_req *grp) +{ + for (grp = grp->grp_first; grp; grp = grp->grp_next) + eio_cancel (grp); +} + +void eio_cancel (eio_req *req) +{ + etp_cancel (req); +} + +void eio_submit (eio_req *req) +{ + etp_submit (req); +} + +unsigned int eio_nreqs (void) +{ + return etp_nreqs (); +} + +unsigned int eio_nready (void) +{ + return etp_nready (); +} + +unsigned int eio_npending (void) +{ + return etp_npending (); +} + +unsigned int eio_nthreads (void) +{ + return etp_nthreads (); +} + +void eio_set_max_poll_time (double nseconds) +{ + etp_set_max_poll_time (nseconds); +} + +void eio_set_max_poll_reqs (unsigned int maxreqs) +{ + etp_set_max_poll_reqs (maxreqs); +} + +void eio_set_max_idle (unsigned int nthreads) +{ + etp_set_max_idle (nthreads); +} + +void eio_set_min_parallel (unsigned int nthreads) +{ + etp_set_min_parallel (nthreads); +} + +void eio_set_max_parallel (unsigned int nthreads) +{ + etp_set_max_parallel (nthreads); +} + +int eio_poll (void) +{ + return etp_poll (); +} + +/*****************************************************************************/ +/* work around various missing functions */ + +#if !HAVE_PREADWRITE +# undef pread +# undef pwrite +# define pread eio__pread +# define pwrite eio__pwrite + +static ssize_t +eio__pread (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t res; + off_t ooffset; + + X_LOCK (preadwritelock); + ooffset = lseek (fd, 0, SEEK_CUR); + lseek (fd, offset, SEEK_SET); + res = read (fd, buf, count); + lseek (fd, ooffset, SEEK_SET); + X_UNLOCK (preadwritelock); + + return res; +} + +static ssize_t +eio__pwrite (int fd, void *buf, size_t count, off_t offset) +{ + ssize_t res; + off_t ooffset; + + X_LOCK (preadwritelock); + ooffset = lseek (fd, 0, SEEK_CUR); + lseek (fd, offset, SEEK_SET); + res = write (fd, buf, count); + lseek (fd, offset, SEEK_SET); + X_UNLOCK (preadwritelock); + + return res; +} +#endif + +#ifndef HAVE_FUTIMES + +# undef utimes +# undef futimes +# define utimes(path,times) eio__utimes (path, times) +# define futimes(fd,times) eio__futimes (fd, times) + +static int +eio__utimes (const char *filename, const struct timeval times[2]) +{ + if (times) + { + struct utimbuf buf; + + buf.actime = times[0].tv_sec; + buf.modtime = times[1].tv_sec; + + return utime (filename, &buf); + } + else + return utime (filename, 0); +} + +static int eio__futimes (int fd, const struct timeval tv[2]) +{ + errno = ENOSYS; + return -1; +} + +#endif + +#if !HAVE_FDATASYNC +# undef fdatasync +# define fdatasync(fd) fsync (fd) +#endif + +/* sync_file_range always needs emulation */ +int +eio__sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags) +{ +#if HAVE_SYNC_FILE_RANGE + int res; + + if (EIO_SYNC_FILE_RANGE_WAIT_BEFORE != SYNC_FILE_RANGE_WAIT_BEFORE + || EIO_SYNC_FILE_RANGE_WRITE != SYNC_FILE_RANGE_WRITE + || EIO_SYNC_FILE_RANGE_WAIT_AFTER != SYNC_FILE_RANGE_WAIT_AFTER) + { + flags = 0 + | (flags & EIO_SYNC_FILE_RANGE_WAIT_BEFORE ? SYNC_FILE_RANGE_WAIT_BEFORE : 0) + | (flags & EIO_SYNC_FILE_RANGE_WRITE ? SYNC_FILE_RANGE_WRITE : 0) + | (flags & EIO_SYNC_FILE_RANGE_WAIT_AFTER ? SYNC_FILE_RANGE_WAIT_AFTER : 0); + } + + res = sync_file_range (fd, offset, nbytes, flags); + + if (!res || errno != ENOSYS) + return res; +#endif + + /* even though we could play tricks with the flags, it's better to always + * call fdatasync, as thta matches the expectation of it's users best */ + return fdatasync (fd); +} + +#if !HAVE_READAHEAD +# undef readahead +# define readahead(fd,offset,count) eio__readahead (fd, offset, count, self) + +static ssize_t +eio__readahead (int fd, off_t offset, size_t count, etp_worker *self) +{ + size_t todo = count; + dBUF; + + while (todo > 0) + { + size_t len = todo < EIO_BUFSIZE ? todo : EIO_BUFSIZE; + + pread (fd, eio_buf, len, offset); + offset += len; + todo -= len; + } + + errno = 0; + return count; +} + +#endif + +/* sendfile always needs emulation */ +static ssize_t +eio__sendfile (int ofd, int ifd, off_t offset, size_t count, etp_worker *self) +{ + ssize_t res; + + if (!count) + return 0; + +#if HAVE_SENDFILE +# if __linux + res = sendfile (ofd, ifd, &offset, count); + +# elif __freebsd + /* + * Of course, the freebsd sendfile is a dire hack with no thoughts + * wasted on making it similar to other I/O functions. + */ + { + off_t sbytes; + res = sendfile (ifd, ofd, offset, count, 0, &sbytes, 0); + + if (res < 0 && sbytes) + /* maybe only on EAGAIN: as usual, the manpage leaves you guessing */ + res = sbytes; + } + +# elif __hpux + res = sendfile (ofd, ifd, offset, count, 0, 0); + +# elif __solaris + { + struct sendfilevec vec; + size_t sbytes; + + vec.sfv_fd = ifd; + vec.sfv_flag = 0; + vec.sfv_off = offset; + vec.sfv_len = count; + + res = sendfilev (ofd, &vec, 1, &sbytes); + + if (res < 0 && sbytes) + res = sbytes; + } + +# endif +#else + res = -1; + errno = ENOSYS; +#endif + + if (res < 0 + && (errno == ENOSYS || errno == EINVAL || errno == ENOTSOCK +#if __solaris + || errno == EAFNOSUPPORT || errno == EPROTOTYPE +#endif + ) + ) + { + /* emulate sendfile. this is a major pain in the ass */ + dBUF; + + res = 0; + + while (count) + { + ssize_t cnt; + + cnt = pread (ifd, eio_buf, count > EIO_BUFSIZE ? EIO_BUFSIZE : count, offset); + + if (cnt <= 0) + { + if (cnt && !res) res = -1; + break; + } + + cnt = write (ofd, eio_buf, cnt); + + if (cnt <= 0) + { + if (cnt && !res) res = -1; + break; + } + + offset += cnt; + res += cnt; + count -= cnt; + } + } + + return res; +} + +/* read a full directory */ +static void +eio__scandir (eio_req *req, etp_worker *self) +{ + DIR *dirp; + EIO_STRUCT_DIRENT *entp; + char *name, *names; + int memlen = 4096; + int memofs = 0; + int res = 0; + + X_LOCK (wrklock); + /* the corresponding closedir is in ETP_WORKER_CLEAR */ + self->dirp = dirp = opendir (req->ptr1); + req->flags |= EIO_FLAG_PTR2_FREE; + req->ptr2 = names = malloc (memlen); + X_UNLOCK (wrklock); + + if (dirp && names) + for (;;) + { + errno = 0; + entp = readdir (dirp); + + if (!entp) + break; + + name = entp->d_name; + + if (name [0] != '.' || (name [1] && (name [1] != '.' || name [2]))) + { + int len = strlen (name) + 1; + + res++; + + while (memofs + len > memlen) + { + memlen *= 2; + X_LOCK (wrklock); + req->ptr2 = names = realloc (names, memlen); + X_UNLOCK (wrklock); + + if (!names) + break; + } + + memcpy (names + memofs, name, len); + memofs += len; + } + } + + if (errno) + res = -1; + + req->result = res; +} + +#if !(_POSIX_MAPPED_FILES && _POSIX_SYNCHRONIZED_IO) +# undef msync +# define msync(a,b,c) ((errno = ENOSYS), -1) +#endif + +int +eio__mtouch (void *mem, size_t len, int flags) +{ + intptr_t addr = (intptr_t)mem; + intptr_t end = addr + len; +#ifdef PAGESIZE + const intptr_t page = PAGESIZE; +#else + static intptr_t page; + + if (!page) + page = sysconf (_SC_PAGESIZE); +#endif + + addr &= ~(page - 1); /* assume page size is always a power of two */ + + if (addr < end) + if (flags) /* modify */ + do { *((volatile sig_atomic_t *)addr) |= 0; } while ((addr += page) < len); + else + do { *((volatile sig_atomic_t *)addr) ; } while ((addr += page) < len); + + return 0; +} + +/*****************************************************************************/ + +#define ALLOC(len) \ + if (!req->ptr2) \ + { \ + X_LOCK (wrklock); \ + req->flags |= EIO_FLAG_PTR2_FREE; \ + X_UNLOCK (wrklock); \ + req->ptr2 = malloc (len); \ + if (!req->ptr2) \ + { \ + errno = ENOMEM; \ + req->result = -1; \ + break; \ + } \ + } + +X_THREAD_PROC (etp_proc) +{ + ETP_REQ *req; + struct timespec ts; + etp_worker *self = (etp_worker *)thr_arg; + + /* try to distribute timeouts somewhat randomly */ + ts.tv_nsec = ((unsigned long)self & 1023UL) * (1000000000UL / 1024UL); + + for (;;) + { + X_LOCK (reqlock); + + for (;;) + { + self->req = req = reqq_shift (&req_queue); + + if (req) + break; + + ++idle; + + ts.tv_sec = time (0) + IDLE_TIMEOUT; + if (X_COND_TIMEDWAIT (reqwait, reqlock, ts) == ETIMEDOUT) + { + if (idle > max_idle) + { + --idle; + X_UNLOCK (reqlock); + X_LOCK (wrklock); + --started; + X_UNLOCK (wrklock); + goto quit; + } + + /* we are allowed to idle, so do so without any timeout */ + X_COND_WAIT (reqwait, reqlock); + } + + --idle; + } + + --nready; + + X_UNLOCK (reqlock); + + if (req->type < 0) + goto quit; + + if (!EIO_CANCELLED (req)) + ETP_EXECUTE (self, req); + + X_LOCK (reslock); + + ++npending; + + if (!reqq_push (&res_queue, req) && want_poll_cb) + want_poll_cb (); + + self->req = 0; + etp_worker_clear (self); + + X_UNLOCK (reslock); + } + +quit: + X_LOCK (wrklock); + etp_worker_free (self); + X_UNLOCK (wrklock); + + return 0; +} + +/*****************************************************************************/ + +int eio_init (void (*want_poll)(void), void (*done_poll)(void)) +{ + return etp_init (want_poll, done_poll); +} + +static void eio_api_destroy (eio_req *req) +{ + free (req); +} + +#define REQ(rtype) \ + eio_req *req; \ + \ + req = (eio_req *)calloc (1, sizeof *req); \ + if (!req) \ + return 0; \ + \ + req->type = rtype; \ + req->pri = pri; \ + req->finish = cb; \ + req->data = data; \ + req->destroy = eio_api_destroy; + +#define SEND eio_submit (req); return req + +#define PATH \ + req->flags |= EIO_FLAG_PTR1_FREE; \ + req->ptr1 = strdup (path); \ + if (!req->ptr1) \ + { \ + eio_api_destroy (req); \ + return 0; \ + } + +static void eio_execute (etp_worker *self, eio_req *req) +{ + errno = 0; + + switch (req->type) + { + case EIO_READ: ALLOC (req->size); + req->result = req->offs >= 0 + ? pread (req->int1, req->ptr2, req->size, req->offs) + : read (req->int1, req->ptr2, req->size); break; + case EIO_WRITE: req->result = req->offs >= 0 + ? pwrite (req->int1, req->ptr2, req->size, req->offs) + : write (req->int1, req->ptr2, req->size); break; + + case EIO_READAHEAD: req->result = readahead (req->int1, req->offs, req->size); break; + case EIO_SENDFILE: req->result = eio__sendfile (req->int1, req->int2, req->offs, req->size, self); break; + + case EIO_STAT: ALLOC (sizeof (EIO_STRUCT_STAT)); + req->result = stat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; + case EIO_LSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); + req->result = lstat (req->ptr1, (EIO_STRUCT_STAT *)req->ptr2); break; + case EIO_FSTAT: ALLOC (sizeof (EIO_STRUCT_STAT)); + req->result = fstat (req->int1, (EIO_STRUCT_STAT *)req->ptr2); break; + + case EIO_CHOWN: req->result = chown (req->ptr1, req->int2, req->int3); break; + case EIO_FCHOWN: req->result = fchown (req->int1, req->int2, req->int3); break; + case EIO_CHMOD: req->result = chmod (req->ptr1, (mode_t)req->int2); break; + case EIO_FCHMOD: req->result = fchmod (req->int1, (mode_t)req->int2); break; + case EIO_TRUNCATE: req->result = truncate (req->ptr1, req->offs); break; + case EIO_FTRUNCATE: req->result = ftruncate (req->int1, req->offs); break; + + case EIO_OPEN: req->result = open (req->ptr1, req->int1, (mode_t)req->int2); break; + case EIO_CLOSE: req->result = close (req->int1); break; + case EIO_DUP2: req->result = dup2 (req->int1, req->int2); break; + case EIO_UNLINK: req->result = unlink (req->ptr1); break; + case EIO_RMDIR: req->result = rmdir (req->ptr1); break; + case EIO_MKDIR: req->result = mkdir (req->ptr1, (mode_t)req->int2); break; + case EIO_RENAME: req->result = rename (req->ptr1, req->ptr2); break; + case EIO_LINK: req->result = link (req->ptr1, req->ptr2); break; + case EIO_SYMLINK: req->result = symlink (req->ptr1, req->ptr2); break; + case EIO_MKNOD: req->result = mknod (req->ptr1, (mode_t)req->int2, (dev_t)req->int3); break; + + case EIO_READLINK: ALLOC (NAME_MAX); + req->result = readlink (req->ptr1, req->ptr2, NAME_MAX); break; + + case EIO_SYNC: req->result = 0; sync (); break; + case EIO_FSYNC: req->result = fsync (req->int1); break; + case EIO_FDATASYNC: req->result = fdatasync (req->int1); break; + case EIO_MSYNC: req->result = msync (req->ptr2, req->size, req->int1); break; + case EIO_MTOUCH: req->result = eio__mtouch (req->ptr2, req->size, req->int1); break; + case EIO_SYNC_FILE_RANGE: req->result = eio__sync_file_range (req->int1, req->offs, req->size, req->int2); break; + + case EIO_READDIR: eio__scandir (req, self); break; + + case EIO_BUSY: +#ifdef _WIN32 + Sleep (req->nv1 * 1000.); +#else + { + struct timeval tv; + + tv.tv_sec = req->nv1; + tv.tv_usec = (req->nv1 - tv.tv_sec) * 1000000.; + + req->result = select (0, 0, 0, 0, &tv); + } +#endif + break; + + case EIO_UTIME: + case EIO_FUTIME: + { + struct timeval tv[2]; + struct timeval *times; + + if (req->nv1 != -1. || req->nv2 != -1.) + { + tv[0].tv_sec = req->nv1; + tv[0].tv_usec = (req->nv1 - tv[0].tv_sec) * 1000000.; + tv[1].tv_sec = req->nv2; + tv[1].tv_usec = (req->nv2 - tv[1].tv_sec) * 1000000.; + + times = tv; + } + else + times = 0; + + + req->result = req->type == EIO_FUTIME + ? futimes (req->int1, times) + : utimes (req->ptr1, times); + } + break; + + case EIO_GROUP: + abort (); /* handled in eio_request */ + + case EIO_NOP: + req->result = 0; + break; + + case EIO_CUSTOM: + ((void (*)(eio_req *))req->feed) (req); + break; + + default: + req->result = -1; + break; + } + + req->errorno = errno; +} + +#ifndef EIO_NO_WRAPPERS + +eio_req *eio_nop (int pri, eio_cb cb, void *data) +{ + REQ (EIO_NOP); SEND; +} + +eio_req *eio_busy (double delay, int pri, eio_cb cb, void *data) +{ + REQ (EIO_BUSY); req->nv1 = delay; SEND; +} + +eio_req *eio_sync (int pri, eio_cb cb, void *data) +{ + REQ (EIO_SYNC); SEND; +} + +eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FSYNC); req->int1 = fd; SEND; +} + +eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) +{ + REQ (EIO_MSYNC); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; +} + +eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data) +{ + REQ (EIO_MTOUCH); req->ptr2 = addr; req->size = length; req->int1 = flags; SEND; +} + +eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data) +{ + REQ (EIO_SYNC_FILE_RANGE); req->int1 = fd; req->offs = offset; req->size = nbytes; req->int2 = flags; SEND; +} + +eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FDATASYNC); req->int1 = fd; SEND; +} + +eio_req *eio_close (int fd, int pri, eio_cb cb, void *data) +{ + REQ (EIO_CLOSE); req->int1 = fd; SEND; +} + +eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data) +{ + REQ (EIO_READAHEAD); req->int1 = fd; req->offs = offset; req->size = length; SEND; +} + +eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data) +{ + REQ (EIO_READ); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND; +} + +eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data) +{ + REQ (EIO_WRITE); req->int1 = fd; req->offs = offset; req->size = length; req->ptr2 = buf; SEND; +} + +eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FSTAT); req->int1 = fd; SEND; +} + +eio_req *eio_futime (int fd, double atime, double mtime, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FUTIME); req->int1 = fd; req->nv1 = atime; req->nv2 = mtime; SEND; +} + +eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FTRUNCATE); req->int1 = fd; req->offs = offset; SEND; +} + +eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FCHMOD); req->int1 = fd; req->int2 = (long)mode; SEND; +} + +eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data) +{ + REQ (EIO_FCHOWN); req->int1 = fd; req->int2 = (long)uid; req->int3 = (long)gid; SEND; +} + +eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data) +{ + REQ (EIO_DUP2); req->int1 = fd; req->int2 = fd2; SEND; +} + +eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data) +{ + REQ (EIO_SENDFILE); req->int1 = out_fd; req->int2 = in_fd; req->offs = in_offset; req->size = length; SEND; +} + +eio_req *eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data) +{ + REQ (EIO_OPEN); PATH; req->int1 = flags; req->int2 = (long)mode; SEND; +} + +eio_req *eio_utime (const char *path, double atime, double mtime, int pri, eio_cb cb, void *data) +{ + REQ (EIO_UTIME); PATH; req->nv1 = atime; req->nv2 = mtime; SEND; +} + +eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data) +{ + REQ (EIO_TRUNCATE); PATH; req->offs = offset; SEND; +} + +eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data) +{ + REQ (EIO_CHOWN); PATH; req->int2 = (long)uid; req->int3 = (long)gid; SEND; +} + +eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data) +{ + REQ (EIO_CHMOD); PATH; req->int2 = (long)mode; SEND; +} + +eio_req *eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data) +{ + REQ (EIO_MKDIR); PATH; req->int2 = (long)mode; SEND; +} + +static eio_req * +eio__1path (int type, const char *path, int pri, eio_cb cb, void *data) +{ + REQ (type); PATH; SEND; +} + +eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_READLINK, path, pri, cb, data); +} + +eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_STAT, path, pri, cb, data); +} + +eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_LSTAT, path, pri, cb, data); +} + +eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_UNLINK, path, pri, cb, data); +} + +eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_RMDIR, path, pri, cb, data); +} + +eio_req *eio_readdir (const char *path, int pri, eio_cb cb, void *data) +{ + return eio__1path (EIO_READDIR, path, pri, cb, data); +} + +eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data) +{ + REQ (EIO_MKNOD); PATH; req->int2 = (long)mode; req->int3 = (long)dev; SEND; +} + +static eio_req * +eio__2path (int type, const char *path, const char *new_path, int pri, eio_cb cb, void *data) +{ + REQ (type); PATH; + + req->flags |= EIO_FLAG_PTR2_FREE; + req->ptr2 = strdup (new_path); + if (!req->ptr2) + { + eio_api_destroy (req); + return 0; + } + + SEND; +} + +eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data) +{ + return eio__2path (EIO_LINK, path, new_path, pri, cb, data); +} + +eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data) +{ + return eio__2path (EIO_SYMLINK, path, new_path, pri, cb, data); +} + +eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data) +{ + return eio__2path (EIO_RENAME, path, new_path, pri, cb, data); +} + +eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data) +{ + REQ (EIO_CUSTOM); req->feed = (void (*)(eio_req *))execute; SEND; +} + +#endif + +eio_req *eio_grp (eio_cb cb, void *data) +{ + const int pri = EIO_PRI_MAX; + + REQ (EIO_GROUP); SEND; +} + +#undef REQ +#undef PATH +#undef SEND + +/*****************************************************************************/ +/* grp functions */ + +void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit) +{ + grp->int2 = limit; + grp->feed = feed; + + grp_try_feed (grp); +} + +void eio_grp_limit (eio_req *grp, int limit) +{ + grp->int2 = limit; + + grp_try_feed (grp); +} + +void eio_grp_add (eio_req *grp, eio_req *req) +{ + assert (("cannot add requests to IO::AIO::GRP after the group finished", grp->int1 != 2)); + + grp->flags |= EIO_FLAG_GROUPADD; + + ++grp->size; + req->grp = grp; + + req->grp_prev = 0; + req->grp_next = grp->grp_first; + + if (grp->grp_first) + grp->grp_first->grp_prev = req; + + grp->grp_first = req; +} + +/*****************************************************************************/ +/* misc garbage */ + +ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count) +{ + etp_worker wrk; + + wrk.dbuf = 0; + + eio__sendfile (ofd, ifd, offset, count, &wrk); + + if (wrk.dbuf) + free (wrk.dbuf); +} + diff --git a/deps/libeio/eio.h b/deps/libeio/eio.h new file mode 100644 index 0000000000..12fc3ed161 --- /dev/null +++ b/deps/libeio/eio.h @@ -0,0 +1,246 @@ +/* + * libeio API header + * + * Copyright (c) 2007,2008 Marc Alexander Lehmann <libeio@schmorp.de> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modifica- + * tion, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER- + * CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE- + * CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH- + * ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Alternatively, the contents of this file may be used under the terms of + * the GNU General Public License ("GPL") version 2 or any later version, + * in which case the provisions of the GPL are applicable instead of + * the above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use your + * version of this file under the BSD license, indicate your decision + * by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file under + * either the BSD or the GPL. + */ + +#ifndef EIO_H_ +#define EIO_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include <stddef.h> +#include <sys/types.h> + +typedef struct eio_req eio_req; + +typedef int (*eio_cb)(eio_req *req); + +#ifndef EIO_REQ_MEMBERS +# define EIO_REQ_MEMBERS +#endif + +#ifndef EIO_STRUCT_STAT +# define EIO_STRUCT_STAT struct stat +#endif + +enum { + EIO_CUSTOM, + EIO_OPEN, EIO_CLOSE, EIO_DUP2, + EIO_READ, EIO_WRITE, + EIO_READAHEAD, EIO_SENDFILE, + EIO_STAT, EIO_LSTAT, EIO_FSTAT, + EIO_TRUNCATE, EIO_FTRUNCATE, + EIO_UTIME, EIO_FUTIME, + EIO_CHMOD, EIO_FCHMOD, + EIO_CHOWN, EIO_FCHOWN, + EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC, + EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE, + EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME, + EIO_MKNOD, EIO_READDIR, + EIO_LINK, EIO_SYMLINK, EIO_READLINK, + EIO_GROUP, EIO_NOP, + EIO_BUSY +}; + +/* eio_sync_file_range flags */ + +enum { + EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1, + EIO_SYNC_FILE_RANGE_WRITE = 2, + EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4 +}; + +typedef double eio_tstamp; /* feel free to use double in your code directly */ + +/* eio request structure */ +/* this structure is mostly read-only */ +struct eio_req +{ + eio_req volatile *next; /* private ETP */ + + ssize_t result; /* result of syscall, e.g. result = read (... */ + off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset */ + size_t size; /* read, write, readahead, sendfile, msync, sync_file_range: length */ + void *ptr1; /* all applicable requests: pathname, old name */ + void *ptr2; /* all applicable requests: new name or memory buffer */ + eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */ + eio_tstamp nv2; /* utime, futime: mtime */ + + int type; /* EIO_xxx constant ETP */ + int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync: flags */ + long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */ + long int3; /* chown, fchown: gid; mknod: dev_t */ + int errorno; /* errno value on syscall return */ + + unsigned char flags; /* private */ + signed char pri; /* the priority */ + + void *data; + eio_cb finish; + void (*destroy)(eio_req *req); /* called when requets no longer needed */ + void (*feed)(eio_req *req); /* only used for group requests */ + + EIO_REQ_MEMBERS + + eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */ +}; + +/* _private_ flags */ +enum { + EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */ + EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */ + EIO_FLAG_PTR2_FREE = 0x04, /* need to free(ptr2) */ + EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */ +}; + +enum { + EIO_PRI_MIN = -4, + EIO_PRI_MAX = 4, + EIO_PRI_DEFAULT = 0, +}; + +/* returns < 0 on error, errno set + * need_poll, if non-zero, will be called when results are available + * and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself). + * done_poll is called when the need to poll is gone. + */ +int eio_init (void (*want_poll)(void), void (*done_poll)(void)); + +/* must be called regularly to handle pending requests */ +/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */ +int eio_poll (void); + +/* stop polling if poll took longer than duration seconds */ +void eio_set_max_poll_time (eio_tstamp nseconds); +/* do not handle more then count requests in one call to eio_poll_cb */ +void eio_set_max_poll_reqs (unsigned int nreqs); + +/* set minimum required number + * maximum wanted number + * or maximum idle number of threads */ +void eio_set_min_parallel (unsigned int nthreads); +void eio_set_max_parallel (unsigned int nthreads); +void eio_set_max_idle (unsigned int nthreads); + +unsigned int eio_nreqs (void); /* number of requests in-flight */ +unsigned int eio_nready (void); /* number of not-yet handled requests */ +unsigned int eio_npending (void); /* numbe rof finished but unhandled requests */ +unsigned int eio_nthreads (void); /* number of worker threads in use currently */ + +/*****************************************************************************/ +/* convinience wrappers */ + +#ifndef EIO_NO_WRAPPERS +eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */ +eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ties a thread for this long, simulating busyness */ +eio_req *eio_sync (int pri, eio_cb cb, void *data); +eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data); +eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data); +eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); +eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data); +eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data); +eio_req *eio_close (int fd, int pri, eio_cb cb, void *data); +eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data); +eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data); +eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data); +eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ +eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data); +eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data); +eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data); +eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data); +eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data); +eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data); +eio_req *eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data); +eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data); +eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data); +eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data); +eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data); +eio_req *eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data); +eio_req *eio_readdir (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */ +eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data); +eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data); +eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */ +eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ +eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */ +eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data); +eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data); +eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data); +eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data); +eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data); +#endif + +/*****************************************************************************/ +/* groups */ + +eio_req *eio_grp (eio_cb cb, void *data); +void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit); +void eio_grp_limit (eio_req *grp, int limit); +void eio_grp_add (eio_req *grp, eio_req *req); +void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the group */ + +/*****************************************************************************/ +/* request api */ + +/* true if the request was cancelled, useful in the invoke callback */ +#define EIO_CANCELLED(req) ((req)->flags & EIO_FLAG_CANCELLED) + +#define EIO_RESULT(req) ((req)->result) +/* returns a pointer to the result buffer allocated by eio */ +#define EIO_BUF(req) ((req)->ptr2) +#define EIO_STAT_BUF(req) ((EIO_STRUCT_STAT *)EIO_BUF(req)) +#define EIO_PATH(req) ((char *)(req)->ptr1) + +/* submit a request for execution */ +void eio_submit (eio_req *req); +/* cancel a request as soon fast as possible, if possible */ +void eio_cancel (eio_req *req); +/* destroy a request that has never been submitted */ +void eio_destroy (eio_req *req); + +/*****************************************************************************/ +/* convinience functions */ + +ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/deps/libeio/eio.pod b/deps/libeio/eio.pod new file mode 100644 index 0000000000..bbacb662d3 --- /dev/null +++ b/deps/libeio/eio.pod @@ -0,0 +1,282 @@ +=head1 NAME + +libeio - truly asynchronous POSIX I/O + +=head1 SYNOPSIS + + #include <eio.h> + +=head1 DESCRIPTION + +The newest version of this document is also available as an html-formatted +web page you might find easier to navigate when reading it for the first +time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>. + +Note that this library is a by-product of the C<IO::AIO> perl +module, and many of the subtler points regarding requets lifetime +and so on are only documented in its documentation at the +moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>. + +=head2 FEATURES + +This library provides fully asynchronous versions of most POSIX functions +dealign with I/O. Unlike most asynchronous libraries, this not only +includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and +similar functions, as well as less rarely ones such as C<mknod>, C<futime> +or C<readlink>. + +It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and +FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with +emulation elsewhere>). + +The goal is to enbale you to write fully non-blocking programs. For +example, in a game server, you would not want to freeze for a few seconds +just because the server is running a backup and you happen to call +C<readdir>. + +=head2 TIME REPRESENTATION + +Libeio represents time as a single floating point number, representing the +(fractional) number of seconds since the (POSIX) epoch (somewhere near +the beginning of 1970, details are complicated, don't ask). This type is +called C<eio_tstamp>, but it is guarenteed to be of type C<double> (or +better), so you can freely use C<double> yourself. + +Unlike the name component C<stamp> might indicate, it is also used for +time differences throughout libeio. + +=head2 FORK SUPPORT + +Calling C<fork ()> is fully supported by this module. It is implemented in these steps: + + 1. wait till all requests in "execute" state have been handled + (basically requests that are already handed over to the kernel). + 2. fork + 3. in the parent, continue business as usual, done + 4. in the child, destroy all ready and pending requests and free the + memory used by the worker threads. This gives you a fully empty + libeio queue. + +=head1 INITIALISATION/INTEGRATION + +Before you can call any eio functions you first have to initialise the +library. The library integrates into any event loop, but can also be used +without one, including in polling mode. + +You have to provide the necessary glue yourself, however. + +=over 4 + +=item int eio_init (void (*want_poll)(void), void (*done_poll)(void)) + +This function initialises the library. On success it returns C<0>, on +failure it returns C<-1> and sets C<errno> appropriately. + +It accepts two function pointers specifying callbacks as argument, both of +which can be C<0>, in which case the callback isn't called. + +=item want_poll callback + +The C<want_poll> callback is invoked whenever libeio wants attention (i.e. +it wants to be polled by calling C<eio_poll>). It is "edge-triggered", +that is, it will only be called once when eio wants attention, until all +pending requests have been handled. + +This callback is called while locks are being held, so I<you must +not call any libeio functions inside this callback>. That includes +C<eio_poll>. What you should do is notify some other thread, or wake up +your event loop, and then call C<eio_poll>. + +=item done_poll callback + +This callback is invoked when libeio detects that all pending requests +have been handled. It is "edge-triggered", that is, it will only be +called once after C<want_poll>. To put it differently, C<want_poll> and +C<done_poll> are invoked in pairs: after C<want_poll> you have to call +C<eio_poll ()> until either C<eio_poll> indicates that everything has been +handled or C<done_poll> has been called, which signals the same. + +Note that C<eio_poll> might return after C<done_poll> and C<want_poll> +have been called again, so watch out for races in your code. + +As with C<want_poll>, this callback is called while lcoks are being held, +so you I<must not call any libeio functions form within this callback>. + +=item int eio_poll () + +This function has to be called whenever there are pending requests that +need finishing. You usually call this after C<want_poll> has indicated +that you should do so, but you can also call this function regularly to +poll for new results. + +If any request invocation returns a non-zero value, then C<eio_poll ()> +immediately returns with that value as return value. + +Otherwise, if all requests could be handled, it returns C<0>. If for some +reason not all requests have been handled, i.e. some are still pending, it +returns C<-1>. + +=back + +For libev, you would typically use an C<ev_async> watcher: the +C<want_poll> callback would invoke C<ev_async_send> to wake up the event +loop. Inside the callback set for the watcher, one would call C<eio_poll +()> (followed by C<ev_async_send> again if C<eio_poll> indicates that not +all requests have been handled yet). The race is taken care of because +libev resets/rearms the async watcher before calling your callback, +and therefore, before calling C<eio_poll>. This might result in (some) +spurious wake-ups, but is generally harmless. + +For most other event loops, you would typically use a pipe - the event +loop should be told to wait for read readyness on the read end. In +C<want_poll> you would write a single byte, in C<done_poll> you would try +to read that byte, and in the callback for the read end, you would call +C<eio_poll>. The race is avoided here because the event loop should invoke +your callback again and again until the byte has been read (as the pipe +read callback does not read it, only C<done_poll>). + +=head2 CONFIGURATION + +The functions in this section can sometimes be useful, but the default +configuration will do in most case, so you should skip this section on +first reading. + +=over 4 + +=item eio_set_max_poll_time (eio_tstamp nseconds) + +This causes C<eio_poll ()> to return after it has detected that it was +running for C<nsecond> seconds or longer (this number can be fractional). + +This can be used to limit the amount of time spent handling eio requests, +for example, in interactive programs, you might want to limit this time to +C<0.01> seconds or so. + +Note that: + +a) libeio doesn't know how long your request callbacks take, so the time +spent in C<eio_poll> is up to one callback invocation longer then this +interval. + +b) this is implemented by calling C<gettimeofday> after each request, +which can be costly. + +c) at least one request will be handled. + +=item eio_set_max_poll_reqs (unsigned int nreqs) + +When C<nreqs> is non-zero, then C<eio_poll> will not handle more than +C<nreqs> requests per invocation. This is a less costly way to limit the +amount of work done by C<eio_poll> then setting a time limit. + +If you know your callbacks are generally fast, you could use this to +encourage interactiveness in your programs by setting it to C<10>, C<100> +or even C<1000>. + +=item eio_set_min_parallel (unsigned int nthreads) + +Make sure libeio can handle at least this many requests in parallel. It +might be able handle more. + +=item eio_set_max_parallel (unsigned int nthreads) + +Set the maximum number of threads that libeio will spawn. + +=item eio_set_max_idle (unsigned int nthreads) + +Libeio uses threads internally to handle most requests, and will start and stop threads on demand. + +This call can be used to limit the number of idle threads (threads without +work to do): libeio will keep some threads idle in preperation for more +requests, but never longer than C<nthreads> threads. + +In addition to this, libeio will also stop threads when they are idle for +a few seconds, regardless of this setting. + +=item unsigned int eio_nthreads () + +Return the number of worker threads currently running. + +=item unsigned int eio_nreqs () + +Return the number of requests currently handled by libeio. This is the +total number of requests that have been submitted to libeio, but not yet +destroyed. + +=item unsigned int eio_nready () + +Returns the number of ready requests, i.e. requests that have been +submitted but have not yet entered the execution phase. + +=item unsigned int eio_npending () + +Returns the number of pending requests, i.e. requests that have been +executed and have results, but have not been finished yet by a call to +C<eio_poll>). + +=back + + +=head1 ANATOMY OF AN EIO REQUEST + +#TODO + + +=head1 HIGH LEVEL REQUEST API + +#TODO + +=back + + +=head1 LOW LEVEL REQUEST API + +#TODO + +=head1 EMBEDDING + +Libeio can be embedded directly into programs. This functionality is not +documented and not (yet) officially supported. + +Note that, when including C<libeio.m4>, you are responsible for defining +the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.). + +If you need to know how, check the C<IO::AIO> perl module, which does +exactly that. + + +=head1 PORTABILITY REQUIREMENTS + +In addition to a working ISO-C implementation, libeio relies on a few +additional extensions: + +=over 4 + +=item POSIX threads + +To be portable, this module uses threads, specifically, the POSIX threads +library must be available (and working, which partially excludes many xBSD +systems, where C<fork ()> is buggy). + +=item POSIX-compatible filesystem API + +This is actually a harder portability requirement: The libeio API is quite +demanding regarding POSIX API calls (symlinks, user/group management +etc.). + +=item C<double> must hold a time value in seconds with enough accuracy + +The type C<double> is used to represent timestamps. It is required to +have at least 51 bits of mantissa (and 9 bits of exponent), which is good +enough for at least into the year 4000. This requirement is fulfilled by +implementations implementing IEEE 754 (basically all existing ones). + +=back + +If you know of other additional requirements drop me a note. + + +=head1 AUTHOR + +Marc Lehmann <libeio@schmorp.de>. + diff --git a/deps/libeio/libeio.m4 b/deps/libeio/libeio.m4 new file mode 100644 index 0000000000..c3efcd2cbb --- /dev/null +++ b/deps/libeio/libeio.m4 @@ -0,0 +1,107 @@ +AC_SEARCH_LIBS( + pthread_create, + [pthread pthreads pthreadVC2], + , + [AC_MSG_ERROR(pthread functions not found)] +) + +AC_CACHE_CHECK(for futimes, ac_cv_futimes, [AC_LINK_IFELSE([[ +#include <sys/types.h> +#include <sys/time.h> +#include <utime.h> +struct timeval tv[2]; +int res; +int fd; +int main(void) +{ + res = futimes (fd, tv); + return 0; +} +]],ac_cv_futimes=yes,ac_cv_futimes=no)]) +test $ac_cv_futimes = yes && AC_DEFINE(HAVE_FUTIMES, 1, futimes(2) is available) + +AC_CACHE_CHECK(for readahead, ac_cv_readahead, [AC_LINK_IFELSE([ +#include <fcntl.h> +int main(void) +{ + int fd = 0; + size_t count = 2; + ssize_t res; + res = readahead (fd, 0, count); + return 0; +} +],ac_cv_readahead=yes,ac_cv_readahead=no)]) +test $ac_cv_readahead = yes && AC_DEFINE(HAVE_READAHEAD, 1, readahead(2) is available (linux)) + +AC_CACHE_CHECK(for fdatasync, ac_cv_fdatasync, [AC_LINK_IFELSE([ +#include <unistd.h> +int main(void) +{ + int fd = 0; + fdatasync (fd); + return 0; +} +],ac_cv_fdatasync=yes,ac_cv_fdatasync=no)]) +test $ac_cv_fdatasync = yes && AC_DEFINE(HAVE_FDATASYNC, 1, fdatasync(2) is available) + +AC_CACHE_CHECK(for pread and pwrite, ac_cv_preadwrite, [AC_LINK_IFELSE([ +#include <unistd.h> +int main(void) +{ + int fd = 0; + size_t count = 1; + char buf; + off_t offset = 1; + ssize_t res; + res = pread (fd, &buf, count, offset); + res = pwrite (fd, &buf, count, offset); + return 0; +} +],ac_cv_preadwrite=yes,ac_cv_preadwrite=no)]) +test $ac_cv_preadwrite = yes && AC_DEFINE(HAVE_PREADWRITE, 1, pread(2) and pwrite(2) are available) + +AC_CACHE_CHECK(for sendfile, ac_cv_sendfile, [AC_LINK_IFELSE([ +# include <sys/types.h> +#if __linux +# include <sys/sendfile.h> +#elif __freebsd +# include <sys/socket.h> +# include <sys/uio.h> +#elif __hpux +# include <sys/socket.h> +#else +# error unsupported architecture +#endif +int main(void) +{ + int fd = 0; + off_t offset = 1; + size_t count = 2; + ssize_t res; +#if __linux + res = sendfile (fd, fd, offset, count); +#elif __freebsd + res = sendfile (fd, fd, offset, count, 0, &offset, 0); +#elif __hpux + res = sendfile (fd, fd, offset, count, 0, 0); +#endif + return 0; +} +],ac_cv_sendfile=yes,ac_cv_sendfile=no)]) +test $ac_cv_sendfile = yes && AC_DEFINE(HAVE_SENDFILE, 1, sendfile(2) is available and supported) + +AC_CACHE_CHECK(for sync_file_range, ac_cv_sync_file_range, [AC_LINK_IFELSE([ +#include <fcntl.h> +int main(void) +{ + int fd = 0; + off64_t offset = 1; + off64_t nbytes = 1; + unsigned int flags = SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER; + ssize_t res; + res = sync_file_range (fd, offset, nbytes, flags); + return 0; +} +],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)]) +test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available) + diff --git a/deps/libeio/xthread.h b/deps/libeio/xthread.h new file mode 100644 index 0000000000..e53cb53da8 --- /dev/null +++ b/deps/libeio/xthread.h @@ -0,0 +1,154 @@ +#ifndef XTHREAD_H_ +#define XTHREAD_H_ + +/* whether word reads are potentially non-atomic. + * this is conservatice, likely most arches this runs + * on have atomic word read/writes. + */ +#ifndef WORDACCESS_UNSAFE +# if __i386 || __x86_64 +# define WORDACCESS_UNSAFE 0 +# else +# define WORDACCESS_UNSAFE 1 +# endif +#endif + +///////////////////////////////////////////////////////////////////////////// + +#ifdef _WIN32 +typedef int ssize_t; + +#define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls +#define _WIN32_WINNT 0x400 +#include <stdio.h>//D +#include <fcntl.h> +#include <io.h> +#include <time.h> +#include <winsock2.h> +#include <process.h> +#include <windows.h> +#include <pthread.h> +#define sigset_t int +#define sigfillset(a) +#define pthread_sigmask(a,b,c) +#define sigaddset(a,b) +#define sigemptyset(s) +#define sigfillset(s) + +typedef pthread_mutex_t mutex_t; +#define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#define X_LOCK(mutex) pthread_mutex_lock (&(mutex)) +#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) + +typedef pthread_cond_t cond_t; +#define X_COND_INIT PTHREAD_COND_INITIALIZER +#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) +#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) +#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) + +typedef pthread_t thread_t; +#define X_THREAD_PROC(name) void *name (void *thr_arg) +#define X_THREAD_ATFORK(a,b,c) + +static int +thread_create (thread_t *tid, void *(*proc)(void *), void *arg) +{ + int retval; + pthread_attr_t attr; + + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + + retval = pthread_create (tid, &attr, proc, arg) == 0; + + pthread_attr_destroy (&attr); + + return retval; +} + +#define respipe_read(a,b,c) PerlSock_recv ((a), (b), (c), 0) +#define respipe_write(a,b,c) send ((a), (b), (c), 0) +#define respipe_close(a) PerlSock_closesocket ((a)) + +#else +///////////////////////////////////////////////////////////////////////////// + +#if __linux && !defined(_GNU_SOURCE) +# define _GNU_SOURCE +#endif + +/* just in case */ +#define _REENTRANT 1 + +#if __solaris +# define _POSIX_PTHREAD_SEMANTICS 1 +/* try to bribe solaris headers into providing a current pthread API + * despite environment being configured for an older version. + */ +# define __EXTENSIONS__ 1 +#endif + +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <limits.h> +#include <pthread.h> + +typedef pthread_mutex_t mutex_t; +#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP) +# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +#else +# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER +#endif +#define X_LOCK(mutex) pthread_mutex_lock (&(mutex)) +#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex)) + +typedef pthread_cond_t cond_t; +#define X_COND_INIT PTHREAD_COND_INITIALIZER +#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond)) +#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex)) +#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to)) + +typedef pthread_t thread_t; +#define X_THREAD_PROC(name) static void *name (void *thr_arg) +#define X_THREAD_ATFORK(prepare,parent,child) pthread_atfork (prepare, parent, child) + +// the broken bsd's once more +#ifndef PTHREAD_STACK_MIN +# define PTHREAD_STACK_MIN 0 +#endif + +static int +thread_create (thread_t *tid, void *(*proc)(void *), void *arg) +{ + int retval; + sigset_t fullsigset, oldsigset; + pthread_attr_t attr; + + pthread_attr_init (&attr); + pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096 + ? sizeof (long) * 4096 : PTHREAD_STACK_MIN); +#ifdef PTHREAD_SCOPE_PROCESS + pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS); +#endif + + sigfillset (&fullsigset); + + pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset); + retval = pthread_create (tid, &attr, proc, arg) == 0; + pthread_sigmask (SIG_SETMASK, &oldsigset, 0); + + pthread_attr_destroy (&attr); + + return retval; +} + +#define respipe_read(a,b,c) read ((a), (b), (c)) +#define respipe_write(a,b,c) write ((a), (b), (c)) +#define respipe_close(a) close ((a)) + +#endif + +#endif + |