diff --git a/INSTALL b/INSTALL index 54caf7c19..8865734f8 100644 --- a/INSTALL +++ b/INSTALL @@ -1,81 +1,109 @@ -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Installation Instructions +************************* + + Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software Foundation, Inc. - This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. + Copying and distribution of this file, with or without modification, +are permitted in any medium without royalty provided the copyright +notice and this notice are preserved. This file is offered as-is, +without warranty of any kind. Basic Installation ================== - These are generic installation instructions. + Briefly, the shell command './configure && make && make install' +should configure, build, and install this package. The following +more-detailed instructions are generic; see the 'README' file for +instructions specific to this package. Some packages provide this +'INSTALL' file but do not implement all of the features documented +below. The lack of an optional feature in a given package is not +necessarily a bug. More recommendations for GNU packages can be found +in *note Makefile Conventions: (standards)Makefile Conventions. - The `configure' shell script attempts to guess correct values for + The 'configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that +those values to create a 'Makefile' in each directory of the package. +It may also create one or more '.h' files containing system-dependent +definitions. Finally, it creates a shell script 'config.status' that you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). +file 'config.log' containing compiler output (useful mainly for +debugging 'configure'). - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) + It can also use an optional file (typically called 'config.cache' and +enabled with '--cache-file=config.cache' or simply '-C') that saves the +results of its tests to speed up reconfiguring. Caching is disabled by +default to prevent problems with accidental use of stale cache files. If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can +to figure out how 'configure' could check whether to do them, and mail +diffs or instructions to the address given in the 'README' so they can be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you +some point 'config.cache' contains results you don't want to keep, you may remove or edit it. - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. + The file 'configure.ac' (or 'configure.in') is used to create +'configure' by a program called 'autoconf'. You need 'configure.ac' if +you want to change it or regenerate 'configure' using a newer version of +'autoconf'. + + The simplest way to compile this package is: -The simplest way to compile this package is: + 1. 'cd' to the directory containing the package's source code and type + './configure' to configure the package for your system. - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. + Running 'configure' might take a while. While running, it prints + some messages telling which features it is checking for. - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. + 2. Type 'make' to compile the package. - 2. Type `make' to compile the package. + 3. Optionally, type 'make check' to run any self-tests that come with + the package, generally using the just-built uninstalled binaries. - 3. Optionally, type `make check' to run any self-tests that come with - the package. + 4. Type 'make install' to install the programs and any data files and + documentation. When installing into a prefix owned by root, it is + recommended that the package be configured and built as a regular + user, and only the 'make install' phase executed with root + privileges. - 4. Type `make install' to install the programs and any data files and - documentation. + 5. Optionally, type 'make installcheck' to repeat any self-tests, but + this time using the binaries in their final installed location. + This target does not install anything. Running this target as a + regular user, particularly if the prior 'make install' required + root privileges, verifies that the installation completed + correctly. - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly + 6. You can remove the program binaries and object files from the + source code directory by typing 'make clean'. To also remove the + files that 'configure' created (so you can compile the package for + a different kind of computer), type 'make distclean'. There is + also a 'make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. + 7. Often, you can also type 'make uninstall' to remove the installed + files again. In practice, not all packages have tested that + uninstallation works correctly, even though it is required by the + GNU Coding Standards. + + 8. Some packages, particularly those that use Automake, provide 'make + distcheck', which can by used by developers to test that all other + targets like 'make install' and 'make uninstall' work correctly. + This target is generally not run by end users. + Compilers and Options ===================== Some systems require unusual options for compilation or linking that -the `configure' script does not know about. Run `./configure --help' +the 'configure' script does not know about. Run './configure --help' for details on some of the pertinent environment variables. - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: + You can give 'configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here is +an example: - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + ./configure CC=c99 CFLAGS=-g LIBS=-lposix *Note Defining Variables::, for more details. @@ -84,146 +112,257 @@ Compiling For Multiple Architectures You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the +own directory. To do this, you can use GNU 'make'. 'cd' to the directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. +the 'configure' script. 'configure' automatically checks for the source +code in the directory that 'configure' is in and in '..'. This is known +as a "VPATH" build. + + With a non-GNU 'make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use 'make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. Installation Names ================== - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. + By default, 'make install' installs the package's commands under +'/usr/local/bin', include files under '/usr/local/include', etc. You +can specify an installation prefix other than '/usr/local' by giving +'configure' the option '--prefix=PREFIX', where PREFIX must be an +absolute file name. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. +pass the option '--exec-prefix=PREFIX' to 'configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. +options like '--bindir=DIR' to specify different values for particular +kinds of files. Run 'configure --help' for a list of the directories +you can set and what kinds of files go in them. In general, the default +for these options is expressed in terms of '${prefix}', so that +specifying just '--prefix' will affect all of the other directory +specifications that were not explicitly provided. + + The most portable way to affect installation locations is to pass the +correct locations to 'configure'; however, many packages provide one or +both of the following shortcuts of passing variable assignments to the +'make install' command line to change installation locations without +having to reconfigure or recompile. + + The first method involves providing an override variable for each +affected directory. For example, 'make install +prefix=/alternate/directory' will choose an alternate location for all +directory configuration variables that were expressed in terms of +'${prefix}'. Any directories that were specified during 'configure', +but not in terms of '${prefix}', must each be overridden at install time +for the entire installation to be relocated. The approach of makefile +variable overrides for each directory variable is required by the GNU +Coding Standards, and ideally causes no recompilation. However, some +platforms have known limitations with the semantics of shared libraries +that end up requiring recompilation when using this method, particularly +noticeable in packages that use GNU Libtool. + + The second method involves providing the 'DESTDIR' variable. For +example, 'make install DESTDIR=/alternate/directory' will prepend +'/alternate/directory' before all installation names. The approach of +'DESTDIR' overrides is not required by the GNU Coding Standards, and +does not work on platforms that have drive letters. On the other hand, +it does better at avoiding recompilation issues, and works well even +when some directory options were not specified in terms of '${prefix}' +at 'configure' time. Optional Features ================= - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving 'configure' the +option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'. + + Some packages pay attention to '--enable-FEATURE' options to +'configure', where FEATURE indicates an optional part of the package. +They may also pay attention to '--with-PACKAGE' options, where PACKAGE +is something like 'gnu-as' or 'x' (for the X Window System). The +'README' should mention any '--enable-' and '--with-' options that the package recognizes. - For packages that use the X Window System, `configure' can usually + For packages that use the X Window System, 'configure' can usually find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. +you can use the 'configure' options '--x-includes=DIR' and +'--x-libraries=DIR' to specify their locations. + + Some packages offer the ability to configure how verbose the +execution of 'make' will be. For these packages, running './configure +--enable-silent-rules' sets the default to minimal output, which can be +overridden with 'make V=1'; while running './configure +--disable-silent-rules' sets the default to verbose, which can be +overridden with 'make V=0'. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + HP-UX 'make' updates targets which have the same time stamps as their +prerequisites, which makes it generally unusable when shipped generated +files such as 'configure' are involved. Use GNU 'make' instead. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its '' header file. The option '-nodtk' can be used as a +workaround. If GNU CC is not installed, it is therefore recommended to +try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put '/usr/ucb' early in your 'PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in '/usr/bin'. So, if you need '/usr/ucb' +in your 'PATH', put it _after_ '/usr/bin'. + + On Haiku, software installed for all users goes in '/boot/common', +not '/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common Specifying the System Type ========================== - There may be some features `configure' cannot figure out + There may be some features 'configure' cannot figure out automatically, but needs to determine by the type of machine the package will run on. Usually, assuming the package is built to be run on the -_same_ architectures, `configure' can figure that out, but if it prints +_same_ architectures, 'configure' can figure that out, but if it prints a message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: +'--build=TYPE' option. TYPE can either be a short name for the system +type, such as 'sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: - OS KERNEL-OS + OS + KERNEL-OS - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't + See the file 'config.sub' for the possible values of each field. If +'config.sub' isn't included in this package, then this package doesn't need to know the machine type. If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will +use the option '--target=TYPE' to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the "host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. +eventually be run) with '--host=TYPE'. Sharing Defaults ================ - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. + If you want to set default values for 'configure' scripts to share, +you can create a site shell script called 'config.site' that gives +default values for variables like 'CC', 'cache_file', and 'prefix'. +'configure' looks for 'PREFIX/share/config.site' if it exists, then +'PREFIX/etc/config.site' if it exists. Or, you can set the +'CONFIG_SITE' environment variable to the location of the site script. +A warning: not all 'configure' scripts look for a site script. Defining Variables ================== Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run +environment passed to 'configure'. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: +them in the 'configure' command line, using 'VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc -will cause the specified gcc to be used as the C compiler (unless it is +causes the specified 'gcc' to be used as the C compiler (unless it is overridden in the site shell script). -`configure' Invocation +Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an +Autoconf limitation. Until the limitation is lifted, you can use this +workaround: + + CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash + +'configure' Invocation ====================== - `configure' recognizes the following options to control how it + 'configure' recognizes the following options to control how it operates. -`--help' -`-h' - Print a summary of the options to `configure', and exit. +'--help' +'-h' + Print a summary of all of the options to 'configure', and exit. + +'--help=short' +'--help=recursive' + Print a summary of the options unique to this package's + 'configure', and exit. The 'short' variant lists options used only + in the top level, while the 'recursive' variant lists options also + present in any nested packages. -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' +'--version' +'-V' + Print the version of Autoconf used to generate the 'configure' script, and exit. -`--cache-file=FILE' +'--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to + traditionally 'config.cache'. FILE defaults to '/dev/null' to disable caching. -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. +'--config-cache' +'-C' + Alias for '--cache-file=config.cache'. -`--quiet' -`--silent' -`-q' +'--quiet' +'--silent' +'-q' Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error + suppress all normal output, redirect it to '/dev/null' (any error messages will still be shown). -`--srcdir=DIR' +'--srcdir=DIR' Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. + 'configure' can determine that directory automatically. + +'--prefix=DIR' + Use DIR as the installation prefix. *note Installation Names:: for + more details, including other options available for fine-tuning the + installation locations. -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. +'--no-create' +'-n' + Run the configure checks, but stop before creating any output + files. +'configure' also accepts some other, not widely useful, options. Run +'configure --help' for more details. diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 79afab8e5..000000000 --- a/autogen.sh +++ /dev/null @@ -1,51 +0,0 @@ -#! /bin/sh - -echo aclocal... -(aclocal --version) < /dev/null > /dev/null 2>&1 || { - echo aclocal not found - exit 1 -} - -aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1 - -echo autoheader... -(autoheader --version) < /dev/null > /dev/null 2>&1 || { - echo autoheader not found - exit 1 -} - -autoheader || exit 1 - -echo -n "libtoolize... " -if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then - echo "using glibtoolize" - glibtoolize --automake --copy --force || exit 1 - -elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then - echo "using libtoolize" - libtoolize --automake --copy --force || exit 1 - -else - echo "libtoolize nor glibtoolize not found" - exit 1 -fi - -echo automake... -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo automake not found - exit 1 -} - -automake --add-missing --copy --gnu || exit 1 - -echo autoconf... -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo autoconf not found - exit 1 -} - -autoconf || exit 1 - -echo ready to configure - -exit 0 diff --git a/configure.ac b/configure.ac index 88a46edde..453e29361 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,14 @@ -AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com) +AC_INIT([[libtorrent]],[[0.13.8]],[[sundell.software@gmail.com]]) -LT_INIT([disable-static]) +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_MACRO_DIRS([scripts]) +AM_INIT_AUTOMAKE([serial-tests subdir-objects foreign]) + +LT_INIT([[disable-static]]) dnl Find a better way to do this -AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id) -AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT) +AC_DEFINE([[PEER_NAME]], [["-lt0D80-"]], [[Identifier that is part of the default peer id.]]) +AC_DEFINE([[PEER_VERSION]], [["lt\x0D\x80"]], [[4 byte client and version identifier for DHT.]]) LIBTORRENT_CURRENT=21 LIBTORRENT_REVISION=0 @@ -17,26 +21,22 @@ AC_SUBST(LIBTORRENT_CURRENT) AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO) AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO) -AM_INIT_AUTOMAKE([serial-tests subdir-objects]) -AC_CONFIG_HEADERS(config.h) - AC_PROG_CXX AC_SYS_LARGEFILE AC_C_BIGENDIAN( - AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian), - AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian), - AC_MSG_ERROR([Could not determine endianness]) + AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian), + AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian), + AC_MSG_ERROR([Could not determine endianness]) ) +AX_CXX_COMPILE_STDCXX(14, noext, mandatory) + RAK_CHECK_CFLAGS RAK_CHECK_CXXFLAGS RAK_ENABLE_DEBUG RAK_ENABLE_EXTRA_DEBUG RAK_ENABLE_WERROR -RAK_DISABLE_BACKTRACE - -RAK_CHECK_CXX11 TORRENT_ENABLE_ALIGNED TORRENT_ENABLE_INTERRUPT_SOCKET @@ -55,7 +55,25 @@ TORRENT_WITHOUT_STATVFS TORRENT_WITHOUT_STATFS TORRENT_WITH_INOTIFY -CC_ATTRIBUTE_VISIBILITY +AC_ARG_ENABLE(attribute-visibility, + AS_HELP_STRING([--disable-attribute-visibility],[disable symbol visibility attribute [[default=enable]]]), + [ + if test "$enableval" = "yes"; then + CC_ATTRIBUTE_VISIBILITY + fi + ],[ + CC_ATTRIBUTE_VISIBILITY + ]) + +AC_ARG_ENABLE(execinfo, + AS_HELP_STRING([--disable-execinfo],[disable libexecinfo [[default=enable]]]), + [ + if test "$enableval" = "yes"; then + AX_EXECINFO + fi + ],[ + AX_EXECINFO + ]) AX_CHECK_ZLIB AX_PTHREAD @@ -71,11 +89,11 @@ TORRENT_ARG_CYRUS_RC4 AC_CHECK_FUNCS(posix_memalign) -TORRENT_CHECK_MADVISE() -TORRENT_CHECK_CACHELINE() -TORRENT_CHECK_POPCOUNT() -TORRENT_CHECK_PTHREAD_SETNAME_NP() -TORRENT_MINCORE() +TORRENT_CHECK_MADVISE +TORRENT_CHECK_CACHELINE +TORRENT_CHECK_POPCOUNT +TORRENT_DISABLE_PTHREAD_SETNAME_NP +TORRENT_MINCORE TORRENT_DISABLE_INSTRUMENTATION @@ -88,16 +106,17 @@ AC_SUBST(LIBTORRENT_CFLAGS) AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included) CC_ATTRIBUTE_UNUSED( - AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]), - AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported]) + AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]), + AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported]) ) -AC_OUTPUT([ +AC_CONFIG_FILES([ libtorrent.pc Makefile src/Makefile src/torrent/Makefile - test/Makefile - test/torrent/net/Makefile - test/net/Makefile + test/Makefile + test/torrent/net/Makefile + test/net/Makefile ]) +AC_OUTPUT diff --git a/scripts/ax_check_zlib.m4 b/scripts/ax_check_zlib.m4 old mode 100644 new mode 100755 index ae5705f62..1a1684304 --- a/scripts/ax_check_zlib.m4 +++ b/scripts/ax_check_zlib.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html +# https://www.gnu.org/software/autoconf-archive/ax_check_zlib.html # =========================================================================== # # SYNOPSIS @@ -47,7 +47,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see . +# with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -62,7 +62,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 14 +#serial 16 AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB]) AC_DEFUN([AX_CHECK_ZLIB], @@ -108,11 +108,10 @@ then LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib" CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include" fi - AC_LANG_SAVE - AC_LANG_C + AC_LANG_PUSH([C]) AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no]) AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no]) - AC_LANG_RESTORE + AC_LANG_POP([C]) if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes" then # diff --git a/scripts/ax_cxx_compile_stdcxx.m4 b/scripts/ax_cxx_compile_stdcxx.m4 new file mode 100755 index 000000000..9413da624 --- /dev/null +++ b/scripts/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,962 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for no added switch, and then for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# Copyright (c) 2020 Jason Merrill +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 12 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [], [dnl + AC_CACHE_CHECK(whether $CXX supports C++$1 features by default, + ax_cv_cxx_compile_cxx$1, + [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [ax_cv_cxx_compile_cxx$1=yes], + [ax_cv_cxx_compile_cxx$1=no])]) + if test x$ax_cv_cxx_compile_cxx$1 = xyes; then + ac_success=yes + fi]) + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/scripts/ax_cxx_compile_stdcxx_0x.m4 b/scripts/ax_cxx_compile_stdcxx_0x.m4 deleted file mode 100644 index 5ff134a65..000000000 --- a/scripts/ax_cxx_compile_stdcxx_0x.m4 +++ /dev/null @@ -1,106 +0,0 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_0X -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++0x -# standard. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 7 (+1) - -AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X]) -AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [ - AC_CACHE_CHECK(if g++ supports C++0x features without additional flags, - ax_cv_cxx_compile_cxx0x_native, - [AC_LANG_SAVE - AC_LANG_CPLUSPLUS - AC_TRY_COMPILE([ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - typedef check> right_angle_brackets; - - int a; - decltype(a) b; - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c);],, - ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no) - AC_LANG_RESTORE - ]) - - AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x, - ax_cv_cxx_compile_cxx0x_cxx, - [AC_LANG_SAVE - AC_LANG_CPLUSPLUS - ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -std=c++0x" - AC_TRY_COMPILE([ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - typedef check> right_angle_brackets; - - int a; - decltype(a) b; - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c);],, - ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no) - CXXFLAGS="$ac_save_CXXFLAGS" - AC_LANG_RESTORE - ]) - - AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x, - ax_cv_cxx_compile_cxx0x_gxx, - [AC_LANG_SAVE - AC_LANG_CPLUSPLUS - ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS -std=gnu++0x" - AC_TRY_COMPILE([ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - typedef check> right_angle_brackets; - - int a; - decltype(a) b; - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c);],, - ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no) - CXXFLAGS="$ac_save_CXXFLAGS" - AC_LANG_RESTORE - ]) - - if test "$ax_cv_cxx_compile_cxx0x_cxx" = yes; then - AC_DEFINE(HAVE_STDCXX_0X,, [Define if compiler supports C++0x features.]) - CXXFLAGS="$CXXFLAGS -std=c++0x" - fi -]) diff --git a/scripts/ax_cxx_compile_stdcxx_11.m4 b/scripts/ax_cxx_compile_stdcxx_11.m4 deleted file mode 100644 index 5cf70eb68..000000000 --- a/scripts/ax_cxx_compile_stdcxx_11.m4 +++ /dev/null @@ -1,147 +0,0 @@ -# ============================================================================ -# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html -# ============================================================================ -# -# SYNOPSIS -# -# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional]) -# -# DESCRIPTION -# -# Check for baseline language coverage in the compiler for the C++11 -# standard; if necessary, add switches to CXXFLAGS to enable support. -# -# The first argument, if specified, indicates whether you insist on an -# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. -# -std=c++11). If neither is specified, you get whatever works, with -# preference for an extended mode. -# -# The second argument, if specified 'mandatory' or if left unspecified, -# indicates that baseline C++11 support is required and that the macro -# should error out if no mode with that support is found. If specified -# 'optional', then configuration proceeds regardless, after defining -# HAVE_CXX11 if and only if a supporting mode is found. -# -# LICENSE -# -# Copyright (c) 2008 Benjamin Kosnik -# Copyright (c) 2012 Zack Weinberg -# Copyright (c) 2013 Roy Stogner -# Copyright (c) 2014 Alexey Sokolov -# Copyright (c) 2014 Jari Sundell -# -# Copying and distribution of this file, with or without modification, are -# permitted in any medium without royalty provided the copyright notice -# and this notice are preserved. This file is offered as-is, without any -# warranty. - -#serial 5 - -m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[ - template - struct check - { - static_assert(sizeof(int) <= sizeof(T), "not big enough"); - }; - - struct Base { - virtual void f() {} - }; - struct Child : public Base { - virtual void f() override {} - }; - - typedef check> right_angle_brackets; - - int a; - decltype(a) b; - - typedef check check_type; - check_type c; - check_type&& cr = static_cast(c); - - auto d = a; - auto l = [](){}; - - void unused() { - l(); - } -]]) - -AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl - m4_if([$1], [], [], - [$1], [ext], [], - [$1], [noext], [], - [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl - m4_if([$2], [], [ax_cxx_compile_cxx11_required=true], - [$2], [mandatory], [ax_cxx_compile_cxx11_required=true], - [$2], [optional], [ax_cxx_compile_cxx11_required=false], - [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])]) - AC_LANG_PUSH([C++])dnl - ac_success=no - AC_CACHE_CHECK(whether $CXX supports C++11 features by default, - ax_cv_cxx_compile_cxx11, - [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [ax_cv_cxx_compile_cxx11=yes], - [ax_cv_cxx_compile_cxx11=no])]) - if test x$ax_cv_cxx_compile_cxx11 = xyes; then - ac_success=yes - fi - - m4_if([$1], [noext], [], [dnl - if test x$ac_success = xno; then - for switch in -std=gnu++11 -std=gnu++0x; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - - m4_if([$1], [ext], [], [dnl - if test x$ac_success = xno; then - for switch in -std=c++11 -std=c++0x; do - cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch]) - AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch, - $cachevar, - [ac_save_CXXFLAGS="$CXXFLAGS" - CXXFLAGS="$CXXFLAGS $switch" - AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])], - [eval $cachevar=yes], - [eval $cachevar=no]) - CXXFLAGS="$ac_save_CXXFLAGS"]) - if eval test x\$$cachevar = xyes; then - CXXFLAGS="$CXXFLAGS $switch" - ac_success=yes - break - fi - done - fi]) - AC_LANG_POP([C++]) - if test x$ax_cxx_compile_cxx11_required = xtrue; then - if test x$ac_success = xno; then - AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.]) - fi - else - if test x$ac_success = xno; then - HAVE_CXX11=0 - AC_MSG_NOTICE([No compiler with C++11 support was found]) - else - HAVE_CXX11=1 - AC_DEFINE(HAVE_CXX11,1, - [define if the compiler supports basic C++11 syntax]) - fi - - AC_SUBST(HAVE_CXX11) - fi -]) diff --git a/scripts/ax_pthread.m4 b/scripts/ax_pthread.m4 old mode 100644 new mode 100755 index 27f2533c5..9f35d1391 --- a/scripts/ax_pthread.m4 +++ b/scripts/ax_pthread.m4 @@ -1,5 +1,5 @@ # =========================================================================== -# http://www.gnu.org/software/autoconf-archive/ax_pthread.html +# https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS @@ -14,24 +14,28 @@ # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). (This -# is necessary on AIX to use the special cc_r compiler alias.) +# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is +# needed for multi-threaded programs (defaults to the value of CC +# respectively CXX otherwise). (This is necessary on e.g. AIX to use the +# special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, -# but also link it with them as well. e.g. you should link with +# but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS +# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # -# If you are only building threads programs, you may wish to use these +# If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" +# CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant -# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name -# (e.g. PTHREAD_CREATE_UNDETACHED on AIX). +# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to +# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with @@ -55,6 +59,7 @@ # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. +# Copyright (c) 2019 Marc Stevens # # 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 @@ -67,7 +72,7 @@ # Public License for more details. # # You should have received a copy of the GNU General Public License along -# with this program. If not, see . +# with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure @@ -82,35 +87,41 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 17 +#serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). +# requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" +if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then + ax_pthread_save_CC="$CC" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" + AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) + AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes) - AC_MSG_RESULT($ax_pthread_ok) - if test x"$ax_pthread_ok" = xno; then + AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) + AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) + AC_MSG_RESULT([$ax_pthread_ok]) + if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CC="$ax_pthread_save_CC" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different @@ -118,12 +129,14 @@ fi # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. +# Create a list of thread flags to try. Items with a "," contain both +# C compiler flags (before ",") and linker flags (after ","). Other items +# starting with a "-" are C compiler flags, and remaining items are +# library names, except for "none" which indicates that we try without +# any flags at all, and "pthread-config" which is a program returning +# the flags for the Pth emulation library. -ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" +ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: @@ -132,68 +145,163 @@ ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mt # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc +# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 +# (Note: HP C rejects this with "bad form for `-t' option") +# -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC +# doesn't hurt to check since this sometimes defines pthreads and +# -D_REENTRANT too), HP C (must be checked before -lpthread, which +# is present but should not be used directly; and before -mthreads, +# because the compiler interprets this as "-mt" + "-hreads") +# -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) -case "${host_cpu}-${host_os}" in - *solaris*) +case $host_os in + + freebsd*) + + # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) + # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) + + ax_pthread_flags="-kthread lthread $ax_pthread_flags" + ;; + + hpux*) + + # From the cc(1) man page: "[-mt] Sets various -D flags to enable + # multi-threading and also sets -lpthread." + + ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" + ;; + + openedition*) + + # IBM z/OS requires a feature-test macro to be defined in order to + # enable POSIX threads at all, so give the user a hint if this is + # not set. (We don't define these ourselves, as they can affect + # other portions of the system API in unpredictable ways.) + + AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], + [ +# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) + AX_PTHREAD_ZOS_MISSING +# endif + ], + [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) + ;; + + solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: + # tests will erroneously succeed. (N.B.: The stubs are missing + # pthread_cleanup_push, or rather a function called by this macro, + # so we could check for that, but who knows whether they'll stub + # that too in a future libc.) So we'll check first for the + # standard Solaris way of linking pthreads (-mt -lpthread). - ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags" + ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; +esac - *-darwin*) - ax_pthread_flags="none -pthread $ax_pthread_flags" +# Are we compiling with Clang? + +AC_CACHE_CHECK([whether $CC is Clang], + [ax_cv_PTHREAD_CLANG], + [ax_cv_PTHREAD_CLANG=no + # Note that Autoconf sets GCC=yes for Clang as well as GCC + if test "x$GCC" = "xyes"; then + AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], + [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ +# if defined(__clang__) && defined(__llvm__) + AX_PTHREAD_CC_IS_CLANG +# endif + ], + [ax_cv_PTHREAD_CLANG=yes]) + fi + ]) +ax_pthread_clang="$ax_cv_PTHREAD_CLANG" + + +# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) + +# Note that for GCC and Clang -pthread generally implies -lpthread, +# except when -nostdlib is passed. +# This is problematic using libtool to build C++ shared libraries with pthread: +# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 +# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 +# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 +# To solve this, first try -pthread together with -lpthread for GCC + +AS_IF([test "x$GCC" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) + +# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first + +AS_IF([test "x$ax_pthread_clang" = "xyes"], + [ax_pthread_flags="-pthread,-lpthread -pthread"]) + + +# The presence of a feature test macro requesting re-entrant function +# definitions is, on some systems, a strong hint that pthreads support is +# correctly enabled + +case $host_os in + darwin* | hpux* | linux* | osf* | solaris*) + ax_pthread_check_macro="_REENTRANT" + ;; + + aix*) + ax_pthread_check_macro="_THREAD_SAFE" + ;; + + *) + ax_pthread_check_macro="--" ;; esac +AS_IF([test "x$ax_pthread_check_macro" = "x--"], + [ax_pthread_check_cond=0], + [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) + -if test x"$ax_pthread_ok" = xno; then -for flag in $ax_pthread_flags; do +if test "x$ax_pthread_ok" = "xno"; then +for ax_pthread_try_flag in $ax_pthread_flags; do - case $flag in + case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; + *,*) + PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` + PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` + AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) + ;; + -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" + AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) + PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) - AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no) - if test x"$ax_pthread_config" = xno; then continue; fi + AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) + AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" + AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) + PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we @@ -204,8 +312,18 @@ for flag in $ax_pthread_flags; do # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include - static void routine(void *a) { a = 0; } +# if $ax_pthread_check_cond +# error "$ax_pthread_check_macro must be defined" +# endif + static void *some_global = NULL; + static void routine(void *a) + { + /* To avoid any unused-parameter or + unused-but-set-parameter warning. */ + some_global = a; + } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); @@ -213,93 +331,188 @@ for flag in $ax_pthread_flags; do pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], - [ax_pthread_ok=yes], - []) + [ax_pthread_ok=yes], + []) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - AC_MSG_RESULT($ax_pthread_ok) - if test "x$ax_pthread_ok" = xyes; then - break; - fi + AC_MSG_RESULT([$ax_pthread_ok]) + AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi + +# Clang needs special handling, because older versions handle the -pthread +# option in a rather... idiosyncratic way + +if test "x$ax_pthread_clang" = "xyes"; then + + # Clang takes -pthread; it has never supported any other flag + + # (Note 1: This will need to be revisited if a system that Clang + # supports has POSIX threads in a separate library. This tends not + # to be the way of modern systems, but it's conceivable.) + + # (Note 2: On some systems, notably Darwin, -pthread is not needed + # to get POSIX threads support; the API is always present and + # active. We could reasonably leave PTHREAD_CFLAGS empty. But + # -pthread does define _REENTRANT, and while the Darwin headers + # ignore this macro, third-party headers might not.) + + # However, older versions of Clang make a point of warning the user + # that, in an invocation where only linking and no compilation is + # taking place, the -pthread option has no effect ("argument unused + # during compilation"). They expect -pthread to be passed in only + # when source code is being compiled. + # + # Problem is, this is at odds with the way Automake and most other + # C build frameworks function, which is that the same flags used in + # compilation (CFLAGS) are also used in linking. Many systems + # supported by AX_PTHREAD require exactly this for POSIX threads + # support, and in fact it is often not straightforward to specify a + # flag that is used only in the compilation phase and not in + # linking. Such a scenario is extremely rare in practice. + # + # Even though use of the -pthread flag in linking would only print + # a warning, this can be a nuisance for well-run software projects + # that build with -Werror. So if the active version of Clang has + # this misfeature, we search for an option to squash it. + + AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], + [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown + # Create an alternate version of $ac_link that compiles and + # links in two steps (.c -> .o, .o -> exe) instead of one + # (.c -> exe), because the warning occurs only in the second + # step + ax_pthread_save_ac_link="$ac_link" + ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' + ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` + ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" + ax_pthread_save_CFLAGS="$CFLAGS" + for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do + AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) + CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" + ac_link="$ax_pthread_save_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [ac_link="$ax_pthread_2step_ac_link" + AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], + [break]) + ]) + done + ac_link="$ax_pthread_save_ac_link" + CFLAGS="$ax_pthread_save_CFLAGS" + AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) + ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" + ]) + + case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in + no | unknown) ;; + *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; + esac + +fi # $ax_pthread_clang = yes + + + # Various other checks: -if test "x$ax_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" +if test "x$ax_pthread_ok" = "xyes"; then + ax_pthread_save_CFLAGS="$CFLAGS" + ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], - [int attr = $attr; return attr /* ; */])], - [attr_name=$attr; break], - []) - done - AC_MSG_RESULT($attr_name) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi + AC_CACHE_CHECK([for joinable pthread attribute], + [ax_cv_PTHREAD_JOINABLE_ATTR], + [ax_cv_PTHREAD_JOINABLE_ATTR=unknown + for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do + AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], + [int attr = $ax_pthread_attr; return attr /* ; */])], + [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], + []) + done + ]) + AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ + test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ + test "x$ax_pthread_joinable_attr_defined" != "xyes"], + [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], + [$ax_cv_PTHREAD_JOINABLE_ATTR], + [Define to necessary symbol if this constant + uses a non-standard name on your system.]) + ax_pthread_joinable_attr_defined=yes + ]) - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case "${host_cpu}-${host_os}" in - *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; - *-osf* | *-hpux*) flag="-D_REENTRANT";; - *solaris*) - if test "$GCC" = "yes"; then - flag="-D_REENTRANT" - else - flag="-mt -D_REENTRANT" - fi - ;; - esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi + AC_CACHE_CHECK([whether more special flags are required for pthreads], + [ax_cv_PTHREAD_SPECIAL_FLAGS], + [ax_cv_PTHREAD_SPECIAL_FLAGS=no + case $host_os in + solaris*) + ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" + ;; + esac + ]) + AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ + test "x$ax_pthread_special_flags_added" != "xyes"], + [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" + ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], - ax_cv_PTHREAD_PRIO_INHERIT, [ - AC_LINK_IFELSE([ - AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT;]])], - [ax_cv_PTHREAD_PRIO_INHERIT=yes], - [ax_cv_PTHREAD_PRIO_INHERIT=no]) + [ax_cv_PTHREAD_PRIO_INHERIT], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[int i = PTHREAD_PRIO_INHERIT; + return i;]])], + [ax_cv_PTHREAD_PRIO_INHERIT=yes], + [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) - AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"], - AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.])) + AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ + test "x$ax_pthread_prio_inherit_defined" != "xyes"], + [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) + ax_pthread_prio_inherit_defined=yes + ]) - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" + CFLAGS="$ax_pthread_save_CFLAGS" + LIBS="$ax_pthread_save_LIBS" - # More AIX lossage: must compile with xlc_r or cc_r - if test x"$GCC" != xyes; then - AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) - else - PTHREAD_CC=$CC + # More AIX lossage: compile with *_r variant + if test "x$GCC" != "xyes"; then + case $host_os in + aix*) + AS_CASE(["x/$CC"], + [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], + [#handle absolute path differently from PATH based program lookup + AS_CASE(["x$CC"], + [x/*], + [ + AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) + AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) + ], + [ + AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) + AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) + ] + ) + ]) + ;; + esac fi -else - PTHREAD_CC="$CC" fi -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) +test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" +test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" + +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AC_SUBST([PTHREAD_CC]) +AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$ax_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) +if test "x$ax_pthread_ok" = "xyes"; then + ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no diff --git a/scripts/checks.m4 b/scripts/checks.m4 index 98ef17f85..b9095cee1 100644 --- a/scripts/checks.m4 +++ b/scripts/checks.m4 @@ -21,7 +21,7 @@ AC_DEFUN([TORRENT_CHECK_XFS], [ AC_DEFUN([TORRENT_WITHOUT_XFS], [ AC_ARG_WITH(xfs, - AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]), + AS_HELP_STRING([--without-xfs],[do not check for XFS filesystem support]), [ if test "$withval" = "yes"; then TORRENT_CHECK_XFS @@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [ AC_DEFUN([TORRENT_WITH_XFS], [ AC_ARG_WITH(xfs, - AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]), + AS_HELP_STRING([--with-xfs],[check for XFS filesystem support]), [ if test "$withval" = "yes"; then TORRENT_CHECK_XFS @@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [ AC_DEFUN([TORRENT_WITHOUT_EPOLL], [ AC_ARG_WITH(epoll, - AC_HELP_STRING([--without-epoll], [do not check for epoll support]), + AS_HELP_STRING([--without-epoll],[do not check for epoll support]), [ if test "$withval" = "yes"; then TORRENT_CHECK_EPOLL @@ -134,7 +134,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [ AC_DEFUN([TORRENT_WITH_KQUEUE], [ AC_ARG_WITH(kqueue, - AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]), + AS_HELP_STRING([--with-kqueue],[enable kqueue [[default=no]]]), [ if test "$withval" = "yes"; then TORRENT_CHECK_KQUEUE @@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ AC_ARG_WITH(kqueue, - AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]), + AS_HELP_STRING([--without-kqueue],[do not check for kqueue support]), [ if test "$withval" = "yes"; then TORRENT_CHECK_KQUEUE @@ -158,7 +158,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ AC_ARG_WITH(variable-fdset, - AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]), + AS_HELP_STRING([--without-variable-fdset],[do not use non-portable variable sized fd_set's]), [ if test "$withval" = "yes"; then AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size) @@ -172,14 +172,13 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ AC_MSG_CHECKING(for fallocate) - AC_TRY_LINK([#define _GNU_SOURCE + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE #include - ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0; - ], - [ + ]], [[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0; + ]])],[ AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.) AC_MSG_RESULT(yes) - ], [ + ],[ AC_MSG_RESULT(no) ]) ]) @@ -188,13 +187,12 @@ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [ AC_MSG_CHECKING(for posix_fallocate) - AC_TRY_LINK([#include - ],[ posix_fallocate(0, 0, 0); - ], - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include + ]], [[ posix_fallocate(0, 0, 0); + ]])],[ AC_DEFINE(USE_POSIX_FALLOCATE, 1, posix_fallocate supported.) AC_MSG_RESULT(yes) - ], [ + ],[ AC_MSG_RESULT(no) ]) ]) @@ -202,7 +200,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [ AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [ AC_ARG_WITH(posix-fallocate, - AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]), + AS_HELP_STRING([--with-posix-fallocate],[check for and use posix_fallocate to allocate files]), [ if test "$withval" = "yes"; then TORRENT_CHECK_POSIX_FALLOCATE @@ -215,8 +213,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ AC_MSG_CHECKING(for statvfs) - AC_TRY_LINK( - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #if HAVE_SYS_VFS_H #include #endif @@ -226,12 +223,11 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ #if HAVE_SYS_STATFS_H #include #endif - ],[ + ]], [[ struct statvfs s; fsblkcnt_t c; statvfs("", &s); fstatvfs(0, &s); - ], - [ + ]])],[ AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd) AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename) AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function) @@ -240,8 +236,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [ AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_frsize)], Determine the block size) AC_MSG_RESULT(ok) have_stat_vfs=yes - ], - [ + ],[ AC_MSG_RESULT(no) have_stat_vfs=no ]) @@ -252,8 +247,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ AC_MSG_CHECKING(for statfs) - AC_TRY_LINK( - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #if HAVE_SYS_STATFS_H #include #endif @@ -263,12 +257,11 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ #if HAVE_SYS_MOUNT_H #include #endif - ],[ + ]], [[ struct statfs s; statfs("", &s); fstatfs(0, &s); - ], - [ + ]])],[ AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd) AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename) AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function) @@ -277,8 +270,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [ AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_bsize)], Determine the block size) AC_MSG_RESULT(ok) have_stat_vfs=yes - ], - [ + ],[ AC_MSG_RESULT(no) have_stat_vfs=no ]) @@ -296,7 +288,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [ AC_ARG_WITH(statvfs, - AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]), + AS_HELP_STRING([--without-statvfs],[don't try to use statvfs to find free diskspace]), [ if test "$withval" = "yes"; then TORRENT_CHECK_STATVFS @@ -311,7 +303,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [ AC_DEFUN([TORRENT_WITHOUT_STATFS], [ AC_ARG_WITH(statfs, - AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]), + AS_HELP_STRING([--without-statfs],[don't try to use statfs to find free diskspace]), [ if test "$have_stat_vfs" = "no"; then if test "$withval" = "yes"; then @@ -333,7 +325,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [ AC_ARG_WITH(address-space, - AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]), + AS_HELP_STRING([--with-address-space=MB],[change the default address space size [[default=1024mb]]]), [ if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval]) @@ -354,7 +346,7 @@ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [ AC_DEFUN([TORRENT_WITH_FASTCGI], [ AC_ARG_WITH(fastcgi, - AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]), + AS_HELP_STRING([--with-fastcgi=PATH],[enable FastCGI RPC support (DO NOT USE)]), [ AC_MSG_CHECKING([for FastCGI (DO NOT USE)]) @@ -365,13 +357,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [ CXXFLAGS="$CXXFLAGS" LIBS="$LIBS -lfcgi" - AC_TRY_LINK( - [ #include - ],[ FCGX_Init(); ], - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include + ]], [[ FCGX_Init(); ]])],[ AC_MSG_RESULT(ok) - ], - [ + ],[ AC_MSG_RESULT(not found) AC_MSG_ERROR(Could not compile FastCGI test.) ]) @@ -382,13 +371,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [ CXXFLAGS="$CXXFLAGS -I$withval/include" LIBS="$LIBS -lfcgi -L$withval/lib" - AC_TRY_LINK( - [ #include - ],[ FCGX_Init(); ], - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include + ]], [[ FCGX_Init(); ]])],[ AC_MSG_RESULT(ok) - ], - [ + ],[ AC_MSG_RESULT(not found) AC_MSG_ERROR(Could not compile FastCGI test.) ]) @@ -403,7 +389,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [ AC_MSG_CHECKING(for XMLRPC-C) AC_ARG_WITH(xmlrpc-c, - AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]), + AS_HELP_STRING([--with-xmlrpc-c=PATH],[enable XMLRPC-C support]), [ if test "$withval" = "no"; then AC_MSG_RESULT(no) @@ -419,12 +405,10 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [ CXXFLAGS="$CXXFLAGS `$xmlrpc_cc_prg --cflags server-util`" LIBS="$LIBS `$xmlrpc_cc_prg server-util --libs`" - AC_TRY_LINK( - [ #include - ],[ xmlrpc_registry_new(NULL); ], - [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include + ]], [[ xmlrpc_registry_new(NULL); ]])],[ AC_MSG_RESULT(ok) - ], [ + ],[ AC_MSG_RESULT(failed) AC_MSG_ERROR(Could not compile XMLRPC-C test.) ]) @@ -466,23 +450,23 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [ AC_MSG_CHECKING(for pthread_setname_np type) - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ + ]], [[ pthread_t t; pthread_setname_np(t, "foo"); - ],[ + ]])],[ AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.) AC_MSG_RESULT(generic) ],[ - AC_TRY_LINK([ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include #include - ],[ + ]],[[ pthread_t t; pthread_setname_np("foo"); - ],[ + ]])],[ AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.) AC_MSG_RESULT(darwin) ],[ @@ -490,3 +474,21 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [ ]) ]) ]) + +AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [ + AC_MSG_CHECKING([for pthread_setname_no]) + + AC_ARG_ENABLE(pthread-setname-np, + AS_HELP_STRING([--disable-pthread-setname-np],[disable pthread_setname_np]), + [ + if test "$enableval" = "no"; then + AC_MSG_RESULT(disabled) + else + AC_MSG_RESULT(checking) + TORRENT_CHECK_PTHREAD_SETNAME_NP + fi + ], [ + TORRENT_CHECK_PTHREAD_SETNAME_NP + ] + ) +]) diff --git a/scripts/common.m4 b/scripts/common.m4 index 55e8d66e1..2f54402e0 100644 --- a/scripts/common.m4 +++ b/scripts/common.m4 @@ -1,6 +1,7 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [ AC_ARG_WITH(sysroot, - AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]), + AS_HELP_STRING([--with-sysroot=PATH], + [compile and link with a specific sysroot]), [ AC_MSG_CHECKING(for sysroot) @@ -22,7 +23,8 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [ AC_DEFUN([TORRENT_ENABLE_ARCH], [ AC_ARG_ENABLE(arch, - AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]), + AS_HELP_STRING([--enable-arch=ARCH], + [comma seprated list of architectures to compile for]), [ AC_MSG_CHECKING(for target architectures) @@ -82,7 +84,8 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [ AC_DEFUN([TORRENT_MINCORE], [ AC_ARG_ENABLE(mincore, - AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]), + AS_HELP_STRING([--disable-mincore], + [disable mincore check [[default=enable]]]), [ if test "$enableval" = "yes"; then TORRENT_MINCORE_SIGNEDNESS() @@ -174,7 +177,8 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [ AC_DEFUN([TORRENT_ENABLE_ALIGNED], [ AC_ARG_ENABLE(aligned, - AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]), + AS_HELP_STRING([--enable-aligned], + [enable alignment safe code [[default=check]]]), [ if test "$enableval" = "yes"; then AC_DEFINE(USE_ALIGNED, 1, Require byte alignment) @@ -189,7 +193,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [ AC_MSG_CHECKING([if instrumentation should be included]) AC_ARG_ENABLE(instrumentation, - AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]), + AS_HELP_STRING([--disable-instrumentation], + [disable instrumentation [[default=enabled]]]), [ if test "$enableval" = "yes"; then AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation) @@ -206,7 +211,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [ AC_ARG_ENABLE(interrupt-socket, - AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]), + AS_HELP_STRING([--enable-interrupt-socket], + [enable interrupt socket [[default=no]]]), [ if test "$enableval" = "yes"; then AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill) @@ -214,3 +220,14 @@ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [ ] ) ]) + +AC_DEFUN([TORRENT_DISABLE_IPV6], [ + AC_ARG_ENABLE(ipv6, + AS_HELP_STRING([--enable-ipv6], + [enable ipv6 [[default=no]]]), + [ + if test "$enableval" = "yes"; then + AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff) + fi + ]) +]) diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4 index 9a361bed2..bc1572a39 100644 --- a/scripts/rak_compiler.m4 +++ b/scripts/rak_compiler.m4 @@ -26,7 +26,7 @@ AC_DEFUN([RAK_CHECK_CXXFLAGS], [ AC_DEFUN([RAK_ENABLE_DEBUG], [ AC_ARG_ENABLE(debug, - AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]), + AS_HELP_STRING([--enable-debug],[enable debug information [[default=yes]]]), [ if test "$enableval" = "yes"; then CXXFLAGS="$CXXFLAGS -g -DDEBUG" @@ -41,7 +41,7 @@ AC_DEFUN([RAK_ENABLE_DEBUG], [ AC_DEFUN([RAK_ENABLE_WERROR], [ AC_ARG_ENABLE(werror, - AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flags [[default -Wall only]]]), + AS_HELP_STRING([--enable-werror],[enable the -Werror and -Wall flags [[default -Wall only]]]), [ if test "$enableval" = "yes"; then CXXFLAGS="$CXXFLAGS -Werror -Wall" @@ -54,7 +54,7 @@ AC_DEFUN([RAK_ENABLE_WERROR], [ AC_DEFUN([RAK_ENABLE_EXTRA_DEBUG], [ AC_ARG_ENABLE(extra-debug, - AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]), + AS_HELP_STRING([--enable-extra-debug],[enable extra debugging checks [[default=no]]]), [ if test "$enableval" = "yes"; then AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.) diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4 deleted file mode 100644 index 0db61b838..000000000 --- a/scripts/rak_cxx.m4 +++ /dev/null @@ -1,14 +0,0 @@ -AC_DEFUN([RAK_CHECK_CXX11], [ - AC_ARG_ENABLE([c++0x], - AC_HELP_STRING([--enable-c++0x], [compile with C++0x (unsupported)]), - [ - if test "$enableval" = "yes"; then - AX_CXX_COMPILE_STDCXX_0X - else - AX_CXX_COMPILE_STDCXX_11(noext) - fi - ],[ - AX_CXX_COMPILE_STDCXX_11(noext) - ] - ) -]) diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4 deleted file mode 100644 index c1d9b2f86..000000000 --- a/scripts/rak_execinfo.m4 +++ /dev/null @@ -1,11 +0,0 @@ -AC_DEFUN([RAK_DISABLE_BACKTRACE], [ - AC_ARG_ENABLE(backtrace, - AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]), - [ - if test "$enableval" = "yes"; then - AX_EXECINFO - fi - ],[ - AX_EXECINFO - ]) -]) diff --git a/src/Makefile.am b/src/Makefile.am index 95e6a7aeb..925e7e154 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -76,8 +76,6 @@ libtorrent_other_la_SOURCES = \ net/address_list.cc \ net/address_list.h \ net/data_buffer.h \ - net/local_addr.cc \ - net/local_addr.h \ net/listen.cc \ net/listen.h \ net/protocol_buffer.h \ diff --git a/src/download/download_main.cc b/src/download/download_main.cc index 9a3f9df24..e075038aa 100644 --- a/src/download/download_main.cc +++ b/src/download/download_main.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include diff --git a/src/download/download_main.h b/src/download/download_main.h index da3cf182f..4783e8639 100644 --- a/src/download/download_main.h +++ b/src/download/download_main.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_DOWNLOAD_MAIN_H #define LIBTORRENT_DOWNLOAD_MAIN_H diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc index 59e817814..304bddced 100644 --- a/src/download/download_wrapper.cc +++ b/src/download/download_wrapper.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -62,6 +26,8 @@ #include "download_wrapper.h" +#define LT_LOG_THIS(log_fmt, ...) \ + lt_log_print_info(LOG_TORRENT_INFO, this->info(), "download", log_fmt, __VA_ARGS__); #define LT_LOG_STORAGE_ERRORS(log_fmt, ...) \ lt_log_print_info(LOG_PROTOCOL_STORAGE_ERRORS, this->info(), "storage_errors", log_fmt, __VA_ARGS__); @@ -325,8 +291,8 @@ DownloadWrapper::receive_tick(uint32_t ticks) { void DownloadWrapper::receive_update_priorities() { - if (m_main->chunk_selector()->empty()) - return; + LT_LOG_THIS("update priorities: chunks_selected:%" PRIu32 " wanted_chunks:%" PRIu32, + m_main->chunk_selector()->size(), data()->wanted_chunks()); data()->mutable_high_priority()->clear(); data()->mutable_normal_priority()->clear(); @@ -359,7 +325,6 @@ DownloadWrapper::receive_update_priorities() { } bool was_partial = data()->wanted_chunks() != 0; - data()->update_wanted_chunks(); m_main->chunk_selector()->update_priorities(); diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc deleted file mode 100644 index 244132659..000000000 --- a/src/net/local_addr.cc +++ /dev/null @@ -1,327 +0,0 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2007, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#include "config.h" - -#include -#include -#include -#include - -#ifdef __linux__ -#include -#include -#endif - -#include "torrent/exceptions.h" -#include "socket_fd.h" -#include "local_addr.h" - -namespace torrent { - -#ifdef __linux__ - -namespace { - -// IPv4 priority, from highest to lowest: -// -// 1. Everything else (global address) -// 2. Private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) -// 3. Empty/INADDR_ANY (0.0.0.0) -// 4. Link-local address (169.254.0.0/16) -// 5. Localhost (127.0.0.0/8) -int -get_priority_ipv4(const in_addr& addr) { - if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x7f000000U)) { - return 5; - } - if ((addr.s_addr & htonl(0xffff0000U)) == htonl(0xa9fe0000U)) { - return 4; - } - if (addr.s_addr == htonl(0)) { - return 3; - } - if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x0a000000U) || - (addr.s_addr & htonl(0xfff00000U)) == htonl(0xac100000U) || - (addr.s_addr & htonl(0xffff0000U)) == htonl(0xc0a80000U)) { - return 2; - } - return 1; -} - -// IPv6 priority, from highest to lowest: -// -// 1. Global address (2000::/16 not in 6to4 or Teredo) -// 2. 6to4 (2002::/16) -// 3. Teredo (2001::/32) -// 4. Empty/INADDR_ANY (::) -// 5. Everything else (link-local, ULA, etc.) -int -get_priority_ipv6(const in6_addr& addr) { - const uint32_t *addr32 = reinterpret_cast(addr.s6_addr); - if (addr32[0] == htonl(0) && - addr32[1] == htonl(0) && - addr32[2] == htonl(0) && - addr32[3] == htonl(0)) { - return 4; - } - if (addr32[0] == htonl(0x20010000)) { - return 3; - } - if ((addr32[0] & htonl(0xffff0000)) == htonl(0x20020000)) { - return 2; - } - if ((addr32[0] & htonl(0xe0000000)) == htonl(0x20000000)) { - return 1; - } - return 5; -} - -int -get_priority(const rak::socket_address& addr) { - switch (addr.family()) { - case AF_INET: - return get_priority_ipv4(addr.c_sockaddr_inet()->sin_addr); - case AF_INET6: - return get_priority_ipv6(addr.c_sockaddr_inet6()->sin6_addr); - default: - throw torrent::internal_error("Unknown address family given to compare"); - } -} - -} - -// Linux-specific implementation that understands how to filter away -// understands how to filter away secondary addresses. -bool get_local_address(sa_family_t family, rak::socket_address *address) { - rak::socket_address best_addr; - switch (family) { - case AF_INET: - best_addr.sa_inet()->clear(); - break; - case AF_INET6: - best_addr.sa_inet6()->clear(); - break; - default: - throw torrent::internal_error("Unknown address family given to get_local_address"); - } - - // The bottom bit of the priority is used to hold if the address is - // a secondary address (e.g. with IPv6 privacy extensions) or not; - // secondary addresses have lower priority (higher number). - int best_addr_pri = get_priority(best_addr) * 2; - - // Get all the addresses via Linux' netlink interface. - int fd = ::socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - if (fd == -1) { - return false; - } - - struct sockaddr_nl nladdr; - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - if (::bind(fd, (sockaddr *)&nladdr, sizeof(nladdr))) { - ::close(fd); - return false; - } - - const int seq_no = 1; - struct { - nlmsghdr nh; - rtgenmsg g; - } req; - memset(&req, 0, sizeof(req)); - - req.nh.nlmsg_len = sizeof(req); - req.nh.nlmsg_type = RTM_GETADDR; - req.nh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST; - req.nh.nlmsg_pid = getpid(); - req.nh.nlmsg_seq = seq_no; - req.g.rtgen_family = AF_UNSPEC; - - int ret; - do { - ret = ::sendto(fd, &req, sizeof(req), 0, (sockaddr *)&nladdr, sizeof(nladdr)); - } while (ret == -1 && errno == EINTR); - - if (ret == -1) { - ::close(fd); - return false; - } - - bool done = false; - do { - char buf[4096]; - socklen_t len = sizeof(nladdr); - do { - ret = ::recvfrom(fd, buf, sizeof(buf), 0, (sockaddr *)&nladdr, &len); - } while (ret == -1 && errno == EINTR); - - if (ret < 0) { - ::close(fd); - return false; - } - - for (const nlmsghdr *nlmsg = (const nlmsghdr *)buf; - NLMSG_OK(nlmsg, ret); - nlmsg = NLMSG_NEXT(nlmsg, ret)) { - if (nlmsg->nlmsg_seq != seq_no) - continue; - if (nlmsg->nlmsg_type == NLMSG_DONE) { - done = true; - break; - } - if (nlmsg->nlmsg_type == NLMSG_ERROR) { - ::close(fd); - return false; - } - if (nlmsg->nlmsg_type != RTM_NEWADDR) - continue; - - const ifaddrmsg *ifa = (const ifaddrmsg *)NLMSG_DATA(nlmsg); - - if (ifa->ifa_family != family) - continue; - -#ifdef IFA_F_OPTIMISTIC - if ((ifa->ifa_flags & IFA_F_OPTIMISTIC) != 0) - continue; -#endif -#ifdef IFA_F_DADFAILED - if ((ifa->ifa_flags & IFA_F_DADFAILED) != 0) - continue; -#endif -#ifdef IFA_F_DEPRECATED - if ((ifa->ifa_flags & IFA_F_DEPRECATED) != 0) - continue; -#endif -#ifdef IFA_F_TENTATIVE - if ((ifa->ifa_flags & IFA_F_TENTATIVE) != 0) - continue; -#endif - - // Since there can be point-to-point links on the machine, we need to keep - // track of the addresses we've seen for this interface; if we see both - // IFA_LOCAL and IFA_ADDRESS for an interface, keep only the IFA_LOCAL. - rak::socket_address this_addr; - bool seen_addr = false; - int plen = IFA_PAYLOAD(nlmsg); - for (const rtattr *rta = IFA_RTA(ifa); - RTA_OK(rta, plen); - rta = RTA_NEXT(rta, plen)) { - if (rta->rta_type != IFA_LOCAL && - rta->rta_type != IFA_ADDRESS) { - continue; - } - if (rta->rta_type == IFA_ADDRESS && seen_addr) { - continue; - } - seen_addr = true; - switch (ifa->ifa_family) { - case AF_INET: - this_addr.sa_inet()->clear(); - this_addr.sa_inet()->set_address(*(const in_addr *)RTA_DATA(rta)); - break; - case AF_INET6: - this_addr.sa_inet6()->clear(); - this_addr.sa_inet6()->set_address(*(const in6_addr *)RTA_DATA(rta)); - break; - } - } - if (!seen_addr) - continue; - - int this_addr_pri = get_priority(this_addr) * 2; - if ((ifa->ifa_flags & IFA_F_SECONDARY) == IFA_F_SECONDARY) { - ++this_addr_pri; - } - - if (this_addr_pri < best_addr_pri) { - best_addr = this_addr; - best_addr_pri = this_addr_pri; - } - } - } while (!done); - - ::close(fd); - if (!best_addr.is_address_any()) { - *address = best_addr; - return true; - } else { - return false; - } -} - -#else - -// Generic POSIX variant. -bool -get_local_address(sa_family_t family, rak::socket_address *address) { - SocketFd sock; - if (!sock.open_datagram()) { - return false; - } - - rak::socket_address dummy_dest; - dummy_dest.clear(); - - switch (family) { - case rak::socket_address::af_inet: - dummy_dest.set_address_c_str("4.0.0.0"); - break; - case rak::socket_address::af_inet6: - dummy_dest.set_address_c_str("2001:700::"); - break; - default: - throw internal_error("Unknown address family"); - } - - dummy_dest.set_port(80); - - if (!sock.connect(dummy_dest)) { - sock.close(); - return false; - } - - bool ret = sock.getsockname(address); - sock.close(); - - return ret; -} - -#endif - -} diff --git a/src/net/local_addr.h b/src/net/local_addr.h deleted file mode 100644 index 43bc82066..000000000 --- a/src/net/local_addr.h +++ /dev/null @@ -1,64 +0,0 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2007, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -// A routine to get a local IP address that can be presented to a tracker. -// (Does not use UPnP etc., so will not understand NAT.) -// On a machine with multiple network cards, address selection can be a -// complex process, and in general what's selected is a source/destination -// address pair. However, this routine will give an approximation that will -// be good enough for most purposes and users. - -#ifndef LIBTORRENT_NET_LOCAL_ADDR_H -#define LIBTORRENT_NET_LOCAL_ADDR_H - -#include - -namespace rak { - class socket_address; -} - -namespace torrent { - -// Note: family must currently be rak::af_inet or rak::af_inet6 -// (rak::af_unspec won't do); anything else will throw an exception. -// Returns false if no address of the given family could be found, -// either because there are none, or because something went wrong in -// the process (e.g., no free file descriptors). -bool get_local_address(sa_family_t family, rak::socket_address *address); - -} - -#endif /* LIBTORRENT_NET_LOCAL_ADDR_H */ diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc index 1b877c7a5..d6f48e599 100644 --- a/src/protocol/handshake.cc +++ b/src/protocol/handshake.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am index 30157b953..5de7e8ae5 100644 --- a/src/torrent/Makefile.am +++ b/src/torrent/Makefile.am @@ -46,6 +46,8 @@ libtorrent_torrent_la_SOURCES = \ net/socket_event.cc \ net/socket_event.h \ net/types.h \ + net/utils.cc \ + net/utils.h \ \ peer/choke_status.h \ peer/client_info.cc \ @@ -167,7 +169,8 @@ libtorrent_torrent_net_include_HEADERS = \ net/socket_address.h \ net/socket_address_key.h \ net/socket_event.h \ - net/types.h + net/types.h \ + net/utils.h libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer libtorrent_torrent_peer_include_HEADERS = \ diff --git a/src/torrent/connection_manager.cc b/src/torrent/connection_manager.cc index 972dcbfc3..ea5efc589 100644 --- a/src/torrent/connection_manager.cc +++ b/src/torrent/connection_manager.cc @@ -89,7 +89,11 @@ ConnectionManager::ConnectionManager() : m_listen(new Listen), m_listen_port(0), - m_listen_backlog(SOMAXCONN) { + m_listen_backlog(SOMAXCONN), + + m_block_ipv4(false), + m_block_ipv6(false), + m_prefer_ipv6(false) { m_bindAddress = (new rak::socket_address())->c_sockaddr(); m_localAddress = (new rak::socket_address())->c_sockaddr(); diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h index cf43b0bfd..09ccdd289 100644 --- a/src/torrent/connection_manager.h +++ b/src/torrent/connection_manager.h @@ -167,6 +167,15 @@ class LIBTORRENT_EXPORT ConnectionManager { // For internal usage. Listen* listen() { return m_listen; } + bool is_block_ipv4() const { return m_block_ipv4; } + void set_block_ipv4(bool v) { m_block_ipv4 = v; } + + bool is_block_ipv6() const { return m_block_ipv6; } + void set_block_ipv6(bool v) { m_block_ipv6 = v; } + + bool is_prefer_ipv6() const { return m_prefer_ipv6; } + void set_prefer_ipv6(bool v) { m_prefer_ipv6 = v; } + private: ConnectionManager(const ConnectionManager&); void operator = (const ConnectionManager&); @@ -190,6 +199,10 @@ class LIBTORRENT_EXPORT ConnectionManager { slot_filter_type m_slot_filter; slot_resolver_type m_slot_resolver; slot_throttle_type m_slot_address_throttle; + + bool m_block_ipv4; + bool m_block_ipv6; + bool m_prefer_ipv6; }; } diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h index fc2120477..c701cb2fc 100644 --- a/src/torrent/data/download_data.h +++ b/src/torrent/data/download_data.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H #define LIBTORRENT_DATA_DOWNLOAD_DATA_H diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc index 7c00b686f..edf477952 100644 --- a/src/torrent/download/choke_queue.cc +++ b/src/torrent/download/choke_queue.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -50,6 +14,10 @@ #include "choke_queue.h" +// TODO: Add a different logging category. +#define LT_LOG_THIS(log_fmt, ...) \ + lt_log_print_subsystem(LOG_TORRENT_INFO, "choke_queue", log_fmt, __VA_ARGS__); + namespace torrent { struct choke_manager_less { @@ -193,6 +161,9 @@ choke_queue::rebuild_containers(container_type* queued, container_type* unchoked void choke_queue::balance() { + LT_LOG_THIS("balancing queue: heuristics:%i currently_unchoked:%" PRIu32 " max_unchoked:%" PRIu32, + m_heuristics, m_currently_unchoked, m_maxUnchoked) + // Return if no balancing is needed. Don't return if is_unlimited() // as we might have just changed the value and have interested that // can be unchoked. @@ -216,6 +187,9 @@ choke_queue::balance() { // If we have more unchoked than max global slots allow for, // 'can_unchoke' will be negative. + // + // Throws std::bad_function_call if 'set_slot_can_unchoke' is not + // set. int can_unchoke = m_slotCanUnchoke(); int max_unchoked = std::min(m_maxUnchoked, (uint32_t)(1 << 20)); @@ -240,8 +214,8 @@ choke_queue::balance() { if (result != 0) m_slotUnchoke(result); - lt_log_print(LOG_PEER_DEBUG, "Called balance; adjust:%i can_unchoke:%i queued:%u unchoked:%u result:%i.", - adjust, can_unchoke, (unsigned)queued.size(), (unsigned)unchoked.size(), result); + LT_LOG_THIS("balanced queue: adjust:%i can_unchoke:%i queued:%" PRIu32 " unchoked:%" PRIu32 " result:%i", + adjust, can_unchoke, queued.size(), unchoked.size(), result); } void diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc index 51434c91f..8ca7b02e5 100644 --- a/src/torrent/download/resource_manager.cc +++ b/src/torrent/download/resource_manager.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -51,6 +15,11 @@ #include "choke_queue.h" #include "resource_manager.h" +#define LT_LOG_THIS(log_fmt, ...) \ + lt_log_print_subsystem(LOG_TORRENT_INFO, "resource_manager", log_fmt, __VA_ARGS__); +#define LT_LOG_ITR(log_fmt, ...) \ + lt_log_print_info(LOG_TORRENT_INFO, itr->download()->info(), "resource_manager", log_fmt, __VA_ARGS__); + namespace torrent { const Rate* resource_manager_entry::up_rate() const { return m_download->info()->up_rate(); } @@ -226,6 +195,8 @@ ResourceManager::group_index_of(const std::string& name) { void ResourceManager::set_priority(iterator itr, uint16_t pri) { + LT_LOG_ITR("set priority: %" PRIu16, 0) + itr->set_priority(pri); } @@ -283,7 +254,7 @@ ResourceManager::set_max_download_unchoked(unsigned int m) { // possibly multiple calls of this function. void ResourceManager::receive_upload_unchoke(int num) { - lt_log_print(LOG_PEER_INFO, "Upload unchoked slots adjust; currently:%u adjust:%i", m_currentlyUploadUnchoked, num); + LT_LOG_THIS("adjusting upload unchoked slots; current:%u adjusted:%i", m_currentlyUploadUnchoked, num); if ((int)m_currentlyUploadUnchoked + num < 0) throw internal_error("ResourceManager::receive_upload_unchoke(...) received an invalid value."); @@ -293,7 +264,7 @@ ResourceManager::receive_upload_unchoke(int num) { void ResourceManager::receive_download_unchoke(int num) { - lt_log_print(LOG_PEER_INFO, "Download unchoked slots adjust; currently:%u adjust:%i", m_currentlyDownloadUnchoked, num); + LT_LOG_THIS("adjusting download unchoked slots; current:%u adjusted:%i", m_currentlyDownloadUnchoked, num); if ((int)m_currentlyDownloadUnchoked + num < 0) throw internal_error("ResourceManager::receive_download_unchoke(...) received an invalid value."); @@ -387,12 +358,14 @@ ResourceManager::balance_unchoked(unsigned int weight, unsigned int max_unchoked std::sort(group_first, group_last, std::bind(std::less(), std::bind(&choke_group::up_requested, std::placeholders::_1), std::bind(&choke_group::up_requested, std::placeholders::_2))); - lt_log_print(LOG_PEER_DEBUG, "Upload unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked); + + LT_LOG_THIS("balancing upload unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked); } else { std::sort(group_first, group_last, std::bind(std::less(), std::bind(&choke_group::down_requested, std::placeholders::_1), std::bind(&choke_group::down_requested, std::placeholders::_2))); - lt_log_print(LOG_PEER_DEBUG, "Download unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked); + + LT_LOG_THIS("balancing download unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked); } while (group_first != group_last) { diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc index f834f9fa1..7375ed8e9 100644 --- a/src/torrent/exceptions.cc +++ b/src/torrent/exceptions.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -73,23 +37,30 @@ void internal_error::initialize(const std::string& msg) { m_msg = msg; - std::stringstream output; - #ifdef HAVE_BACKTRACE - void* stackPtrs[20]; + void* stack_ptrs[20]; + int stack_size = ::backtrace(stack_ptrs, 20); + char** stack_symbol_names = ::backtrace_symbols(stack_ptrs, stack_size); - // Print the stack and exit. - int stackSize = ::backtrace(stackPtrs, 20); - char** stackStrings = backtrace_symbols(stackPtrs, stackSize); + if (stack_symbol_names == nullptr) { + m_backtrace = "backtrace_symbols failed"; + return; + } - for (int i = 0; i < stackSize; ++i) - output << stackStrings[i] << std::endl; + std::stringstream output; -#else - output << "Stack dump not enabled." << std::endl; -#endif + for (int i = 0; i < stack_size; ++i) { + if (stack_symbol_names[i] != nullptr && stack_symbol_names[i] > (void*)0x1000) + output << stack_symbol_names[i] << std::endl; + else + output << "stack_symbol: nullptr" << std::endl; + } m_backtrace = output.str(); + +#else + m_backtrace = "stack dump not enabled"; +#endif } } diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc index 07c917791..6d2281819 100644 --- a/src/torrent/net/fd.cc +++ b/src/torrent/net/fd.cc @@ -64,6 +64,9 @@ fd_open(fd_flags flags) { if ((flags & fd_flag_stream)) { domain = SOCK_STREAM; protocol = IPPROTO_TCP; + } else if ((flags & fd_flag_datagram)) { + domain = SOCK_DGRAM; + protocol = IPPROTO_UDP; } else { LT_LOG_FLAG("fd_open missing socket type"); errno = EINVAL; diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h index a70946463..6ab3302d1 100644 --- a/src/torrent/net/fd.h +++ b/src/torrent/net/fd.h @@ -9,11 +9,12 @@ namespace torrent { enum fd_flags : int { fd_flag_stream = 0x1, - fd_flag_nonblock = 0x10, - fd_flag_reuse_address = 0x20, - fd_flag_v4only = 0x40, - fd_flag_v6only = 0x80, - fd_flag_all = 0xff, + fd_flag_datagram = 0x10, + fd_flag_nonblock = 0x20, + fd_flag_reuse_address = 0x40, + fd_flag_v4only = 0x80, + fd_flag_v6only = 0x100, + fd_flag_all = 0x1ff, }; constexpr bool fd_valid_flags(fd_flags flags); @@ -53,7 +54,8 @@ operator |=(fd_flags& lhs, fd_flags rhs) { constexpr bool fd_valid_flags(fd_flags flags) { return - (flags & fd_flag_stream) && + ((flags & fd_flag_stream) || (flags & fd_flag_datagram)) && + !((flags & fd_flag_stream) && (flags & fd_flag_datagram)) && !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) && !(flags & ~(fd_flag_all)); } diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc index c36ba0aeb..078bee258 100644 --- a/src/torrent/net/socket_address.cc +++ b/src/torrent/net/socket_address.cc @@ -135,7 +135,7 @@ sa_unique_ptr sa_make_unspec() { sa_unique_ptr sa(new sockaddr); - std::memset(sa.get(), 0, sizeof(sa)); + std::memset(sa.get(), 0, sizeof(sockaddr)); sa.get()->sa_family = AF_UNSPEC; return sa; diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h index f64aee686..b9586ca16 100644 --- a/src/torrent/net/socket_address.h +++ b/src/torrent/net/socket_address.h @@ -102,8 +102,8 @@ bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_E inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); } -inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } +inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); } inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); } inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); } diff --git a/src/torrent/net/utils.cc b/src/torrent/net/utils.cc new file mode 100755 index 000000000..4cb85924e --- /dev/null +++ b/src/torrent/net/utils.cc @@ -0,0 +1,104 @@ +#import + +#import +#import +#import +#import +#import + +#define LT_LOG_ERROR(log_fmt) \ + lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (errno:%i message:'%s')", \ + errno, std::strerror(errno)); +#define LT_LOG_FD(log_fmt) \ + lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd); +#define LT_LOG_FD_ERROR(log_fmt) \ + lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \ + fd, errno, std::strerror(errno)); +#define LT_LOG_FD_SIN(log_fmt) \ + lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \ + fd, sin_pretty_str(sa.get()).c_str()); +#define LT_LOG_FD_SIN6(log_fmt) \ + lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \ + fd, sin6_pretty_str(sa.get()).c_str()); + +namespace torrent { + +auto detect_local_sin_addr() -> sin_unique_ptr { + int fd = fd_open(fd_flag_v4only | fd_flag_datagram); + if (fd == -1) { + LT_LOG_ERROR("detect_local_sin_addr: open failed"); + return sin_unique_ptr(); + } + + // TODO: Check if unique_ptr works. + std::shared_ptr _fd(nullptr, [fd](...){ fd_close(fd); }); + + auto connectAddress = sin_make(); + connectAddress.get()->sin_addr.s_addr = htonl(0x04000001); + connectAddress.get()->sin_port = 80; + + if (!fd_connect(fd, reinterpret_cast(connectAddress.get())) && errno != EINPROGRESS) { + LT_LOG_FD_ERROR("detect_local_sin_addr: connect failed"); + return sin_unique_ptr(); + } + + // TODO: Make sa function. + socklen_t socklen = sizeof(sockaddr_in); + + auto sa = sin_make(); + + if (::getsockname(fd, reinterpret_cast(sa.get()), &socklen) != 0) { + LT_LOG_FD_ERROR("detect_local_sin_addr: getsockname failed"); + return sin_unique_ptr(); + } + if (socklen != sizeof(sockaddr_in)) { + LT_LOG_FD("detect_local_sin_addr: getsockname failed, invalid socklen"); + return sin_unique_ptr(); + } + + LT_LOG_FD_SIN("detect_local_sin_addr: success"); + + return sa; +} + +auto detect_local_sin6_addr() -> sin6_unique_ptr { + int fd = fd_open(fd_flag_v6only | fd_flag_datagram); + if (fd == -1) { + LT_LOG_ERROR("detect_local_sin6_addr: open failed"); + return sin6_unique_ptr(); + } + + // TODO: Check if unique_ptr works. + std::shared_ptr _fd(nullptr, [fd](...){ fd_close(fd); }); + + auto connectAddress = sin6_make(); + connectAddress.get()->sin6_addr.s6_addr[0] = 0x20; + connectAddress.get()->sin6_addr.s6_addr[1] = 0x01; + connectAddress.get()->sin6_addr.s6_addr[15] = 0x01; + connectAddress.get()->sin6_port = 80; + + if (!fd_connect(fd, reinterpret_cast(connectAddress.get())) && errno != EINPROGRESS) { + LT_LOG_FD_ERROR("detect_local_sin6_addr: connect failed"); + return sin6_unique_ptr(); + } + + // TODO: Make sa function. + socklen_t socklen = sizeof(sockaddr_in6); + + auto sa = sin6_make(); + + if (::getsockname(fd, reinterpret_cast(sa.get()), &socklen) != 0) { + LT_LOG_FD_ERROR("detect_local_sin6_addr: getsockname failed"); + return sin6_unique_ptr(); + } + if (socklen != sizeof(sockaddr_in6)) { + LT_LOG_FD("detect_local_sin6_addr: getsockname failed, invalid socklen"); + return sin6_unique_ptr(); + } + + LT_LOG_FD_SIN6("detect_local_sin6_addr: success"); + + return sa; +} + +} diff --git a/src/torrent/net/utils.h b/src/torrent/net/utils.h new file mode 100755 index 000000000..1d550c51b --- /dev/null +++ b/src/torrent/net/utils.h @@ -0,0 +1,9 @@ +#import +#import + +namespace torrent { + +auto detect_local_sin_addr() -> sin_unique_ptr; +auto detect_local_sin6_addr() -> sin6_unique_ptr; + +} diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc index 080a7f136..6ce630f7d 100644 --- a/src/torrent/peer/peer_list.cc +++ b/src/torrent/peer/peer_list.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include @@ -262,8 +226,11 @@ PeerList::available_list_size() const { return m_available_list->size(); } +// TODO: Rename connecting: PeerInfo* PeerList::connected(const sockaddr* sa, int flags) { + // TODO: Rewrite to use new socket address api after fixing bug. + const rak::socket_address* address = rak::socket_address::cast_from(sa); socket_address_key sock_key = socket_address_key::from_sockaddr(sa); @@ -281,13 +248,7 @@ PeerList::connected(const sockaddr* sa, int flags) { // We should also remove any PeerInfo objects already for this // address. if ((filter_value & PeerInfo::flag_unwanted)) { - char ipv4_str[INET_ADDRSTRLEN]; - uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr); - - inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN); - - lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str); - + LT_LOG_EVENTS("connecting peer rejected, flagged as unwanted: " LT_LOG_SA_FMT, address->address_str().c_str(), address->port()); return NULL; } @@ -313,12 +274,23 @@ PeerList::connected(const sockaddr* sa, int flags) { // // This also ensure we can connect to peers running on the same // host as the tracker. - if (flags & connect_keep_handshakes && - range.first->second->is_handshake() && - rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port()) - m_available_list->buffer()->push_back(*address); + // if (flags & connect_keep_handshakes && + // range.first->second->is_handshake() && + // rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port()) + // m_available_list->buffer()->push_back(*address); - return NULL; + LT_LOG_EVENTS("connecting peer rejected, already connected (buggy, fixme): " LT_LOG_SA_FMT, address->address_str().c_str(), address->port()); + + // TODO: Verify this works properly, possibly add a check/flag + // that allows the handshake manager to notify peer list if the + // incoming connection was a duplicate peer hash. + + //return NULL; + + peerInfo = new PeerInfo(sa); + peerInfo->set_flags(filter_value & PeerInfo::mask_ip_table); + + base_type::insert(range.second, value_type(sock_key, peerInfo)); } if (flags & connect_filter_recent && diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h index 4c2f707da..a9d31a547 100644 --- a/src/torrent/peer/peer_list.h +++ b/src/torrent/peer/peer_list.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_PEER_LIST_H #define LIBTORRENT_PEER_LIST_H diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc index fb70d2471..67de43870 100644 --- a/src/torrent/torrent.cc +++ b/src/torrent/torrent.cc @@ -203,6 +203,7 @@ download_priority(Download d) { return itr->priority(); } +// TODO: Remove this. void download_set_priority(Download d, uint32_t pri) { ResourceManager::iterator itr = manager->resource_manager()->find(d.ptr()->main()); diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h index c2b887b15..64605d4a7 100644 --- a/src/torrent/utils/extents.h +++ b/src/torrent/utils/extents.h @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #ifndef LIBTORRENT_UTILS_EXTENTS_H #define LIBTORRENT_UTILS_EXTENTS_H diff --git a/src/torrent/utils/signal_bitfield.cc b/src/torrent/utils/signal_bitfield.cc index 82f81e7c6..dfc3d1feb 100644 --- a/src/torrent/utils/signal_bitfield.cc +++ b/src/torrent/utils/signal_bitfield.cc @@ -1,39 +1,3 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - #include "config.h" #include "torrent/exceptions.h" diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc index 99d6355df..ec0619f37 100644 --- a/src/torrent/utils/thread_base.cc +++ b/src/torrent/utils/thread_base.cc @@ -41,10 +41,16 @@ thread_base::~thread_base() { void thread_base::start_thread() { - if (m_poll == NULL) + if (this == nullptr) + throw internal_error("Called thread_base::start_thread on a nullptr."); + + if (m_poll == nullptr) throw internal_error("No poll object for thread defined."); - if (!is_initialized() || pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this)) + if (!is_initialized()) + throw internal_error("Called thread_base::start_thread on an uninitialized object."); + + if (pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this)) throw internal_error("Failed to create thread."); } @@ -82,6 +88,12 @@ thread_base::should_handle_sigusr1() { void* thread_base::event_loop(thread_base* thread) { + if (thread == nullptr) + throw internal_error("thread_base::event_loop called with a null pointer thread"); + + if (!thread->is_initialized()) + throw internal_error("thread_base::event_loop call on an uninitialized object"); + __sync_lock_test_and_set(&thread->m_state, STATE_ACTIVE); #if defined(HAS_PTHREAD_SETNAME_NP_DARWIN) diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc index 6f119f5b5..8cfa0e9ac 100644 --- a/src/tracker/tracker_http.cc +++ b/src/tracker/tracker_http.cc @@ -1,63 +1,28 @@ -// libTorrent - BitTorrent library -// Copyright (C) 2005-2011, Jari Sundell -// -// 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// In addition, as a special exception, the copyright holders give -// permission to link the code of portions of this program with the -// OpenSSL library under certain conditions as described in each -// individual source file, and distribute linked combinations -// including the two. -// -// You must obey the GNU General Public License in all respects for -// all of the code used other than OpenSSL. If you modify file(s) -// with this exception, you may extend this exception to your version -// of the file(s), but you are not obligated to do so. If you do not -// wish to do so, delete this exception statement from your version. -// If you delete this exception statement from all source files in the -// program, then also delete it here. -// -// Contact: Jari Sundell -// -// Skomakerveien 33 -// 3185 Skoppum, NORWAY - -#include "config.h" +#import "config.h" #define __STDC_FORMAT_MACROS -#include -#include -#include -#include +#import +#import +#import +#import -#include "net/address_list.h" -#include "net/local_addr.h" -#include "torrent/connection_manager.h" -#include "torrent/download_info.h" -#include "torrent/exceptions.h" -#include "torrent/http.h" -#include "torrent/object_stream.h" -#include "torrent/tracker_list.h" -#include "torrent/utils/log.h" -#include "torrent/utils/option_strings.h" +#import "net/address_list.h" +#import "torrent/connection_manager.h" +#import "torrent/download_info.h" +#import "torrent/exceptions.h" +#import "torrent/http.h" +#import "torrent/net/utils.h" +#import "torrent/net/socket_address.h" +#import "torrent/object_stream.h" +#import "torrent/tracker_list.h" +#import "torrent/utils/log.h" +#import "torrent/utils/option_strings.h" -#include "tracker_http.h" +#import "tracker_http.h" -#include "globals.h" -#include "manager.h" +#import "globals.h" +#import "manager.h" #define LT_LOG_TRACKER(log_level, log_fmt, ...) \ lt_log_print_info(LOG_TRACKER_##log_level, m_parent->info(), "tracker", "[%u] " log_fmt, group(), __VA_ARGS__); @@ -142,19 +107,16 @@ TrackerHttp::send_state(int state) { const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address()); - if (!localAddress->is_address_any()) - s << "&ip=" << localAddress->address_str(); - - if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) { - rak::socket_address local_v6; - if (get_local_address(rak::socket_address::af_inet6, &local_v6)) - s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str()); - } + if (localAddress->is_address_any()) { + if (manager->connection_manager()->is_prefer_ipv6()) { + auto ipv6_address = detect_local_sin6_addr(); - if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) { - rak::socket_address local_v4; - if (get_local_address(rak::socket_address::af_inet, &local_v4)) - s << "&ipv4=" << local_v4.address_str(); + if (ipv6_address != nullptr) { + s << "&ip=" << sin6_addr_str(ipv6_address.get()); + } + } + } else { + s << "&ip=" << localAddress->address_str(); } if (info->is_compact()) diff --git a/test/helpers/network.h b/test/helpers/network.h index 6cf2f8702..eb1884265 100644 --- a/test/helpers/network.h +++ b/test/helpers/network.h @@ -112,6 +112,7 @@ wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), sa != nullptr); + return sa; } @@ -121,6 +122,7 @@ wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, con CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(), sa != nullptr); + return torrent::c_sa_unique_ptr(sa.release()); } diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc index 5e56f0f37..0a00ccd4c 100644 --- a/test/torrent/net/test_fd.cc +++ b/test/torrent/net/test_fd.cc @@ -9,13 +9,22 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net"); void test_fd::test_valid_flags() { CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram)); + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_datagram)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock)); CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address)); CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only)); CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_nonblock)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_reuse_address)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only)); + CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v6only)); + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only)); CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); + CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only | torrent::fd_flag_v6only)); CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags())); CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all))); diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc index 8a1b0c8ab..a27b38bc0 100644 --- a/test/torrent/net/test_socket_address.cc +++ b/test/torrent/net/test_socket_address.cc @@ -83,7 +83,7 @@ test_socket_address::test_make() { CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6); CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0); CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0); - CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0})); + CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, (in6_addr{0}))); CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0); torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix("");