1# canonicalize.m4 serial 37
2
3dnl Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc.
4
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# Provides canonicalize_file_name and canonicalize_filename_mode, but does
10# not provide or fix realpath.
11AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE],
12[
13  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
14  AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
15  AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat])
16  AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
17  AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
18  if test $ac_cv_func_canonicalize_file_name = no; then
19    HAVE_CANONICALIZE_FILE_NAME=0
20  else
21    case "$gl_cv_func_realpath_works" in
22      *yes) ;;
23      *)    REPLACE_CANONICALIZE_FILE_NAME=1 ;;
24    esac
25  fi
26])
27
28# Provides canonicalize_file_name and realpath.
29AC_DEFUN([gl_CANONICALIZE_LGPL],
30[
31  AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
32  AC_REQUIRE([gl_CANONICALIZE_LGPL_SEPARATE])
33  if test $ac_cv_func_canonicalize_file_name = no; then
34    HAVE_CANONICALIZE_FILE_NAME=0
35    if test $ac_cv_func_realpath = no; then
36      HAVE_REALPATH=0
37    else
38      case "$gl_cv_func_realpath_works" in
39        *yes) ;;
40        *)    REPLACE_REALPATH=1 ;;
41      esac
42    fi
43  else
44    case "$gl_cv_func_realpath_works" in
45      *yes)
46        ;;
47      *)
48        REPLACE_CANONICALIZE_FILE_NAME=1
49        REPLACE_REALPATH=1
50        ;;
51    esac
52  fi
53])
54
55# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation
56# (no REPLACE_CANONICALIZE_FILE_NAME, no REPLACE_REALPATH, no AC_LIBOBJ).
57AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
58[
59  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
60  AC_REQUIRE([gl_FUNC_LSTAT_FOLLOWS_SLASHED_SYMLINK])
61  AC_CHECK_FUNCS_ONCE([canonicalize_file_name faccessat])
62
63  dnl On native Windows, we use _getcwd(), regardless whether getcwd() is
64  dnl available through the linker option '-loldnames'.
65  AC_REQUIRE([AC_CANONICAL_HOST])
66  case "$host_os" in
67    mingw*) ;;
68    *)      AC_CHECK_FUNCS([getcwd]) ;;
69  esac
70
71  AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
72  AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
73  AC_CHECK_HEADERS_ONCE([sys/param.h])
74])
75
76# Check whether realpath works.  Assume that if a platform has both
77# realpath and canonicalize_file_name, but the former is broken, then
78# so is the latter.
79AC_DEFUN([gl_FUNC_REALPATH_WORKS],
80[
81  AC_CHECK_FUNCS_ONCE([realpath lstat])
82  AC_REQUIRE([AC_CANONICAL_HOST]) dnl for cross-compiles
83  AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [
84    rm -rf conftest.a conftest.d
85    touch conftest.a
86    # Assume that if we have lstat, we can also check symlinks.
87    if test $ac_cv_func_lstat = yes; then
88      ln -s conftest.a conftest.l
89    fi
90    mkdir conftest.d
91    AC_RUN_IFELSE([
92      AC_LANG_PROGRAM([[
93        ]GL_NOCRASH[
94        #include <errno.h>
95        #include <stdlib.h>
96        #include <string.h>
97      ]], [[
98        int result = 0;
99        /* This test fails on Solaris 10.  */
100        {
101          char *name = realpath ("conftest.a", NULL);
102          if (!(name && *name == '/'))
103            result |= 1;
104          free (name);
105        }
106        /* This test fails on older versions of Cygwin.  */
107        {
108          char *name = realpath ("conftest.b/../conftest.a", NULL);
109          if (name != NULL)
110            result |= 2;
111          free (name);
112        }
113        /* This test fails on Cygwin 2.9.  */
114        #if HAVE_LSTAT
115        {
116          char *name = realpath ("conftest.l/../conftest.a", NULL);
117          if (name != NULL || errno != ENOTDIR)
118            result |= 4;
119          free (name);
120        }
121        #endif
122        /* This test fails on Mac OS X 10.13, OpenBSD 6.0.  */
123        {
124          char *name = realpath ("conftest.a/", NULL);
125          if (name != NULL)
126            result |= 8;
127          free (name);
128        }
129        /* This test fails on AIX 7, Solaris 10.  */
130        {
131          char *name1 = realpath (".", NULL);
132          char *name2 = realpath ("conftest.d//./..", NULL);
133          if (! name1 || ! name2 || strcmp (name1, name2))
134            result |= 16;
135          free (name1);
136          free (name2);
137        }
138        #ifdef __linux__
139        /* On Linux, // is the same as /. See also double-slash-root.m4.
140           realpath() should respect this.
141           This test fails on musl libc 1.2.2.  */
142        {
143          char *name = realpath ("//", NULL);
144          if (! name || strcmp (name, "/"))
145            result |= 32;
146          free (name);
147        }
148        #endif
149        return result;
150      ]])
151     ],
152     [gl_cv_func_realpath_works=yes],
153     [case $? in
154        32) gl_cv_func_realpath_works=nearly ;;
155        *)  gl_cv_func_realpath_works=no ;;
156      esac
157     ],
158     [case "$host_os" in
159                       # Guess yes on glibc systems.
160        *-gnu* | gnu*) gl_cv_func_realpath_works="guessing yes" ;;
161                       # Guess 'nearly' on musl systems.
162        *-musl*)       gl_cv_func_realpath_works="guessing nearly" ;;
163                       # Guess no on Cygwin.
164        cygwin*)       gl_cv_func_realpath_works="guessing no" ;;
165                       # Guess no on native Windows.
166        mingw*)        gl_cv_func_realpath_works="guessing no" ;;
167                       # If we don't know, obey --enable-cross-guesses.
168        *)             gl_cv_func_realpath_works="$gl_cross_guess_normal" ;;
169      esac
170     ])
171    rm -rf conftest.a conftest.l conftest.d
172  ])
173  case "$gl_cv_func_realpath_works" in
174    *yes)
175      AC_DEFINE([FUNC_REALPATH_WORKS], [1],
176        [Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles leading slashes and a trailing slash correctly.])
177      ;;
178    *nearly)
179      AC_DEFINE([FUNC_REALPATH_NEARLY_WORKS], [1],
180        [Define to 1 if realpath() can malloc memory, always gives an absolute path, and handles a trailing slash correctly.])
181      ;;
182  esac
183])
184