changeset 12016:4fac822214af

canonicalize-lgpl: use native realpath if it works Forward-looking to when more platforms comply with POSIX 2008, but don't provide glibc extensions. For example, this could fix // handling in cygwin 1.7 (well, if cygwin didn't have bugs in .. handling). canonicalize can't use native realpath, for the same reason that it does not use resolvepath. * lib/canonicalize-lgpl.c (realpath): Guard with FUNC_REALPATH_WORKS. * lib/stdlib.in.h (realpath): Make declaration optional based on HAVE_REALPATH. * m4/canonicalize-lgpl.m4 (gl_CANONICALIZE_LGPL): Check whether native realpath works. * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default. * modules/stdlib (Makefile.am): Substitute witness. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Thu, 10 Sep 2009 15:44:15 -0600
parents 9317d4a9ac96
children acc38673eec3
files ChangeLog lib/canonicalize-lgpl.c lib/stdlib.in.h m4/canonicalize-lgpl.m4 m4/stdlib_h.m4 modules/stdlib
diffstat 6 files changed, 43 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2009-09-17  Eric Blake  <ebb9@byu.net>
 
+	canonicalize-lgpl: use native realpath if it works
+	* lib/canonicalize-lgpl.c (realpath): Guard with
+	FUNC_REALPATH_WORKS.
+	* lib/stdlib.in.h (realpath): Make declaration optional based on
+	HAVE_REALPATH.
+	* m4/canonicalize-lgpl.m4 (gl_CANONICALIZE_LGPL): Check whether
+	native realpath works.
+	* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default.
+	* modules/stdlib (Makefile.am): Substitute witness.
+
 	canonicalize, canonicalize-lgpl: use <stdlib.h>
 	* modules/canonicalize-lgpl (Files): Drop canonicalize.h.
 	(Include): Mention <stdlib.h>.
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -72,6 +72,7 @@
 # define __readlink readlink
 #endif
 
+#if !FUNC_REALPATH_WORKS || defined _LIBC
 /* Return the canonical absolute name of file NAME.  A canonical name
    does not contain any `.', `..' components nor any repeated path
    separators ('/') or symlinks.  All path components must exist.  If
@@ -310,9 +311,8 @@
   }
   return NULL;
 }
-#ifdef _LIBC
 versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
-#endif
+#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
 
 
 #if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -307,6 +307,8 @@
 #if @GNULIB_REALPATH@
 # if @REPLACE_REALPATH@
 #  define realpath rpl_realpath
+# endif
+# if !@HAVE_REALPATH@ || @REPLACE_REALPATH@
 extern char *realpath (const char *name, char *resolved);
 # endif
 #elif defined GNULIB_POSIXCHECK
--- a/m4/canonicalize-lgpl.m4
+++ b/m4/canonicalize-lgpl.m4
@@ -1,4 +1,4 @@
-# canonicalize-lgpl.m4 serial 7
+# canonicalize-lgpl.m4 serial 8
 dnl Copyright (C) 2003, 2006-2007, 2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -9,13 +9,35 @@
   dnl Do this replacement check manually because the file name is shorter
   dnl than the function name.
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CHECK_FUNCS_ONCE([canonicalize_file_name])
+  AC_CHECK_FUNCS_ONCE([canonicalize_file_name realpath])
   dnl Assume that all platforms with canonicalize_file_name also have
-  dnl a working realpath; otherwise assume realpath is broken.
+  dnl a working realpath.
   if test $ac_cv_func_canonicalize_file_name = no; then
     HAVE_CANONICALIZE_FILE_NAME=0
     AC_LIBOBJ([canonicalize-lgpl])
-    REPLACE_REALPATH=1
+    if test $ac_cv_func_realpath = no; then
+      HAVE_REALPATH=0
+    else
+      AC_CACHE_CHECK([whether realpath works], [gl_cv_func_realpath_works], [
+        touch conftest.a
+        AC_RUN_IFELSE([
+          AC_LANG_PROGRAM([[
+            #include <stdlib.h>
+          ]], [[
+            char *name1 = realpath ("conftest.a", NULL);
+            char *name2 = realpath ("conftest.b/../conftest.a", NULL);
+            return !(name1 && *name1 == '/' && !name2);
+          ]])
+        ], [gl_cv_func_realpath_works=yes], [gl_cv_func_realpath_works=no],
+           [gl_cv_func_realpath_works="guessing no"])
+      ])
+      if test $gl_cv_func_realpath_works != yes; then
+        REPLACE_REALPATH=1
+      else
+        AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath()
+          can malloc memory and always gives an absolute path.])
+      fi
+    fi
     gl_PREREQ_CANONICALIZE_LGPL
   fi
 ])
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 18
+# stdlib_h.m4 serial 19
 dnl Copyright (C) 2007-2009 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -63,6 +63,7 @@
   HAVE_MKOSTEMP=1;           AC_SUBST([HAVE_MKOSTEMP])
   HAVE_RANDOM_R=1;           AC_SUBST([HAVE_RANDOM_R])
   HAVE_REALLOC_POSIX=1;      AC_SUBST([HAVE_REALLOC_POSIX])
+  HAVE_REALPATH=1;           AC_SUBST([HAVE_REALPATH])
   HAVE_RPMATCH=1;            AC_SUBST([HAVE_RPMATCH])
   HAVE_SETENV=1;             AC_SUBST([HAVE_SETENV])
   HAVE_STRTOD=1;             AC_SUBST([HAVE_STRTOD])
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -56,6 +56,7 @@
 	      -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
 	      -e 's|@''HAVE_RANDOM_R''@|$(HAVE_RANDOM_R)|g' \
 	      -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \
+	      -e 's|@''HAVE_REALPATH''@|$(HAVE_REALPATH)|g' \
 	      -e 's|@''HAVE_RPMATCH''@|$(HAVE_RPMATCH)|g' \
 	      -e 's|@''HAVE_SETENV''@|$(HAVE_SETENV)|g' \
 	      -e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \