1# serial 14 2# See if we need to provide linkat replacement. 3 4dnl Copyright (C) 2009-2021 Free Software Foundation, Inc. 5dnl This file is free software; the Free Software Foundation 6dnl gives unlimited permission to copy and/or distribute it, 7dnl with or without modifications, as long as this notice is preserved. 8 9# Written by Eric Blake. 10 11AC_DEFUN([gl_FUNC_LINKAT], 12[ 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 20 HAVE_LINKAT=0 21 else 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( 31 [[#include <fcntl.h> 32 #include <unistd.h> 33 ]], 34 [[return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD, 35 "conftest.l2", 0); 36 ]])], 37 [gl_cv_func_linkat_nofollow=yes], 38 [gl_cv_func_linkat_nofollow=no], 39 [case "$host_os" in 40 darwin*) gl_cv_func_linkat_nofollow="guessing no" ;; 41 *) gl_cv_func_linkat_nofollow="guessing yes" ;; 42 esac]) 43 44 rm -rf conftest.l1 conftest.l2]) 45 46 case $gl_cv_func_linkat_nofollow in 47 *no) LINKAT_SYMLINK_NOTSUP=1 ;; 48 *yes) LINKAT_SYMLINK_NOTSUP=0 ;; 49 esac 50 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 54 AC_RUN_IFELSE( 55 [AC_LANG_PROGRAM( 56 [[#include <unistd.h> 57 #include <fcntl.h> 58 #include <errno.h> 59 #include <stdio.h> 60 ]GL_MDA_DEFINES], 61 [[int result; 62 int fd; 63 /* Create a regular file. */ 64 fd = open ("conftest.a", O_CREAT | O_EXCL | O_WRONLY, 0600); 65 if (fd < 0) 66 return 1; 67 if (write (fd, "hello", 5) < 5) 68 return 2; 69 if (close (fd) < 0) 70 return 3; 71 /* Test whether hard links are supported on the current 72 device. */ 73 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.b", 74 AT_SYMLINK_FOLLOW) < 0) 75 return 0; 76 result = 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) 80 result |= 4; 81 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/", 82 AT_SYMLINK_FOLLOW) == 0) 83 result |= 8; 84 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) 88 { 89 if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/", 90 AT_SYMLINK_FOLLOW) == 0) 91 result |= 16; 92 } 93 94 return result; 95 ]])], 96 [gl_cv_func_linkat_slash=yes], 97 [gl_cv_func_linkat_slash=no], 98 [ 99 case "$host_os" in 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";; 106 esac 107 ]) 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 ;; 112 esac 113 114 case "$gl_cv_func_linkat_nofollow" in 115 *yes) linkat_nofollow=yes ;; 116 *) linkat_nofollow=no ;; 117 esac 118 119 if test "$linkat_nofollow" != yes \ 120 || test $gl_linkat_slash_bug = 1; then 121 REPLACE_LINKAT=1 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]) 126 fi 127 fi 128]) 129