3 dnl Copyright (C) 2009-2024 Free Software Foundation, Inc.
4 dnl This file is free software; the Free Software Foundation
5 dnl gives unlimited permission to copy and/or distribute it,
6 dnl with or without modifications, as long as this notice is preserved.
8 # See if we need to provide linkat replacement.
10 # Written by Eric Blake.
12 AC_DEFUN([gl_FUNC_LINKAT],
14 AC_REQUIRE([gl_FUNC_OPENAT])
15 AC_REQUIRE([gl_FUNC_LINK_FOLLOWS_SYMLINK])
16 AC_REQUIRE([gl_UNISTD_H_DEFAULTS])
17 AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
18 AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
19 AC_CHECK_FUNCS_ONCE([symlink])
20 gl_CHECK_FUNCS_ANDROID([linkat], [[#include <unistd.h>]])
21 if test $ac_cv_func_linkat = no; then
23 case "$gl_cv_onwards_func_linkat" in
24 future*) REPLACE_LINKAT=1 ;;
27 dnl OS X Yosemite has linkat() but it's not sufficient
28 dnl to our needs since it doesn't support creating
29 dnl hardlinks to symlinks. Therefore check for that
30 dnl capability before considering using the system version.
31 AC_CACHE_CHECK([whether linkat() can link symlinks],
32 [gl_cv_func_linkat_nofollow],
33 [rm -rf conftest.l1 conftest.l2
34 ln -s target conftest.l1
35 AC_RUN_IFELSE([AC_LANG_PROGRAM(
39 [[return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD,
42 [gl_cv_func_linkat_nofollow=yes],
43 [gl_cv_func_linkat_nofollow=no],
45 darwin*) gl_cv_func_linkat_nofollow="guessing no" ;;
46 *) gl_cv_func_linkat_nofollow="guessing yes" ;;
49 rm -rf conftest.l1 conftest.l2])
51 case $gl_cv_func_linkat_nofollow in
52 *no) LINKAT_SYMLINK_NOTSUP=1 ;;
53 *yes) LINKAT_SYMLINK_NOTSUP=0 ;;
56 AC_CACHE_CHECK([whether linkat handles trailing slash correctly],
57 [gl_cv_func_linkat_slash],
58 [rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s
68 /* Create a regular file. */
69 fd = open ("conftest.a", O_CREAT | O_EXCL | O_WRONLY, 0600);
72 if (write (fd, "hello", 5) < 5)
76 /* Test whether hard links are supported on the current
78 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.b",
79 AT_SYMLINK_FOLLOW) < 0)
82 /* Test whether a trailing "/" is treated like "/.". */
83 if (linkat (AT_FDCWD, "conftest.a/", AT_FDCWD, "conftest.c",
84 AT_SYMLINK_FOLLOW) == 0)
86 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/",
87 AT_SYMLINK_FOLLOW) == 0)
90 /* On Mac OS X 10.13 a trailing "/" will cause the second path to be
91 dereferenced, and thus will succeed on a dangling symlink. */
92 if (symlink ("conftest.e", "conftest.s") == 0)
94 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/",
95 AT_SYMLINK_FOLLOW) == 0)
101 [gl_cv_func_linkat_slash=yes],
102 [gl_cv_func_linkat_slash=no],
105 # Guess yes on Linux systems.
106 linux-* | linux) gl_cv_func_linkat_slash="guessing yes";;
107 # Guess yes on systems that emulate the Linux system calls.
108 midipix*) gl_cv_func_linkat_slash="guessing yes";;
109 # Guess yes on glibc systems.
110 *-gnu* | gnu*) gl_cv_func_linkat_slash="guessing yes";;
111 # If we don't know, obey --enable-cross-guesses.
112 *) gl_cv_func_linkat_slash="$gl_cross_guess_normal";;
115 rm -rf conftest.a conftest.b conftest.c conftest.d conftest.e conftest.s])
116 case "$gl_cv_func_linkat_slash" in
117 *yes) gl_linkat_slash_bug=0 ;;
118 *) gl_linkat_slash_bug=1 ;;
121 case "$gl_cv_func_linkat_nofollow" in
122 *yes) linkat_nofollow=yes ;;
123 *) linkat_nofollow=no ;;
126 if test "$linkat_nofollow" != yes \
127 || test $gl_linkat_slash_bug = 1; then
129 AC_DEFINE_UNQUOTED([LINKAT_TRAILING_SLASH_BUG], [$gl_linkat_slash_bug],
130 [Define to 1 if linkat fails to recognize a trailing slash.])
131 AC_DEFINE_UNQUOTED([LINKAT_SYMLINK_NOTSUP], [$LINKAT_SYMLINK_NOTSUP],
132 [Define to 1 if linkat can create hardlinks to symlinks])