canonicalize-lgpl: use native realpath if it works
authorEric Blake <ebb9@byu.net>
Thu, 10 Sep 2009 21:44:15 +0000 (15:44 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 18 Sep 2009 01:16:26 +0000 (19:16 -0600)
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>
ChangeLog
lib/canonicalize-lgpl.c
lib/stdlib.in.h
m4/canonicalize-lgpl.m4
m4/stdlib_h.m4
modules/stdlib

index 1d89bb3..681fc48 100644 (file)
--- 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>.
index c8f7e16..edf91e2 100644 (file)
@@ -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 @@ error:
   }
   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)
index a6512c5..b20f699 100644 (file)
@@ -307,6 +307,8 @@ extern void * realloc (void *ptr, size_t size);
 #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
index d040c68..1fdacf8 100644 (file)
@@ -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 @@ AC_DEFUN([gl_CANONICALIZE_LGPL],
   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
 ])
index 8cb5d48..1bcf06e 100644 (file)
@@ -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 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
   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])
index c404ca2..bb8a164 100644 (file)
@@ -56,6 +56,7 @@ stdlib.h: stdlib.in.h
              -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' \