diff options
author | Bruno Haible <bruno@clisp.org> | 2010-12-28 12:18:54 +0100 |
---|---|---|
committer | Bruno Haible <bruno@clisp.org> | 2010-12-28 12:18:54 +0100 |
commit | 37da693c0a2d4d84369d1910d258370ce65552ce (patch) | |
tree | 49375929b29526c2896f02f7ece8e242f58e3d3a /m4/link-follow.m4 | |
parent | db6d3e6221185974c47f3123caaa962d26901838 (diff) | |
download | gnulib-37da693c0a2d4d84369d1910d258370ce65552ce.tar.gz |
linkat: Make implementation robust against system behaviour variations.
* m4/link-follow.m4 (gl_FUNC_LINK_FOLLOWS_SYMLINK): Define
LINK_FOLLOWS_SYMLINKS to -1 if it needs a runtime test in the Solaris
way, and to -2 if it needs a generic runtime test.
* lib/linkat.c (solaris_optimized_link_immediate,
solaris_optimized_link_follow): New functions.
* tests/test-linkat.c (EXPECT_LINK_HARDLINKS_SYMLINKS): New macro.
(check_same_link): Use it.
Diffstat (limited to 'm4/link-follow.m4')
-rw-r--r-- | m4/link-follow.m4 | 60 |
1 files changed, 39 insertions, 21 deletions
diff --git a/m4/link-follow.m4 b/m4/link-follow.m4 index 256b2a99d8..95264db261 100644 --- a/m4/link-follow.m4 +++ b/m4/link-follow.m4 @@ -1,4 +1,4 @@ -# serial 15 +# serial 16 dnl Run a program to determine whether link(2) follows symlinks. dnl Set LINK_FOLLOWS_SYMLINKS accordingly. @@ -12,7 +12,8 @@ dnl LINK_FOLLOWS_SYMLINKS is 0, link matches linkat(,0), and dnl linkat(,AT_SYMLINK_FOLLOW) requires a readlink. If it is 1, dnl link matches linkat(,AT_SYMLINK_FOLLOW), and there is no way dnl to do linkat(,0) on symlinks (on all other file types, -dnl link() is sufficient). If it is -1, use a runtime test. +dnl link() is sufficient). If it is -1, use a Solaris specific +dnl runtime test. If it is -2, use a generic runtime test. AC_DEFUN([gl_FUNC_LINK_FOLLOWS_SYMLINK], [dnl AC_CHECK_FUNCS_ONCE([readlink]) @@ -22,12 +23,27 @@ AC_DEFUN([gl_FUNC_LINK_FOLLOWS_SYMLINK], dnl linkat variants. So, we set LINK_FOLLOWS_SYMLINKS to 0. gl_link_follows_symlinks=0 # assume GNU behavior if test $ac_cv_func_readlink = yes; then - AC_CACHE_CHECK([whether link(2) dereferences a symlink], - gl_cv_func_link_follows_symlink, - [ - # Create a regular file. - echo > conftest.file - AC_RUN_IFELSE([AC_LANG_SOURCE([[ + dnl Solaris has an __xpg4 variable in libc, and it determines the + dnl behaviour of link(): It dereferences a symlink if and only if + dnl __xpg4 != 0. + AC_CACHE_CHECK([for __xpg4], [gl_cv_have___xpg4], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[extern int __xpg4;]], + [[return __xpg4;]])], + [gl_cv_have___xpg4=yes], + [gl_cv_have___xpg4=no]) + ]) + if test $gl_cv_have___xpg4 = yes; then + gl_link_follows_symlinks=-1 + else + AC_CACHE_CHECK([whether link(2) dereferences a symlink], + [gl_cv_func_link_follows_symlink], + [ + # Create a regular file. + echo > conftest.file + AC_RUN_IFELSE( + [AC_LANG_SOURCE([[ # include <sys/types.h> # include <sys/stat.h> # include <unistd.h> @@ -62,20 +78,22 @@ AC_DEFUN([gl_FUNC_LINK_FOLLOWS_SYMLINK], the link call followed the symlink. */ return SAME_INODE (sb_hard, sb_file) ? 1 : 0; } - ]])], - [gl_cv_func_link_follows_symlink=no], dnl GNU behavior - [gl_cv_func_link_follows_symlink=yes], dnl Followed link/compile failed - [gl_cv_func_link_follows_symlink=unknown] dnl We're cross compiling. - ) - rm -f conftest.file conftest.sym conftest.hard - ]) - case $gl_cv_func_link_follows_symlink in - yes) gl_link_follows_symlinks=1 ;; - no) ;; # already defaulted to 0 - *) gl_link_follows_symlinks=-1 ;; - esac + ]])], + [gl_cv_func_link_follows_symlink=no], dnl GNU behavior + [gl_cv_func_link_follows_symlink=yes], dnl Followed link/compile failed + [gl_cv_func_link_follows_symlink=unknown] dnl We're cross compiling. + ) + rm -f conftest.file conftest.sym conftest.hard + ]) + case $gl_cv_func_link_follows_symlink in + yes) gl_link_follows_symlinks=1 ;; + no) ;; # already defaulted to 0 + *) gl_link_follows_symlinks=-2 ;; + esac + fi fi AC_DEFINE_UNQUOTED([LINK_FOLLOWS_SYMLINKS], [$gl_link_follows_symlinks], [Define to 1 if `link(2)' dereferences symbolic links, 0 if it - creates hard links to symlinks, and -1 if unknown.]) + creates hard links to symlinks, -1 if it depends on the variable __xpg4, + and -2 if unknown.]) ]) |