Silence -Wunused-const-variable warnings in Gnulib code.
[gnulib.git] / m4 / linkat.m4
blob7725dff3a8d2dfe6c8989abd737562c7d4edb08a
1 # linkat.m4
2 # serial 17
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
22     HAVE_LINKAT=0
23     case "$gl_cv_onwards_func_linkat" in
24       future*) REPLACE_LINKAT=1 ;;
25     esac
26   else
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(
36                         [[#include <fcntl.h>
37                           #include <unistd.h>
38                         ]],
39                         [[return linkat (AT_FDCWD, "conftest.l1", AT_FDCWD,
40                                          "conftest.l2", 0);
41                         ]])],
42          [gl_cv_func_linkat_nofollow=yes],
43          [gl_cv_func_linkat_nofollow=no],
44          [case "$host_os" in
45            darwin*) gl_cv_func_linkat_nofollow="guessing no" ;;
46            *)       gl_cv_func_linkat_nofollow="guessing yes" ;;
47           esac])
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 ;;
54     esac
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
59        AC_RUN_IFELSE(
60          [AC_LANG_PROGRAM(
61             [[#include <unistd.h>
62               #include <fcntl.h>
63               #include <errno.h>
64               #include <stdio.h>
65             ]GL_MDA_DEFINES],
66             [[int result;
67               int fd;
68               /* Create a regular file.  */
69               fd = open ("conftest.a", O_CREAT | O_EXCL | O_WRONLY, 0600);
70               if (fd < 0)
71                 return 1;
72               if (write (fd, "hello", 5) < 5)
73                 return 2;
74               if (close (fd) < 0)
75                 return 3;
76               /* Test whether hard links are supported on the current
77                  device.  */
78               if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.b",
79                           AT_SYMLINK_FOLLOW) < 0)
80                 return 0;
81               result = 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)
85                 result |= 4;
86               if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.d/",
87                           AT_SYMLINK_FOLLOW) == 0)
88                 result |= 8;
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)
93                 {
94                   if (linkat (AT_FDCWD, "conftest.a", AT_FDCWD, "conftest.s/",
95                       AT_SYMLINK_FOLLOW) == 0)
96                     result |= 16;
97                 }
99               return result;
100             ]])],
101          [gl_cv_func_linkat_slash=yes],
102          [gl_cv_func_linkat_slash=no],
103          [
104           case "$host_os" in
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";;
113           esac
114          ])
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 ;;
119     esac
121     case "$gl_cv_func_linkat_nofollow" in
122       *yes) linkat_nofollow=yes ;;
123       *) linkat_nofollow=no ;;
124     esac
126     if test "$linkat_nofollow" != yes \
127        || test $gl_linkat_slash_bug = 1; then
128       REPLACE_LINKAT=1
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])
133     fi
134   fi