Home | History | Annotate | Line # | Download | only in m4
      1 # canonicalize.m4 serial 37
      2 
      3 dnl Copyright (C) 2003-2007, 2009-2022 Free Software Foundation, Inc.
      4 
      5 dnl This file is free software; the Free Software Foundation
      6 dnl gives unlimited permission to copy and/or distribute it,
      7 dnl 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.
     11 AC_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.
     29 AC_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).
     57 AC_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.
     79 AC_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