From c08932c6e5e1609835219e9f42efe46bb6624a7d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 24 Feb 2018 08:47:40 +0000 Subject: Fix raidfile tests on 32-bit Linux A recent fix for Solaris (commit 81e9aa6545f7f19124c9f5e88982b867d8732965) broke support for 32-bit Linux (which wasn't spotted because we didn't have any 32-bit builders). Try a different approach: detect whether the lseek syscall takes a 64-bit integer offset, and use that if possible. CMake: reimplement autoconf tests for 64-bit lseek (cherry picked from commit 138ea5d174f146f14d91a16bf5d1ce8e479d2024) --- infrastructure/m4/ax_check_syscall_lseek.m4 | 111 +++++++++++++++++++--------- 1 file changed, 78 insertions(+), 33 deletions(-) (limited to 'infrastructure/m4/ax_check_syscall_lseek.m4') 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 @@ -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 +]) -- cgit v1.2.3