2 # See if we need to provide linkat replacement.
4 dnl Copyright (C) 2009-2020 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 Mac OS X 10.13 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],
101 # Guess yes on Linux systems.
102 linux-* | linux) gl_cv_func_linkat_slash="guessing yes";;
103 # Guess yes on glibc systems.
104 *-gnu* | gnu*) gl_cv_func_linkat_slash="guessing yes";;
105 # If we don't know, obey --enable-cross-guesses.
106 *) gl_cv_func_linkat_slash="$gl_cross_guess_normal";;
109 rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s])
110 case "$gl_cv_func_linkat_slash" in
111 *yes) gl_linkat_slash_bug=0 ;;
112 *) gl_linkat_slash_bug=1 ;;
115 case "$gl_cv_func_linkat_nofollow" in
116 *yes) linkat_nofollow=yes ;;
117 *) linkat_nofollow=no ;;
120 if test "$linkat_nofollow" != yes \
121 || test $gl_linkat_slash_bug = 1; then
123 AC_DEFINE_UNQUOTED([LINKAT_TRAILING_SLASH_BUG], [$gl_linkat_slash_bug],
124 [Define to 1 if linkat fails to recognize a trailing slash.])
125 AC_DEFINE_UNQUOTED([LINKAT_SYMLINK_NOTSUP], [$LINKAT_SYMLINK_NOTSUP],
126 [Define to 1 if linkat can create hardlinks to symlinks])