X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=m4%2Flinkat.m4;h=9ed082db971fdfe61030fb9bca3ce2cdbaef2b55;hb=d30babc23b4f25be970ada2e63a50220a3672281;hp=2da0e30cb1d4154244a3dd748a7023ee862c23fb;hpb=4aa85f09e755fc827cd5ab6225f20c83cd42245d;p=debian%2Ftar diff --git a/m4/linkat.m4 b/m4/linkat.m4 index 2da0e30c..9ed082db 100644 --- a/m4/linkat.m4 +++ b/m4/linkat.m4 @@ -1,7 +1,7 @@ -# serial 6 +# serial 7 # See if we need to provide linkat replacement. -dnl Copyright (C) 2009-2014 Free Software Foundation, Inc. +dnl Copyright (C) 2009-2015 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, dnl with or without modifications, as long as this notice is preserved. @@ -20,26 +20,38 @@ AC_DEFUN([gl_FUNC_LINKAT], if test $ac_cv_func_linkat = no; then HAVE_LINKAT=0 else - AC_CACHE_CHECK([whether linkat(,AT_SYMLINK_FOLLOW) works], - [gl_cv_func_linkat_follow], - [rm -rf conftest.f1 conftest.f2 - touch conftest.f1 - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ -#include -#include -#ifdef __linux__ -/* Linux added linkat in 2.6.16, but did not add AT_SYMLINK_FOLLOW - until 2.6.18. Always replace linkat to support older kernels. */ -choke me -#endif -]], [return linkat (AT_FDCWD, "conftest.f1", AT_FDCWD, "conftest.f2", - AT_SYMLINK_FOLLOW);])], - [gl_cv_func_linkat_follow=yes], - [gl_cv_func_linkat_follow="need runtime check"]) - rm -rf conftest.f1 conftest.f2]) + dnl OS X Yosemite has linkat() but it's not sufficient + dnl to our needs since it doesn't support creating + dnl hardlinks to symlinks. Therefore check for that + dnl capability before considering using the system version. + AC_CACHE_CHECK([whether linkat() can link symlinks], + [gl_cv_func_linkat_nofollow], + [rm -rf conftest.l1 conftest.l2 + ln -s target conftest.l1 + AC_RUN_IFELSE([AC_LANG_PROGRAM( + [[#include + #include + ]], + [return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD, + "conftest.l2", 0); + ])], + [gl_cv_func_linkat_nofollow=yes], + [gl_cv_func_linkat_nofollow=no], + [case "$host_os" in + darwin*) gl_cv_func_linkat_nofollow="guessing no" ;; + *) gl_cv_func_linkat_nofollow="guessing yes" ;; + esac]) + + rm -rf conftest.l1 conftest.l2]) + + case $gl_cv_func_linkat_nofollow in + *no) LINKAT_SYMLINK_NOTSUP=1 ;; + *yes) LINKAT_SYMLINK_NOTSUP=0 ;; + esac + AC_CACHE_CHECK([whether linkat handles trailing slash correctly], [gl_cv_func_linkat_slash], - [rm -rf conftest.a conftest.b conftest.c conftest.d + [rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s AC_RUN_IFELSE( [AC_LANG_PROGRAM( [[#include @@ -70,6 +82,16 @@ choke me if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/", AT_SYMLINK_FOLLOW) == 0) result |= 8; + + /* On OS X 10.10 a trailing "/" will cause the second path to be + dereferenced, and thus will succeed on a dangling symlink. */ + if (symlink ("conftest.e", "conftest.s") == 0) + { + if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/", + AT_SYMLINK_FOLLOW) == 0) + result |= 16; + } + return result; ]])], [gl_cv_func_linkat_slash=yes], @@ -80,16 +102,24 @@ choke me *) gl_cv_func_linkat_slash="guessing no";; esac ]) - rm -rf conftest.a conftest.b conftest.c conftest.d]) + rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s]) case "$gl_cv_func_linkat_slash" in *yes) gl_linkat_slash_bug=0 ;; *) gl_linkat_slash_bug=1 ;; esac - if test "$gl_cv_func_linkat_follow" != yes \ + + case "$gl_cv_func_linkat_nofollow" in + *yes) linkat_nofollow=yes ;; + *) linkat_nofollow=no ;; + esac + + if test "$linkat_nofollow" != yes \ || test $gl_linkat_slash_bug = 1; then REPLACE_LINKAT=1 AC_DEFINE_UNQUOTED([LINKAT_TRAILING_SLASH_BUG], [$gl_linkat_slash_bug], [Define to 1 if linkat fails to recognize a trailing slash.]) + AC_DEFINE_UNQUOTED([LINKAT_SYMLINK_NOTSUP], [$LINKAT_SYMLINK_NOTSUP], + [Define to 1 if linkat can create hardlinks to symlinks]) fi fi ])