changeset 12018:586fda772b8f

canonicalize-lgpl: fix glibc bug with trailing slash Consolidate the m4 macros into a single file, since both modules now have to worry about replacing canonicalize_file_name on buggy glibc. * m4/canonicalize-lgpl.m4: Move contents... * m4/canonicalize.m4: ...here. (gl_CANONICALIZE_LGPL): Factor realpath check... (gl_FUNC_REALPATH_WORKS): ...into new macro. Enhance to catch glibc 2.3.5 bug, fixed 2005-04-27. (gl_FUNC_CANONICALIZE_FILENAME_MODE): Use it. (gl_PREREQ_CANONICALIZE_LGPL): Inline... (gl_CANONICALIZE_LGPL_SEPARATE): ...into this macro. * modules/canonicalize-lgpl (Files): Manage file rename. * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default. * modules/stdlib (Makefile.am): Substitute witness. * lib/stdlib.in.h (canonicalize_file_name): Declare if replacement is needed. * lib/canonicalize-lgpl.c: Also compile if canonicalize_file_name replacement is required. * lib/canonicalize.c (canonicalize_file_name): Likewise. * doc/glibc-functions/canonicalize_file_name.texi (canonicalize_file_name): Document this. * doc/posix-functions/realpath.texi (realpath): Likewise. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Fri, 11 Sep 2009 13:57:55 -0600
parents acc38673eec3
children 4e6951cd4f33
files ChangeLog doc/glibc-functions/canonicalize_file_name.texi doc/posix-functions/realpath.texi lib/canonicalize-lgpl.c lib/canonicalize.c lib/stdlib.in.h m4/canonicalize-lgpl.m4 m4/canonicalize.m4 m4/stdlib_h.m4 modules/canonicalize-lgpl modules/stdlib
diffstat 11 files changed, 113 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,26 @@
 2009-09-17  Eric Blake  <ebb9@byu.net>
 
+	canonicalize-lgpl: fix glibc bug with trailing slash
+	* m4/canonicalize-lgpl.m4: Move contents...
+	* m4/canonicalize.m4: ...here.
+	(gl_CANONICALIZE_LGPL): Factor realpath check...
+	(gl_FUNC_REALPATH_WORKS): ...into new macro.  Enhance to catch
+	glibc 2.3.5 bug, fixed 2005-04-27.
+	(gl_FUNC_CANONICALIZE_FILENAME_MODE): Use it.
+	(gl_PREREQ_CANONICALIZE_LGPL): Inline...
+	(gl_CANONICALIZE_LGPL_SEPARATE): ...into this macro.
+	* modules/canonicalize-lgpl (Files): Manage file rename.
+	* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide default.
+	* modules/stdlib (Makefile.am): Substitute witness.
+	* lib/stdlib.in.h (canonicalize_file_name): Declare if replacement
+	is needed.
+	* lib/canonicalize-lgpl.c: Also compile if canonicalize_file_name
+	replacement is required.
+	* lib/canonicalize.c (canonicalize_file_name): Likewise.
+	* doc/glibc-functions/canonicalize_file_name.texi
+	(canonicalize_file_name): Document this.
+	* doc/posix-functions/realpath.texi (realpath): Likewise.
+
 	canonicalize-lgpl: reject non-directory with trailing slash
 	* lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc.
 	* tests/test-canonicalize-lgpl.c (main): Enhance test.  This
--- a/doc/glibc-functions/canonicalize_file_name.texi
+++ b/doc/glibc-functions/canonicalize_file_name.texi
@@ -9,6 +9,10 @@
 @item
 This function is missing on all non-glibc platforms:
 MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, AIX 5.1, HP-UX 11, IRIX 6.5, OSF/1 5.1, Solaris 10, Cygwin, mingw, Interix 3.5, BeOS.
+@item
+This function fails to detect trailing slashes on non-directories on
+some platforms:
+glibc 2.3.5.
 @end itemize
 
 Portability problems not fixed by Gnulib:
--- a/doc/posix-functions/realpath.texi
+++ b/doc/posix-functions/realpath.texi
@@ -19,6 +19,14 @@
 This function does not always return an absolute path on some
 platforms:
 Solaris.
+@item
+This function fails to detect trailing slashes on non-directories on
+some platforms:
+glibc 2.3.5.
+@item
+This function fails to recognize non-directories followed @samp{..} on
+some platforms:
+cygwin.
 @end itemize
 
 Portability problems not fixed by Gnulib:
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -19,7 +19,7 @@
 # include <config.h>
 #endif
 
-#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC
+#if !HAVE_CANONICALIZE_FILE_NAME || !FUNC_REALPATH_WORKS || defined _LIBC
 
 /* Specification.  */
 #include <stdlib.h>
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -31,7 +31,8 @@
 #include "xalloc.h"
 #include "xgetcwd.h"
 
-#if !(HAVE_CANONICALIZE_FILE_NAME || GNULIB_CANONICALIZE_LGPL)
+#if !((HAVE_CANONICALIZE_FILE_NAME && FUNC_REALPATH_WORKS)	\
+      || GNULIB_CANONICALIZE_LGPL)
 /* Return the canonical absolute name of file NAME.  A canonical name
    does not contain any `.', `..' components nor any repeated file name
    separators ('/') or symlinks.  All components must exist.
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -116,7 +116,10 @@
 #endif
 
 #if @GNULIB_CANONICALIZE_FILE_NAME@
-# if !@HAVE_CANONICALIZE_FILE_NAME@
+# if @REPLACE_CANONICALIZE_FILE_NAME@
+#  define canonicalize_file_name rpl_canonicalize_file_name
+# endif
+# if !@HAVE_CANONICALIZE_FILE_NAME@ || @REPLACE_CANONICALIZE_FILE_NAME@
 extern char *canonicalize_file_name (const char *name);
 # endif
 #elif defined GNULIB_POSIXCHECK
deleted file mode 100644
--- a/m4/canonicalize-lgpl.m4
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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,
-dnl with or without modifications, as long as this notice is preserved.
-
-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 realpath])
-  dnl Assume that all platforms with canonicalize_file_name also have
-  dnl a working realpath.
-  if test $ac_cv_func_canonicalize_file_name = no; then
-    HAVE_CANONICALIZE_FILE_NAME=0
-    AC_LIBOBJ([canonicalize-lgpl])
-    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
-])
-
-# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation
-# (no AC_LIBOBJ).
-AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
-[
-  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
-  AC_CHECK_FUNCS_ONCE([canonicalize_file_name])
-  gl_PREREQ_CANONICALIZE_LGPL
-])
-
-# Prerequisites of lib/canonicalize-lgpl.c.
-AC_DEFUN([gl_PREREQ_CANONICALIZE_LGPL],
-[
-  AC_CHECK_HEADERS_ONCE([sys/param.h])
-  AC_CHECK_FUNCS_ONCE([getcwd readlink])
-])
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,18 +1,79 @@
-# canonicalize.m4 serial 14
+# canonicalize.m4 serial 15
 
-# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software
-# Foundation, Inc.
+dnl Copyright (C) 2003-2007, 2009 Free Software Foundation, Inc.
 
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
 
-# Written by Jim Meyering.
-
+# Provides canonicalize_file_name and canonicalize_filename_mode, but does
+# not provide or fix realpath.
 AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE],
 [
   AC_LIBOBJ([canonicalize])
 
   AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
   AC_CHECK_FUNCS_ONCE([canonicalize_file_name])
+  AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
+  if test $ac_cv_func_canonicalize_file_name = no; then
+    HAVE_CANONICALIZE_FILE_NAME=0
+  elif test $gl_cv_func_realpath_works != yes; then
+    REPLACE_CANONICALIZE_FILE_NAME=1
+  fi
 ])
+
+# Provides canonicalize_file_name and realpath.
+AC_DEFUN([gl_CANONICALIZE_LGPL],
+[
+  AC_REQUIRE([gl_CANONICALIZE_LGPL_SEPARATE])
+  if test $ac_cv_func_canonicalize_file_name = no; then
+    HAVE_CANONICALIZE_FILE_NAME=0
+    AC_LIBOBJ([canonicalize-lgpl])
+    if test $ac_cv_func_realpath = no; then
+      HAVE_REALPATH=0
+    elif test $gl_cv_func_realpath_works != yes; then
+      REPLACE_REALPATH=1
+    fi
+  elif test $gl_cv_func_realpath_works != yes; then
+    AC_LIBOBJ([canonicalize-lgpl])
+    REPLACE_REALPATH=1
+    REPLACE_CANONICALIZE_FILE_NAME=1
+  fi
+])
+
+# Like gl_CANONICALIZE_LGPL, except prepare for separate compilation
+# (no AC_LIBOBJ).
+AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
+[
+  AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
+  AC_CHECK_FUNCS_ONCE([canonicalize_file_name getcwd readlink])
+  AC_REQUIRE([gl_FUNC_REALPATH_WORKS])
+  AC_CHECK_HEADERS_ONCE([sys/param.h])
+])
+
+# Check whether realpath works.  Assume that if a platform has both
+# realpath and canonicalize_file_name, but the former is broken, then
+# so is the latter.
+AC_DEFUN([gl_FUNC_REALPATH_WORKS],
+[
+  AC_CHECK_FUNCS_ONCE([realpath])
+  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);
+        char *name3 = realpath ("conftest.a/", NULL);
+        return !(name1 && *name1 == '/' && !name2 && !name3);
+      ]])
+    ], [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
+    AC_DEFINE([FUNC_REALPATH_WORKS], [1], [Define to 1 if realpath()
+      can malloc memory, always gives an absolute path, and handles
+      trailing slash correctly.])
+  fi
+])
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 19
+# stdlib_h.m4 serial 20
 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,
@@ -72,6 +72,7 @@
   HAVE_STRUCT_RANDOM_DATA=1; AC_SUBST([HAVE_STRUCT_RANDOM_DATA])
   HAVE_SYS_LOADAVG_H=0;      AC_SUBST([HAVE_SYS_LOADAVG_H])
   HAVE_UNSETENV=1;           AC_SUBST([HAVE_UNSETENV])
+  REPLACE_CANONICALIZE_FILE_NAME=0;  AC_SUBST([REPLACE_CANONICALIZE_FILE_NAME])
   REPLACE_MKSTEMP=0;         AC_SUBST([REPLACE_MKSTEMP])
   REPLACE_PUTENV=0;          AC_SUBST([REPLACE_PUTENV])
   REPLACE_REALPATH=0;        AC_SUBST([REPLACE_REALPATH])
--- a/modules/canonicalize-lgpl
+++ b/modules/canonicalize-lgpl
@@ -3,7 +3,7 @@
 
 Files:
 lib/canonicalize-lgpl.c
-m4/canonicalize-lgpl.m4
+m4/canonicalize.m4
 
 Depends-on:
 alloca-opt
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -65,6 +65,7 @@
 	      -e 's|@''HAVE_STRUCT_RANDOM_DATA''@|$(HAVE_STRUCT_RANDOM_DATA)|g' \
 	      -e 's|@''HAVE_SYS_LOADAVG_H''@|$(HAVE_SYS_LOADAVG_H)|g' \
 	      -e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \
+	      -e 's|@''REPLACE_CANONICALIZE_FILE_NAME''@|$(REPLACE_CANONICALIZE_FILE_NAME)|g' \
 	      -e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
 	      -e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
 	      -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \