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