2 # See if we need to provide linkat replacement.
4 dnl Copyright (C) 2009-2015 Free Software Foundation, Inc.
5 dnl This file is free software; the Free Software Foundation
6 dnl gives unlimited permission to copy and/or distribute it,
7 dnl with or without modifications, as long as this notice is preserved.
9 # Written by Eric Blake.
11 AC_DEFUN([gl_FUNC_LINKAT],
13 AC_REQUIRE([gl_FUNC_OPENAT])
14 AC_REQUIRE([gl_FUNC_LINK_FOLLOWS_SYMLINK])
15 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
16 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
17 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
18 AC_CHECK_FUNCS_ONCE([linkat symlink])
19 AC_CHECK_HEADERS_ONCE([sys/param.h])
20 if test $ac_cv_func_linkat = no; then
23 dnl OS X Yosemite has linkat() but it's not sufficient
24 dnl to our needs since it doesn't support creating
25 dnl hardlinks to symlinks. Therefore check for that
26 dnl capability before considering using the system version.
27 AC_CACHE_CHECK([whether linkat() can link symlinks],
28 [gl_cv_func_linkat_nofollow],
29 [rm -rf conftest.l1 conftest.l2
30 ln -s target conftest.l1
31 AC_RUN_IFELSE([AC_LANG_PROGRAM(
35 [return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD,
38 [gl_cv_func_linkat_nofollow=yes],
39 [gl_cv_func_linkat_nofollow=no],
41 darwin*) gl_cv_func_linkat_nofollow="guessing no" ;;
42 *) gl_cv_func_linkat_nofollow="guessing yes" ;;
45 rm -rf conftest.l1 conftest.l2])
47 case $gl_cv_func_linkat_nofollow in
48 *no) LINKAT_SYMLINK_NOTSUP=1 ;;
49 *yes) LINKAT_SYMLINK_NOTSUP=0 ;;
52 AC_CACHE_CHECK([whether linkat handles trailing slash correctly],
53 [gl_cv_func_linkat_slash],
54 [rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s
64 /* Create a regular file. */
65 fd = open ("conftest.a", O_CREAT | O_EXCL | O_WRONLY, 0600);
68 if (write (fd, "hello", 5) < 5)
72 /* Test whether hard links are supported on the current
74 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.b",
75 AT_SYMLINK_FOLLOW) < 0)
78 /* Test whether a trailing "/" is treated like "/.". */
79 if (linkat (AT_FDCWD, "conftest.a/", AT_FDCWD, "conftest.c",
80 AT_SYMLINK_FOLLOW) == 0)
82 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/",
83 AT_SYMLINK_FOLLOW) == 0)
86 /* On OS X 10.10 a trailing "/" will cause the second path to be
87 dereferenced, and thus will succeed on a dangling symlink. */
88 if (symlink ("conftest.e", "conftest.s") == 0)
90 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/",
91 AT_SYMLINK_FOLLOW) == 0)
97 [gl_cv_func_linkat_slash=yes],
98 [gl_cv_func_linkat_slash=no],
99 [# Guess yes on glibc systems, no otherwise.
101 *-gnu*) gl_cv_func_linkat_slash="guessing yes";;
102 *) gl_cv_func_linkat_slash="guessing no";;
105 rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s])
106 case "$gl_cv_func_linkat_slash" in
107 *yes) gl_linkat_slash_bug=0 ;;
108 *) gl_linkat_slash_bug=1 ;;
111 case "$gl_cv_func_linkat_nofollow" in
112 *yes) linkat_nofollow=yes ;;
113 *) linkat_nofollow=no ;;
116 if test "$linkat_nofollow" != yes \
117 || test $gl_linkat_slash_bug = 1; then
119 AC_DEFINE_UNQUOTED([LINKAT_TRAILING_SLASH_BUG], [$gl_linkat_slash_bug],
120 [Define to 1 if linkat fails to recognize a trailing slash.])
121 AC_DEFINE_UNQUOTED([LINKAT_SYMLINK_NOTSUP], [$LINKAT_SYMLINK_NOTSUP],
122 [Define to 1 if linkat can create hardlinks to symlinks])