summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinhard Tartler <siretart@tauware.de>2018-03-14 08:17:06 -0400
committerReinhard Tartler <siretart@tauware.de>2018-03-14 08:17:06 -0400
commitc84f07d33496f2c0c6553c70991581c2bdc75e52 (patch)
tree28b9f1ac7afb1f062035ca4c6021325e4e0050c3
parent5c8edd41853a7a08f2eab8365f0f48a12035a6b6 (diff)
parent16a11e868c6280a64ec3f26f7537161dfa748d61 (diff)
Merge branch 'master' of https://github.com/boxbackup/boxbackup into upstream
-rw-r--r--appveyor.yml8
-rw-r--r--configure.ac1
-rw-r--r--infrastructure/cmake/CMakeLists.txt114
-rw-r--r--infrastructure/m4/ax_check_syscall_lseek.m4111
-rw-r--r--infrastructure/m4/boxbackup_tests.m438
-rwxr-xr-xinfrastructure/makebuildenv.pl.in2
-rw-r--r--lib/intercept/intercept.cpp18
-rw-r--r--test/raidfile/testraidfile.cpp9
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;