diff options
author | Reinhard Tartler <siretart@tauware.de> | 2018-03-14 08:17:45 -0400 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2018-03-14 08:17:45 -0400 |
commit | e7adc056af9656629af0f18fef143f231e1b4bf7 (patch) | |
tree | 4773c3be211d2705129be843d61f7f4609d7b790 | |
parent | d93873567421b74fa3aa4d6297fc998886f47907 (diff) | |
parent | c84f07d33496f2c0c6553c70991581c2bdc75e52 (diff) |
Merge branch 'upstream'
-rw-r--r-- | appveyor.yml | 8 | ||||
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | infrastructure/cmake/CMakeLists.txt | 114 | ||||
-rw-r--r-- | infrastructure/m4/ax_check_syscall_lseek.m4 | 111 | ||||
-rw-r--r-- | infrastructure/m4/boxbackup_tests.m4 | 38 | ||||
-rwxr-xr-x | infrastructure/makebuildenv.pl.in | 2 | ||||
-rw-r--r-- | lib/intercept/intercept.cpp | 18 | ||||
-rw-r--r-- | test/raidfile/testraidfile.cpp | 9 |
8 files changed, 239 insertions, 62 deletions
diff --git a/appveyor.yml b/appveyor.yml index d75eff77..602ef4e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -39,6 +39,12 @@ init: # scripts that run after cloning repository (before the build step, not after!) install: + # work around sourceforge brokenness by temporarily download some files ourselves: + - ps: New-Item -ItemType Directory -Force -Path $env:TEMP\chocolatey\nsis.portable\3.02.0.20160720 + - ps: invoke-webrequest -uri https://10gbps-io.dl.sourceforge.net/project/nsis/NSIS%203%20Pre-release/3.0rc2/nsis-3.0rc2.zip -outfile $env:TEMP\chocolatey\nsis.portable\3.02.0.20160720\download + - ps: New-Item -ItemType Directory -Force -Path ..\cmake\Download\boost + - ps: invoke-webrequest -uri http://download.openpkg.org/components/cache/boost/boost_1_62_0.tar.bz2 -outfile ..\cmake\Download\boost\boost_1_62_0.tar.bz2 + # test_bbackupd needs 7zip (or cmake -E tar) to extract tar archives on Windows: - cinst -y --limit-output 7zip.commandline nsis.portable - dir "c:\Program Files" @@ -107,3 +113,5 @@ deploy: - master - windows_binary_packages +cache: + - '%TEMP%\chocolatey' diff --git a/configure.ac b/configure.ac index f9f481d5..58a04406 100644 --- a/configure.ac +++ b/configure.ac @@ -139,6 +139,7 @@ Large files: $box_cv_have_large_file_support Berkeley DB: $ax_path_bdb_ok Readline: $have_libreadline Extended attributes: $ac_cv_header_sys_xattr_h +Debugger: ${with_debugger:-neither GDB nor LLDB detected!} EOC cat > config.env <<EOC diff --git a/infrastructure/cmake/CMakeLists.txt b/infrastructure/cmake/CMakeLists.txt index 65f59eb8..e6f46148 100644 --- a/infrastructure/cmake/CMakeLists.txt +++ b/infrastructure/cmake/CMakeLists.txt @@ -363,6 +363,7 @@ target_compile_definitions(lib_common PUBLIC $<$<CONFIG:Release>:BOX_RELEASE_BUI include(CheckCXXCompilerFlag) include(CheckCXXSourceCompiles) +include(CheckCXXSourceRuns) include(CheckFunctionExists) include(CheckIncludeFiles) include(CheckLibraryExists) @@ -477,7 +478,7 @@ move_file_if_exists( "${boxconfig_cmake_h_dir}/BoxConfig.cmake.h.bak") foreach(m4_filename boxbackup_tests.m4 ax_check_mount_point.m4 ax_func_syscall.m4) - file(STRINGS "${base_dir}/infrastructure/m4/${m4_filename}" m4_functions REGEX "^ *AC[_A-Z]+\\(.*\\)$") + file(STRINGS "${base_dir}/infrastructure/m4/${m4_filename}" m4_functions REGEX "^ *(AC|AX|BOX)_[A-Z_]+\\(.*\\)$") foreach(m4_function ${m4_functions}) if(DEBUG) message(STATUS "Processing m4_function: ${m4_function}") @@ -559,6 +560,22 @@ foreach(m4_filename boxbackup_tests.m4 ax_check_mount_point.m4 ax_func_syscall.m } ]=] "HAVE_${platform_var_name}") file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_${platform_var_name}\n") + elseif(m4_function MATCHES "^ *BOX_CHECK_CXX_FLAG\\((-[A-Za-z_,=-]+)\\)") + if(DEBUG) + message(STATUS "Processing BOX_CHECK_CXX_FLAG: ${CMAKE_MATCH_1}") + endif() + + if(NOT CMAKE_MATCH_1 STREQUAL "-Wall") + set(flag "${CMAKE_MATCH_1}") + string(TOLOWER "have_flag_${flag}" have_flag_var_name) + string(REGEX REPLACE "[^a-z_]" "_" have_flag_var_name ${have_flag_var_name}) + string(REGEX REPLACE "__+" "_" have_flag_var_name ${have_flag_var_name}) + + CHECK_CXX_COMPILER_FLAG(${flag} ${have_flag_var_name}) + if(${have_flag_var_name}) + add_definitions("${flag}") + endif() + endif() endif() endforeach() @@ -610,6 +627,7 @@ CHECK_CXX_SOURCE_COMPILES([=[ } ]=] "HAVE_STRUCT_STATFS_F_MNTONNAME") file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_STRUCT_STATFS_F_MNTONNAME\n") + CHECK_CXX_SOURCE_COMPILES([=[ #include "BoxConfig.cmake.h" #ifdef HAVE_SYS_PARAM_H @@ -623,6 +641,7 @@ CHECK_CXX_SOURCE_COMPILES([=[ } ]=] "HAVE_STRUCT_STATVFS_F_MNTONNAME") file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_STRUCT_STATVFS_F_MNTONNAME\n") + if(HAVE_STRUCT_STATFS_F_MNTONNAME OR HAVE_STRUCT_STATVFS_F_MNTONNAME OR HAVE_STRUCT_MNTENT_MNT_DIR OR @@ -649,6 +668,34 @@ file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_RANDOM_DEVICE\n") # Build an intermediate version of BoxConfig.cmake.h for use in the following tests: configure_file("${boxconfig_h_file}" "${boxconfig_cmake_h_dir}/BoxConfig.cmake.h") +# Emulate ax_func_syscall.m4: Autoconf's AC_CHECK_FUNC (which we emulate above, +# using check_function_exists) defines the function when testing for its +# presence, so HAVE___SYSCALL will be true even if __syscall has no definition +# in the system libraries, and this is precisely the case that we want to test +# for, so now we test whether a test program compiles with no explicit +# definition (only the system headers) and if that fails, we set +# HAVE___SYSCALL_NEED_DEFN to 1. + +CHECK_CXX_SOURCE_COMPILES( + [=[ + #include "BoxConfig.cmake.h" + + #ifdef HAVE_SYS_SYSCALL_H + # include <sys/syscall.h> + #endif + + int main() + { + __syscall(SYS_exit, 0); + return 0; + } + ]=] HAVE___SYSCALL_NO_DEFN) +set(HAVE___SYSCALL_NEED_DEFN !HAVE___SYSCALL_NO_DEFN) +file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE___SYSCALL_NEED_DEFN\n") + +# Build an intermediate version of BoxConfig.cmake.h for use in the following tests: +configure_file("${boxconfig_h_file}" "${boxconfig_cmake_h_dir}/BoxConfig.cmake.h") + foreach(struct_member_name "struct ucred.uid" "struct ucred.cr_uid") string(REGEX MATCH "(.*)\\.(.*)" dummy_var ${struct_member_name}) set(struct_name "${CMAKE_MATCH_1}") @@ -684,6 +731,71 @@ foreach(struct_member_name "struct ucred.uid" "struct ucred.cr_uid") ]=] "HAVE_${platform_var_name}") file(APPEND "${boxconfig_h_file}" "#cmakedefine HAVE_${platform_var_name}\n") endforeach() + +function(AX_TRY_RUN_FD code var) + CHECK_CXX_SOURCE_RUNS([=[ + #include "BoxConfig.cmake.h" + #include <fcntl.h> + #include <unistd.h> + #include <sys/syscall.h> + #include <sys/types.h> + + #ifdef HAVE___SYSCALL_NEED_DEFN + extern "C" off_t __syscall(quad_t number, ...); + #endif + + #ifdef HAVE___SYSCALL // always use it if we have it + # undef syscall + # define syscall __syscall + #endif + + int main() + { + int fd = creat("lseektest", 0600); + int res = 1; + if(fd>=0) + { + ${code} + close(fd); + } + unlink("lseektest"); + return res; + } + ]=] ${var}) + file(APPEND "${boxconfig_h_file}" "#cmakedefine ${var}\n") +endfunction() + +AX_TRY_RUN_FD( + [=[ + // This test tries first to seek to position 0, with NO "dummy + // argument". If lseek does actually require a dummy argument, + // then it will eat SEEK_SET for the offset and try to use 99 + // as whence, which is invalid, so res will be 0, the program + // will return 0 and we will define HAVE_LSEEK_DUMMY_PARAM + // (whew! that took 1 hour to figure out) The "dummy argument" + // probably means that it takes a 64-bit offset. + res = (syscall(SYS_lseek, fd, (int32_t)10, SEEK_SET, 99) == 10) ? 2 : 0; + ]=] HAVE_LSEEK_DUMMY_PARAM) + +AX_TRY_RUN_FD( + [=[ + // Try to seek to a position that requires a 64-bit + // representation, and check the return value, which is the + // current position. + if(syscall(SYS_lseek, fd, (int64_t)5, SEEK_SET) != 5) + { + res = 2; + } + else if(syscall(SYS_lseek, fd, (int64_t)10, SEEK_CUR) != 15) + { + res = 3; + } + else + { + res = 0; + } + ]=] HAVE_LSEEK_64_BIT) + set(CMAKE_REQUIRED_INCLUDES "") # Build the final version of BoxConfig.cmake.h, as a temporary file. diff --git a/infrastructure/m4/ax_check_syscall_lseek.m4 b/infrastructure/m4/ax_check_syscall_lseek.m4 index 9fd04c81..4fec851a 100644 --- a/infrastructure/m4/ax_check_syscall_lseek.m4 +++ b/infrastructure/m4/ax_check_syscall_lseek.m4 @@ -11,12 +11,14 @@ dnl @category C dnl @author Martin Ebourne dnl @version 2005/07/03 dnl @license AllPermissive +dnl -AC_DEFUN([AX_CHECK_SYSCALL_LSEEK], [ - AC_REQUIRE([AX_FUNC_SYSCALL])dnl - if test "x$ac_cv_header_sys_syscall_h" = "xyes"; then - AC_CACHE_CHECK([[whether syscall lseek requires dummy parameter]], [box_cv_have_lseek_dummy_param], - [AC_TRY_RUN( +AC_DEFUN( + [AX_TRY_RUN_FD], + [ + AC_REQUIRE([AX_FUNC_SYSCALL])dnl + if test "x$ac_cv_header_sys_syscall_h" = "xyes"; then + AC_TRY_RUN( [ $ac_includes_default #include <fcntl.h> @@ -30,40 +32,83 @@ AC_DEFUN([AX_CHECK_SYSCALL_LSEEK], [ #endif int main() { - int fh = creat("lseektest", 0600); - int res = 0; - if(fh>=0) + int fd = creat("lseektest", 0600); + int res = 1; + if(fd>=0) { + $1 + close(fd); + } + unlink("lseektest"); + return abs(res); + } + ], + [$2], + [$3], + [$3 # assume not for cross-compiling] + ) + fi + ])dnl + +AC_DEFUN([AX_CHECK_SYSCALL_LSEEK_DUMMY_PARAM], [ + AC_CACHE_CHECK( + [[whether syscall lseek requires dummy parameter]], + [box_cv_have_lseek_dummy_param], + [AX_TRY_RUN_FD( + [ // This test tries first to seek to position 0, with NO // "dummy argument". If lseek does actually require a dummy // argument, then it will eat SEEK_SET for the offset and // try to use 99 as whence, which is invalid, so res will be - // -1, the program will return zero and - // have_lseek_dummy_param=yes + // 1, the program will return 1 and we will define + // HAVE_LSEEK_DUMMY_PARAM // (whew! that took 1 hour to figure out) // The "dummy argument" probably means that it takes a 64-bit - // offset, so this was probably a bug anyway, and now that - // we cast the offset to off_t, it should never be needed - // (if my reasoning is correct). - res = syscall(SYS_lseek, fh, (off_t)0, SEEK_SET, 99); - close(fh); - } - unlink("lseektest"); - return res!=-1; - } - ], - [box_cv_have_lseek_dummy_param=yes], - [box_cv_have_lseek_dummy_param=no], - [box_cv_have_lseek_dummy_param=no # assume not for cross-compiling] - )]) - if test "x$box_cv_have_lseek_dummy_param" = "xyes"; then - AC_DEFINE([HAVE_LSEEK_DUMMY_PARAM], 1, - [Define to 1 if syscall lseek requires a dummy middle parameter]) - fi + // offset. + res = (syscall(SYS_lseek, fd, (int32_t)10, SEEK_SET, 99) == 10) ? 0 : 1; + ], + dnl if the test program succeeds (res == 0): + [box_cv_have_lseek_dummy_param=no], + dnl if the test program fails (res != 0): + [box_cv_have_lseek_dummy_param=yes], + )] + ) + if test "x$box_cv_have_lseek_dummy_param" != "xno"; then + AC_DEFINE([HAVE_LSEEK_DUMMY_PARAM], 1, + [Define to 1 if syscall lseek requires a dummy middle parameter]) fi - if test "x$box_cv_have_lseek_dummy_param" = "xno" - then - m4_ifvaln([$1],[$1],[:])dnl - m4_ifvaln([$2],[else $2])dnl +]) + +# Please note: this does not appear to work! Do not rely on it without further testing: +AC_DEFUN([AX_CHECK_SYSCALL_LSEEK_64_BIT], [ + AC_CACHE_CHECK( + [[whether syscall lseek takes a 64-bit offset parameter]], + [box_cv_have_lseek_64_bit], + [AX_TRY_RUN_FD( + [ + // Try to seek to a position that requires a 64-bit representation, and check the return + // value, which is the current position. + if(syscall(SYS_lseek, fd, (int64_t)5, SEEK_SET) != 5) + { + res = 2; + } + else if(syscall(SYS_lseek, fd, (int64_t)10, SEEK_CUR) != 15) + { + res = 3; + } + else + { + res = 0; + } + ], + dnl if the test program succeeds (res == 0): + [box_cv_have_lseek_64_bit=yes], + dnl if the test program fails (res != 0): + [box_cv_have_lseek_64_bit=no] + )] + ) + if test "x$box_cv_have_lseek_64_bit" != "xno"; then + AC_DEFINE([HAVE_LSEEK_64_BIT], 1, + [Define to 1 if syscall lseek takes a 64-bit offset]) fi - ])dnl +]) diff --git a/infrastructure/m4/boxbackup_tests.m4 b/infrastructure/m4/boxbackup_tests.m4 index 59467e66..86aa560a 100644 --- a/infrastructure/m4/boxbackup_tests.m4 +++ b/infrastructure/m4/boxbackup_tests.m4 @@ -10,27 +10,28 @@ solaris*) ;; esac +# If the compiler supports it, force errors on unknown flags, so that detection works: +AX_CHECK_COMPILE_FLAG(-Werror=unknown-warning-option, + [cxxflags_force_error="-Werror=unknown-warning-option"]) + +# Reduce compiler flag checking to a one-liner, needed for CMake to parse them +AC_DEFUN([BOX_CHECK_CXX_FLAG], + AX_CHECK_COMPILE_FLAG($1, + [cxxflags_strict="$cxxflags_strict $1"],, + $cxxflags_force_error) +) + # Enable some compiler flags if the compiler supports them. This gives better warnings # and detects some problems early. -AX_CHECK_COMPILE_FLAG(-Wall, [cxxflags_strict="$cxxflags_strict -Wall"]) -# -Wundef would be a good idea, but Boost is full of undefined variable use, so we need -# to disable it for now so that we can concentrate on real errors: -dnl AX_CHECK_COMPILE_FLAG(-Wundef, [cxxflags_strict="$cxxflags_strict -Wundef"]) -AX_CHECK_COMPILE_FLAG(-Werror=return-type, - [cxxflags_strict="$cxxflags_strict -Werror=return-type"]) -AX_CHECK_COMPILE_FLAG(-Werror=delete-non-virtual-dtor, - [cxxflags_strict="$cxxflags_strict -Werror=delete-non-virtual-dtor"]) -AX_CHECK_COMPILE_FLAG(-Werror=undefined-bool-conversion, - [cxxflags_strict="$cxxflags_strict -Werror=undefined-bool-conversion"]) -# We should really enable -Werror=sometimes-uninitialized, but QDBM violates it: -dnl AX_CHECK_COMPILE_FLAG(-Werror=sometimes-uninitialized, -dnl [cxxflags_strict="$cxxflags_strict -Werror=sometimes-uninitialized"]) +BOX_CHECK_CXX_FLAG(-Wall) +BOX_CHECK_CXX_FLAG(-Werror=return-type) +BOX_CHECK_CXX_FLAG(-Werror=delete-non-virtual-dtor) +BOX_CHECK_CXX_FLAG(-Werror=undefined-bool-conversion) # This error is detected by MSVC, but not usually by GCC/Clang: # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58114 -AX_CHECK_COMPILE_FLAG(-Werror=delete-incomplete, - [cxxflags_strict="$cxxflags_strict -Werror=delete-incomplete"]) -AX_CHECK_COMPILE_FLAG(-Wno-deprecated-declarations, - [cxxflags_strict="$cxxflags_strict -Wno-deprecated-declarations"]) +BOX_CHECK_CXX_FLAG(-Werror=delete-incomplete) +BOX_CHECK_CXX_FLAG(-Wno-deprecated-declarations) + AC_SUBST([CXXFLAGS_STRICT], [$cxxflags_strict]) if test "x$GXX" = "xyes"; then @@ -310,7 +311,8 @@ if test "$netbsd_hack" != "netbsd"; then fi AX_FUNC_SYSCALL -AX_CHECK_SYSCALL_LSEEK +AX_CHECK_SYSCALL_LSEEK_DUMMY_PARAM +AX_CHECK_SYSCALL_LSEEK_64_BIT AC_CHECK_FUNCS([listxattr llistxattr getxattr lgetxattr setxattr lsetxattr]) AC_CHECK_DECLS([XATTR_NOFOLLOW],,, [[#include <sys/xattr.h>]]) diff --git a/infrastructure/makebuildenv.pl.in b/infrastructure/makebuildenv.pl.in index d5ac9f2f..48958ba1 100755 --- a/infrastructure/makebuildenv.pl.in +++ b/infrastructure/makebuildenv.pl.in @@ -628,7 +628,7 @@ __E { writetestfile("$mod/t-gdb", "echo 'No debugger was detected by configure script'\n". - "exit 2"); + "exit 2", $mod); } } diff --git a/lib/intercept/intercept.cpp b/lib/intercept/intercept.cpp index 72bd8d4e..f46e6982 100644 --- a/lib/intercept/intercept.cpp +++ b/lib/intercept/intercept.cpp @@ -390,23 +390,23 @@ lseek(int fildes, off_t offset, int whence) { // random magic for lseek syscall, see /usr/src/lib/libc/sys/lseek.c CHECK_FOR_FAKE_ERROR_COND(fildes, 0, SYS_lseek, -1); + #ifdef PLATFORM_NO_SYSCALL int r = TEST_lseek(fildes, offset, whence); +#elif defined HAVE_LSEEK_DUMMY_PARAM + off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, (int32_t)offset, + whence); +#elif defined HAVE_LSEEK_64_BIT + off_t r = syscall(SYS_lseek, fildes, (int64_t)offset, whence); #else - #ifdef HAVE_LSEEK_DUMMY_PARAM - off_t r = syscall(SYS_lseek, fildes, 0 /* extra 0 required here! */, offset, whence); - #elif defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 32 - // Don't bother trying to call SYS__llseek on 32 bit since it is - // fiddly and not needed for the tests - off_t r = syscall(SYS_lseek, fildes, (uint32_t)offset, whence); - #else - off_t r = syscall(SYS_lseek, fildes, offset, whence); - #endif + off_t r = syscall(SYS_lseek, fildes, (int32_t)offset, whence); #endif + if(r != -1) { intercept_filepos = r; } + return r; } diff --git a/test/raidfile/testraidfile.cpp b/test/raidfile/testraidfile.cpp index d771f23d..2314d376 100644 --- a/test/raidfile/testraidfile.cpp +++ b/test/raidfile/testraidfile.cpp @@ -653,12 +653,21 @@ int test(int argc, const char *argv[]) IOStream &write1stream = write1; // use the stream interface where possible write1.Open(); write1stream.Write(data, sizeof(data)); + TEST_EQUAL(sizeof(data), write1stream.GetPosition()); write1stream.Seek(1024, IOStream::SeekType_Absolute); + TEST_EQUAL(1024, write1stream.GetPosition()); write1stream.Write(data2, sizeof(data2)); + TEST_EQUAL(1024 + sizeof(data2), write1stream.GetPosition()); write1stream.Seek(1024, IOStream::SeekType_Relative); + TEST_EQUAL(2048 + sizeof(data2), write1stream.GetPosition()); write1stream.Write(data2, sizeof(data2)); + TEST_EQUAL(2048 + sizeof(data2) * 2, write1stream.GetPosition()); write1stream.Seek(0, IOStream::SeekType_End); + TEST_EQUAL(sizeof(data), write1stream.GetPosition()); write1stream.Write(data, sizeof(data)); + TEST_EQUAL(sizeof(data) * 2, write1stream.GetPosition()); + write1stream.Seek(-1, IOStream::SeekType_Relative); + TEST_EQUAL(sizeof(data) * 2 - 1, write1stream.GetPosition()); // Before it's deleted, check to see the contents are as expected int f; |