2 # See if we need to provide linkat replacement.
4 dnl Copyright (C) 2009-2021 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 if test $ac_cv_func_linkat = no; then
22 dnl OS X Yosemite has linkat() but it's not sufficient
23 dnl to our needs since it doesn't support creating
24 dnl hardlinks to symlinks. Therefore check for that
25 dnl capability before considering using the system version.
26 AC_CACHE_CHECK([whether linkat() can link symlinks],
27 [gl_cv_func_linkat_nofollow],
28 [rm -rf conftest.l1 conftest.l2
29 ln -s target conftest.l1
30 AC_RUN_IFELSE([AC_LANG_PROGRAM(
34 [[return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD,
37 [gl_cv_func_linkat_nofollow=yes],
38 [gl_cv_func_linkat_nofollow=no],
40 darwin*) gl_cv_func_linkat_nofollow="guessing no" ;;
41 *) gl_cv_func_linkat_nofollow="guessing yes" ;;
44 rm -rf conftest.l1 conftest.l2])
46 case $gl_cv_func_linkat_nofollow in
47 *no) LINKAT_SYMLINK_NOTSUP=1 ;;
48 *yes) LINKAT_SYMLINK_NOTSUP=0 ;;
51 AC_CACHE_CHECK([whether linkat handles trailing slash correctly],
52 [gl_cv_func_linkat_slash],
53 [rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s
63 /* Create a regular file. */
64 fd = open ("conftest.a", O_CREAT | O_EXCL | O_WRONLY, 0600);
67 if (write (fd, "hello", 5) < 5)
71 /* Test whether hard links are supported on the current
73 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.b",
74 AT_SYMLINK_FOLLOW) < 0)
77 /* Test whether a trailing "/" is treated like "/.". */
78 if (linkat (AT_FDCWD, "conftest.a/", AT_FDCWD, "conftest.c",
79 AT_SYMLINK_FOLLOW) == 0)
81 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/",
82 AT_SYMLINK_FOLLOW) == 0)
85 /* On Mac OS X 10.13 a trailing "/" will cause the second path to be
86 dereferenced, and thus will succeed on a dangling symlink. */
87 if (symlink ("conftest.e", "conftest.s") == 0)
89 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/",
90 AT_SYMLINK_FOLLOW) == 0)
96 [gl_cv_func_linkat_slash=yes],
97 [gl_cv_func_linkat_slash=no],
100 # Guess yes on Linux systems.
101 linux-* | linux) gl_cv_func_linkat_slash="guessing yes";;
102 # Guess yes on glibc systems.
103 *-gnu* | gnu*) gl_cv_func_linkat_slash="guessing yes";;
104 # If we don't know, obey --enable-cross-guesses.
105 *) gl_cv_func_linkat_slash="$gl_cross_guess_normal";;
108 rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s])
109 case "$gl_cv_func_linkat_slash" in
110 *yes) gl_linkat_slash_bug=0 ;;
111 *) gl_linkat_slash_bug=1 ;;
114 case "$gl_cv_func_linkat_nofollow" in
115 *yes) linkat_nofollow=yes ;;
116 *) linkat_nofollow=no ;;
119 if test "$linkat_nofollow" != yes \
120 || test $gl_linkat_slash_bug = 1; then
122 AC_DEFINE_UNQUOTED([LINKAT_TRAILING_SLASH_BUG], [$gl_linkat_slash_bug],
123 [Define to 1 if linkat fails to recognize a trailing slash.])
124 AC_DEFINE_UNQUOTED([LINKAT_SYMLINK_NOTSUP], [$LINKAT_SYMLINK_NOTSUP],
125 [Define to 1 if linkat can create hardlinks to symlinks])