[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: canonicalize-lgpl bug
From: |
Eric Blake |
Subject: |
Re: canonicalize-lgpl bug |
Date: |
Thu, 10 Sep 2009 23:24:08 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Jim Meyering <jim <at> meyering.net> writes:
> > I noticed that glibc has applied some fixes to canonicalize.c that we were
> > missing; and sure enough, was able to enhance the testsuite to trip these
> > bugs. They also applied some assert's proving that their optimization to
avoid
> > strcpy are safe; I left the asserts out, but copied their optimization. OK
to
> > commit?
>
> Sure.
> Thanks for doing that!
Here's the current state of the series. It still doesn't fix the bug that
canonicalize-lgpl goofs on leading // when providing realpath. Nor does it fix
execution on mingw (where a good implementation need not worry about symlinks,
but should worry about drive letters and should convert '/' to '\\'). But at
least on cygwin, canonicalize-lgpl now honors // by virtue of deferring to the
working native realpath. On the other hand, cygwin realpath() behaves like all
other cygwin functions, such as stat() and open(), where garbage/.. is silently
collapsed whithout checking whether garbage exists or is a symlink.
Note that I've changed things around a bit - canonicalize now provides ONLY
canonicalize_filename_mode - the coreutils extension that allows for choosing
how strict the canonicalization needs to be (useful for implementing readlink
(1)). Meanwhile, canonicalize-lgpl is the ONLY provider of
canonicalize_file_name, and it ALSO provides a POSIX-compliant realpath, for
all systems (well, if there are any live glibc systems out there where
canonicalize_file_name("file/") still passes rather than failing with ENOENT,
then we need a subsequent patch to introduce rpl_canonicalize_file_name).
Does anyone want further changes, such as to the names of these modules? I
could reasonably see renaming canonicalize to canonicalize-mode, and
canonicalize-lgpl to either canonicalize_file_name or to realpath. I could
also try porting // handling to canonicalize-lgpl realpath (and propose the
same patch upstream to glibc), although I'd rather not do that until we find a
platform that honors // but does not have working realpath.
At any rate, I don't feel comfortable pushing this series until I have some
reviews or more feedback, and possibly a fix to cygwin to better handle '..'.
Jim, once I apply this series, coreutils will need to either: start importing
canonicalize-lgpl (right now, it avoids it), or change df.c to use
canonicalize_filename_mode(,CAN_EXISTING) (perhaps via a #define in system.h).
Eric Blake (6):
canonicalize-lgpl: reject non-directory with trailing slash
stdlib: sort witness names
canonicalize: leave canonicalize_file_name to canonicalize-lgpl
canonicalize-lgpl: use native realpath if it works
canonicalize: don't lose errno
canonicalize: honor // if distinct from /
>From cfe26089b21bdddc721a619d4e7da550fc64e1fa Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 12:12:16 -0600
Subject: [PATCH 1/6] canonicalize-lgpl: reject non-directory with trailing slash
* lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc.
* tests/test-canonicalize-lgpl.c (main): Enhance test.
* tests/test-canonicalize.c (main): Likewise. Avoid collisions
with test-canonicalize-lgpl.sh run in parallel.
* tests/test-canonicalize.sh (tmpfiles): Use the name ise1, not
ise, for parallel make.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 10 ++++++++++
lib/canonicalize-lgpl.c | 11 +++++++----
tests/test-canonicalize-lgpl.c | 16 +++++++++++++++-
tests/test-canonicalize.c | 26 +++++++++++++++++++++++---
tests/test-canonicalize.sh | 6 +++---
5 files changed, 58 insertions(+), 11 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c190ecc..de7b506 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2009-09-10 Eric Blake <address@hidden>
+
+ canonicalize-lgpl: reject non-directory with trailing slash
+ * lib/canonicalize-lgpl.c (__realpath): Synchronize with glibc.
+ * tests/test-canonicalize-lgpl.c (main): Enhance test.
+ * tests/test-canonicalize.c (main): Likewise. Avoid collisions
+ with test-canonicalize-lgpl.sh run in parallel.
+ * tests/test-canonicalize.sh (tmpfiles): Use the name ise1, not
+ ise, for parallel make.
+
2009-09-10 Ralf Wildenhues <address@hidden>
Remove obsolete macros from several modules.
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 6b5663a..c8f313e 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -298,6 +298,11 @@ __realpath (const char *name, char *resolved)
while ((--dest)[-1] != '/');
}
#endif
+ else if (!S_ISDIR (st.st_mode) && *end != '\0')
+ {
+ __set_errno (ENOTDIR);
+ goto error;
+ }
}
}
if (dest > rpath + 1 && dest[-1] == '/')
@@ -307,16 +312,14 @@ __realpath (const char *name, char *resolved)
if (extra_buf)
freea (extra_buf);
- return resolved ? memcpy (resolved, rpath, dest - rpath + 1) : rpath;
+ return rpath;
error:
{
int saved_errno = errno;
if (extra_buf)
freea (extra_buf);
- if (resolved)
- strcpy (resolved, rpath);
- else
+ if (resolved == NULL)
free (rpath);
errno = saved_errno;
}
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 29b919d..87e5e46 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -1,5 +1,5 @@
/* Test of execution of program termination handlers.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -79,6 +79,20 @@ main ()
ASSERT (result == NULL);
}
+ /* Check that a non-directory with trailing slash yields NULL. */
+ {
+ char *result = canonicalize_file_name ("t-can-lgpl.tmp/tra/");
+ ASSERT (result == NULL);
+ result = canonicalize_file_name ("t-can-lgpl.tmp/huk/");
+ ASSERT (result == NULL);
+ }
+
+ /* Check that a missing directory yields NULL. */
+ {
+ char *result = canonicalize_file_name ("t-can-lgpl.tmp/ouk/..");
+ ASSERT (result == NULL);
+ }
+
/* Check that a loop of symbolic links is detected. */
{
char *result = canonicalize_file_name ("ise");
diff --git a/tests/test-canonicalize.c b/tests/test-canonicalize.c
index d76c307..f0212e0 100644
--- a/tests/test-canonicalize.c
+++ b/tests/test-canonicalize.c
@@ -1,5 +1,5 @@
/* Test of execution of file name canonicalization.
- Copyright (C) 2007-2008 Free Software Foundation, Inc.
+ Copyright (C) 2007-2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -85,10 +85,30 @@ main ()
ASSERT (result2 == NULL);
}
+ /* Check that a non-directory with trailing slash yields NULL. */
+ {
+ char *result1 = canonicalize_file_name ("t-can.tmp/tra/");
+ char *result2 = canonicalize_filename_mode ("t-can.tmp/tra/",
CAN_EXISTING);
+ ASSERT (result1 == NULL);
+ ASSERT (result2 == NULL);
+ result1 = canonicalize_file_name ("t-can.tmp/huk/");
+ result2 = canonicalize_filename_mode ("t-can.tmp/huk/", CAN_EXISTING);
+ ASSERT (result1 == NULL);
+ ASSERT (result2 == NULL);
+ }
+
+ /* Check that a missing directory yields NULL. */
+ {
+ char *result1 = canonicalize_file_name ("t-can.tmp/ouk/..");
+ char *result2 = canonicalize_filename_mode ("t-can.tmp/ouk/..",
CAN_EXISTING);
+ ASSERT (result1 == NULL);
+ ASSERT (result2 == NULL);
+ }
+
/* Check that a loop of symbolic links is detected. */
{
- char *result1 = canonicalize_file_name ("ise");
- char *result2 = canonicalize_filename_mode ("ise", CAN_EXISTING);
+ char *result1 = canonicalize_file_name ("ise1");
+ char *result2 = canonicalize_filename_mode ("ise1", CAN_EXISTING);
ASSERT (result1 == NULL);
ASSERT (result2 == NULL);
}
diff --git a/tests/test-canonicalize.sh b/tests/test-canonicalize.sh
index a4ab962..224ec86 100755
--- a/tests/test-canonicalize.sh
+++ b/tests/test-canonicalize.sh
@@ -3,10 +3,10 @@
tmpfiles=""
trap 'rm -fr $tmpfiles' 1 2 3 15
-tmpfiles="$tmpfiles t-can.tmp ise"
+tmpfiles="$tmpfiles t-can.tmp ise1"
mkdir t-can.tmp
test "x$HAVE_SYMLINK" = xyes \
- && ln -s t-can.tmp/ket ise \
+ && ln -s t-can.tmp/ket ise1 \
|| { echo "Skipping test: symbolic links not supported on this filesystem"
rm -fr $tmpfiles
exit 77
@@ -16,7 +16,7 @@ test "x$HAVE_SYMLINK" = xyes \
&& ln -s tra huk \
&& ln -s lum bef \
&& ln -s wum ouk \
- && ln -s ../ise ket \
+ && ln -s ../ise1 ket \
&& echo > tra \
&& mkdir lum
) || exit 1
--
1.6.3.2
>From 851f2832809230b9982b3ad43f3dcabdd8e51c80 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 14:10:41 -0600
Subject: [PATCH 2/6] stdlib: sort witness names
* modules/stdlib (Makefile.am): Sort replacements.
* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Likewise.
* lib/stdlib.in.h: Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 5 ++
lib/stdlib.in.h | 114 +++++++++++++++++++++++--------------------------------
m4/stdlib_h.m4 | 12 +++---
modules/stdlib | 12 +++---
4 files changed, 65 insertions(+), 78 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index de7b506..03619d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
2009-09-10 Eric Blake <address@hidden>
+ stdlib: sort witness names
+ * modules/stdlib (Makefile.am): Sort replacements.
+ * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Likewise.
+ * lib/stdlib.in.h: 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.
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index 9ac7199..f05962e 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -87,37 +87,20 @@ struct random_data
extern "C" {
#endif
-
-#if @GNULIB_MALLOC_POSIX@
-# if address@hidden@
-# undef malloc
-# define malloc rpl_malloc
-extern void * malloc (size_t size);
-# endif
-#elif defined GNULIB_POSIXCHECK
-# undef malloc
-# define malloc(s) \
- (GL_LINK_WARNING ("malloc is not POSIX compliant everywhere - " \
- "use gnulib module malloc-posix for portability"), \
- malloc (s))
-#endif
-
-
-#if @GNULIB_REALLOC_POSIX@
-# if address@hidden@
-# undef realloc
-# define realloc rpl_realloc
-extern void * realloc (void *ptr, size_t size);
+#if @GNULIB_ATOLL@
+# if address@hidden@
+/* Parse a signed decimal integer.
+ Returns the value of the integer. Errors are not detected. */
+extern long long atoll (const char *string);
# endif
#elif defined GNULIB_POSIXCHECK
-# undef realloc
-# define realloc(p,s) \
- (GL_LINK_WARNING ("realloc is not POSIX compliant everywhere - " \
- "use gnulib module realloc-posix for portability"), \
- realloc (p, s))
+# undef atoll
+# define atoll(s) \
+ (GL_LINK_WARNING ("atoll is unportable - " \
+ "use gnulib module atoll for portability"), \
+ atoll (s))
#endif
-
#if @GNULIB_CALLOC_POSIX@
# if address@hidden@
# undef calloc
@@ -132,22 +115,6 @@ extern void * calloc (size_t nmemb, size_t size);
calloc (n, s))
#endif
-
-#if @GNULIB_ATOLL@
-# if address@hidden@
-/* Parse a signed decimal integer.
- Returns the value of the integer. Errors are not detected. */
-extern long long atoll (const char *string);
-# endif
-#elif defined GNULIB_POSIXCHECK
-# undef atoll
-# define atoll(s) \
- (GL_LINK_WARNING ("atoll is unportable - " \
- "use gnulib module atoll for portability"), \
- atoll (s))
-#endif
-
-
#if @GNULIB_GETLOADAVG@
# if address@hidden@
/* Store max(NELEM,3) load average numbers in LOADAVG[].
@@ -164,7 +131,6 @@ extern int getloadavg (double loadavg[], int nelem);
getloadavg (l, n))
#endif
-
#if @GNULIB_GETSUBOPT@
/* Assuming *OPTIONP is a comma separated list of elements of the form
"token" or "token=value", getsubopt parses the first of these elements.
@@ -188,6 +154,19 @@ extern int getsubopt (char **optionp, char *const *tokens,
char **valuep);
getsubopt (o, t, v))
#endif
+#if @GNULIB_MALLOC_POSIX@
+# if address@hidden@
+# undef malloc
+# define malloc rpl_malloc
+extern void * malloc (size_t size);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef malloc
+# define malloc(s) \
+ (GL_LINK_WARNING ("malloc is not POSIX compliant everywhere - " \
+ "use gnulib module malloc-posix for portability"), \
+ malloc (s))
+#endif
#if @GNULIB_MKDTEMP@
# if address@hidden@
@@ -206,7 +185,6 @@ extern char * mkdtemp (char * /*template*/);
mkdtemp (t))
#endif
-
#if @GNULIB_MKOSTEMP@
# if address@hidden@
/* Create a unique temporary file from TEMPLATE.
@@ -231,7 +209,6 @@ extern int mkostemp (char * /*template*/, int /*flags*/);
mkostemp (t, f))
#endif
-
#if @GNULIB_MKSTEMP@
# if @REPLACE_MKSTEMP@
/* Create a unique temporary file from TEMPLATE.
@@ -257,7 +234,6 @@ extern int mkstemp (char * /*template*/);
mkstemp (t))
#endif
-
#if @GNULIB_PUTENV@
# if @REPLACE_PUTENV@
# undef putenv
@@ -266,7 +242,6 @@ extern int putenv (char *string);
# endif
#endif
-
#if @GNULIB_RANDOM_R@
# if address@hidden@
@@ -303,6 +278,19 @@ int random_r (struct random_data *buf, int32_t *result);
setstate_r (a,r))
#endif
+#if @GNULIB_REALLOC_POSIX@
+# if address@hidden@
+# undef realloc
+# define realloc rpl_realloc
+extern void * realloc (void *ptr, size_t size);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef realloc
+# define realloc(p,s) \
+ (GL_LINK_WARNING ("realloc is not POSIX compliant everywhere - " \
+ "use gnulib module realloc-posix for portability"), \
+ realloc (p, s))
+#endif
#if @GNULIB_RPMATCH@
# if address@hidden@
@@ -318,7 +306,6 @@ extern int rpmatch (const char *response);
rpmatch (r))
#endif
-
#if @GNULIB_SETENV@
# if address@hidden@
/* Set NAME to VALUE in the environment.
@@ -327,21 +314,6 @@ extern int setenv (const char *name, const char *value,
int replace);
# endif
#endif
-
-#if @GNULIB_UNSETENV@
-# if @HAVE_UNSETENV@
-# if @VOID_UNSETENV@
-/* On some systems, unsetenv() returns void.
- This is the case for MacOS X 10.3, FreeBSD 4.8, NetBSD 1.6, OpenBSD 3.4. */
-# define unsetenv(name) ((unsetenv)(name), 0)
-# endif
-# else
-/* Remove the variable NAME from the environment. */
-extern int unsetenv (const char *name);
-# endif
-#endif
-
-
#if @GNULIB_STRTOD@
# if @REPLACE_STRTOD@
# define strtod rpl_strtod
@@ -358,7 +330,6 @@ extern double strtod (const char *str, char **endp);
strtod (s, e))
#endif
-
#if @GNULIB_STRTOLL@
# if address@hidden@
/* Parse a signed integer whose textual representation starts at STRING.
@@ -379,7 +350,6 @@ extern long long strtoll (const char *string, char
**endptr, int base);
strtoll (s, e, b))
#endif
-
#if @GNULIB_STRTOULL@
# if address@hidden@
/* Parse an unsigned integer whose textual representation starts at STRING.
@@ -400,6 +370,18 @@ extern unsigned long long strtoull (const char *string,
char **endptr, int base)
strtoull (s, e, b))
#endif
+#if @GNULIB_UNSETENV@
+# if @HAVE_UNSETENV@
+# if @VOID_UNSETENV@
+/* On some systems, unsetenv() returns void.
+ This is the case for MacOS X 10.3, FreeBSD 4.8, NetBSD 1.6, OpenBSD 3.4. */
+# define unsetenv(name) ((unsetenv)(name), 0)
+# endif
+# else
+/* Remove the variable NAME from the environment. */
+extern int unsetenv (const char *name);
+# endif
+#endif
#ifdef __cplusplus
}
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index 89ac97f..b7cf18c 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 16
+# stdlib_h.m4 serial 17
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,
@@ -33,17 +33,17 @@ AC_DEFUN([gl_STDLIB_MODULE_INDICATOR],
AC_DEFUN([gl_STDLIB_H_DEFAULTS],
[
- GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
- GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
- GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL])
+ GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG])
GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
+ GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
GNULIB_MKDTEMP=0; AC_SUBST([GNULIB_MKDTEMP])
GNULIB_MKOSTEMP=0; AC_SUBST([GNULIB_MKOSTEMP])
GNULIB_MKSTEMP=0; AC_SUBST([GNULIB_MKSTEMP])
GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV])
GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R])
+ GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH])
GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV])
GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD])
@@ -53,12 +53,13 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL])
HAVE_CALLOC_POSIX=1; AC_SUBST([HAVE_CALLOC_POSIX])
+ HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG])
HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT])
HAVE_MALLOC_POSIX=1; AC_SUBST([HAVE_MALLOC_POSIX])
HAVE_MKDTEMP=1; AC_SUBST([HAVE_MKDTEMP])
HAVE_MKOSTEMP=1; AC_SUBST([HAVE_MKOSTEMP])
- HAVE_REALLOC_POSIX=1; AC_SUBST([HAVE_REALLOC_POSIX])
HAVE_RANDOM_R=1; AC_SUBST([HAVE_RANDOM_R])
+ HAVE_REALLOC_POSIX=1; AC_SUBST([HAVE_REALLOC_POSIX])
HAVE_RPMATCH=1; AC_SUBST([HAVE_RPMATCH])
HAVE_SETENV=1; AC_SUBST([HAVE_SETENV])
HAVE_STRTOD=1; AC_SUBST([HAVE_STRTOD])
@@ -67,7 +68,6 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
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])
- HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG])
REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
diff --git a/modules/stdlib b/modules/stdlib
index c19d7d6..b15f9ae 100644
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -26,18 +26,17 @@ stdlib.h: stdlib.in.h
sed -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
-e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
-e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
- -e 's|@''HAVE_RANDOM_H''@|$(HAVE_RANDOM_H)|g' \
- -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
- -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \
- -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
-e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \
+ -e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
-e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \
-e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
+ -e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
-e 's|@''GNULIB_MKDTEMP''@|$(GNULIB_MKDTEMP)|g' \
-e 's|@''GNULIB_MKOSTEMP''@|$(GNULIB_MKOSTEMP)|g' \
-e 's|@''GNULIB_MKSTEMP''@|$(GNULIB_MKSTEMP)|g' \
-e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \
-e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \
+ -e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \
-e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \
-e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \
-e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \
@@ -46,12 +45,14 @@ stdlib.h: stdlib.in.h
-e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
-e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
-e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \
+ -e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
-e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
-e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \
-e 's|@''HAVE_MKDTEMP''@|$(HAVE_MKDTEMP)|g' \
-e 's|@''HAVE_MKOSTEMP''@|$(HAVE_MKOSTEMP)|g' \
- -e 's|@''HAVE_REALLOC_POSIX''@|$(HAVE_REALLOC_POSIX)|g' \
+ -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_RPMATCH''@|$(HAVE_RPMATCH)|g' \
-e 's|@''HAVE_SETENV''@|$(HAVE_SETENV)|g' \
-e 's|@''HAVE_STRTOD''@|$(HAVE_STRTOD)|g' \
@@ -60,7 +61,6 @@ stdlib.h: stdlib.in.h
-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|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
--
1.6.3.2
>From eb85e26d8c819b00497a53853aba9612438e5012 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 15:04:22 -0600
Subject: [PATCH 3/6] canonicalize: leave canonicalize_file_name to canonicalize-
lgpl
* m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME): Rename...
(gl_FUNC_CANONICALIZE_FILENAME_MODE): ...to this. Drop unneeded
checks.
* modules/canonicalize (configure.ac): Deal with renamed macro.
(Depends-on): Drop filenamecat.
* modules/canonicalize-tests (Depends-on): Add canonicalize-lgpl.
* lib/canonicalize.c (canonicalize_file_name): Delete.
* NEWS: Document this.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 10 ++++++
NEWS | 4 ++
lib/canonicalize.c | 75 --------------------------------------------
m4/canonicalize.m4 | 10 ++---
modules/canonicalize | 5 +--
modules/canonicalize-tests | 1 +
6 files changed, 21 insertions(+), 84 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 03619d8..2f3f391 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
2009-09-10 Eric Blake <address@hidden>
+ canonicalize: leave canonicalize_file_name to canonicalize-lgpl
+ * m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME): Rename...
+ (gl_FUNC_CANONICALIZE_FILENAME_MODE): ...to this. Drop unneeded
+ checks.
+ * modules/canonicalize (configure.ac): Deal with renamed macro.
+ (Depends-on): Drop filenamecat.
+ * modules/canonicalize-tests (Depends-on): Add canonicalize-lgpl.
+ * lib/canonicalize.c (canonicalize_file_name): Delete.
+ * NEWS: Document this.
+
stdlib: sort witness names
* modules/stdlib (Makefile.am): Sort replacements.
* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Likewise.
diff --git a/NEWS b/NEWS
index f506cba..1ccdaea 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ User visible incompatible changes
Date Modules Changes
+2009-09-10 canonicalize This module no longer provides
+ canonicalize_file_name; use the canonicalize-lgpl
+ module for that.
+
2009-09-04 link-follow The macro LINK_FOLLOWS_SYMLINK is now tri-state,
rather than only defined to 1.
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index 523e082..1312ff2 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -33,7 +33,6 @@
#include <stddef.h>
#include "file-set.h"
-#include "filenamecat.h"
#include "hash-triple.h"
#include "xalloc.h"
#include "xgetcwd.h"
@@ -45,80 +44,6 @@
#include "pathmax.h"
#include "areadlink.h"
-#if !(HAVE_CANONICALIZE_FILE_NAME || 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.
- The result is malloc'd. */
-
-char *
-canonicalize_file_name (const char *name)
-{
-# if HAVE_RESOLVEPATH
-
- char *resolved, *extra_buf = NULL;
- size_t resolved_size;
- ssize_t resolved_len;
-
- if (name == NULL)
- {
- __set_errno (EINVAL);
- return NULL;
- }
-
- if (name[0] == '\0')
- {
- __set_errno (ENOENT);
- return NULL;
- }
-
- /* All known hosts with resolvepath (e.g. Solaris 7) don't turn
- relative names into absolute ones, so prepend the working
- directory if the file name is not absolute. */
- if (name[0] != '/')
- {
- char *wd;
-
- if (!(wd = xgetcwd ()))
- return NULL;
-
- extra_buf = file_name_concat (wd, name, NULL);
- name = extra_buf;
- free (wd);
- }
-
- resolved_size = strlen (name);
- while (1)
- {
- resolved_size = 2 * resolved_size + 1;
- resolved = xmalloc (resolved_size);
- resolved_len = resolvepath (name, resolved, resolved_size);
- if (resolved_len < 0)
- {
- free (resolved);
- free (extra_buf);
- return NULL;
- }
- if (resolved_len < resolved_size)
- break;
- free (resolved);
- }
-
- free (extra_buf);
-
- /* NUL-terminate the resulting name. */
- resolved[resolved_len] = '\0';
-
- return resolved;
-
-# else
-
- return canonicalize_filename_mode (name, CAN_EXISTING);
-
-# endif /* !HAVE_RESOLVEPATH */
-}
-#endif /* !HAVE_CANONICALIZE_FILE_NAME */
-
/* Return true if we've already seen the triple, <FILENAME, dev, ino>.
If *HT is not initialized, initialize it. */
static bool
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index 817edd5..b6f2341 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,17 +1,15 @@
-#serial 12
+#serial 13
-# Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2006, 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.
# Written by Jim Meyering.
-AC_DEFUN([AC_FUNC_CANONICALIZE_FILE_NAME],
+AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE],
[
AC_LIBOBJ([canonicalize])
-
AC_CHECK_HEADERS_ONCE([sys/param.h])
- AC_CHECK_DECLS_ONCE([canonicalize_file_name])
- AC_CHECK_FUNCS_ONCE([canonicalize_file_name resolvepath])
])
diff --git a/modules/canonicalize b/modules/canonicalize
index e24be3d..467ff10 100644
--- a/modules/canonicalize
+++ b/modules/canonicalize
@@ -1,5 +1,5 @@
Description:
-Return the canonical absolute name of a given file.
+Return the canonical name of a file, with various levels of resolution.
Files:
lib/canonicalize.h
@@ -11,7 +11,6 @@ Depends-on:
areadlink-with-size
errno
file-set
-filenamecat
hash-triple
memmove
sys_stat
@@ -19,7 +18,7 @@ xalloc
xgetcwd
configure.ac:
-AC_FUNC_CANONICALIZE_FILE_NAME
+gl_FUNC_CANONICALIZE_FILENAME_MODE
gl_MODULE_INDICATOR([canonicalize])
Makefile.am:
diff --git a/modules/canonicalize-tests b/modules/canonicalize-tests
index e8dfec7..9c539c6 100644
--- a/modules/canonicalize-tests
+++ b/modules/canonicalize-tests
@@ -3,6 +3,7 @@ tests/test-canonicalize.sh
tests/test-canonicalize.c
Depends-on:
+canonicalize-lgpl
configure.ac:
AC_CHECK_FUNCS_ONCE([symlink])
--
1.6.3.2
>From 1a13f821aad1c258c442dfa88517d236fb872a6e Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 15:44:15 -0600
Subject: [PATCH 4/6] canonicalize-lgpl: use native realpath if it works
* lib/canonicalize-lgpl.c (realpath): Protect definition with
FUNC_REALPATH_WORKS.
(MAXSYMLINKS): Also consult SYMLOOP_MAX.
* lib/stdlib.in.h (canonicalize_file_name, realpath): Declare.
* modules/stdlib (Makefile.am): Substitute witnesses.
* m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide defaults.
* modules/canonicalize-lgpl (Files): Drop canonicalize.h.
(Depends-on): Add extensions, stdlib.
(configure.ac): Mention functions we provide.
(Include): Mention <stdlib.h>.
* m4/canonicalize-lgpl.m4 (gl_CANONICALIZE_LGPL_SEPARATE): No need
to check for declaration of canonicalize_file_name.
(gl_CANONICALIZE_LGPL): Likewise. Don't define realpath, but do
check that it works. Set gnulib witnesses.
(gl_PREREQ_CANONICALIZE_LGPL): Assume unistd.h.
* lib/canonicalize.h (canonicalize_file_name): Drop declaration.
* tests/test-canonicalize-lgpl.c (includes): Use <stdlib.h>.
* NEWS: Document this.
* doc/glibc-functions/canonicalize_file_name.texi
(canonicalize_file_name): Likewise.
* doc/posix-functions/realpath.texi (realpath): Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 23 +++++++++++++++
NEWS | 4 ++
doc/glibc-functions/canonicalize_file_name.texi | 8 ++--
doc/posix-functions/realpath.texi | 21 ++++++++-----
lib/canonicalize-lgpl.c | 22 ++++++--------
lib/canonicalize.h | 15 +---------
lib/stdlib.in.h | 27 +++++++++++++++++
m4/canonicalize-lgpl.m4 | 35 +++++++++++++++++++----
m4/stdlib_h.m4 | 7 ++++-
modules/canonicalize-lgpl | 9 ++++--
modules/stdlib | 5 +++
tests/test-canonicalize-lgpl.c | 3 +-
12 files changed, 129 insertions(+), 50 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 2f3f391..c06de6f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,28 @@
2009-09-10 Eric Blake <address@hidden>
+ canonicalize-lgpl: use native realpath if it works
+ * lib/canonicalize-lgpl.c (realpath): Protect definition with
+ FUNC_REALPATH_WORKS.
+ (MAXSYMLINKS): Also consult SYMLOOP_MAX.
+ * lib/stdlib.in.h (canonicalize_file_name, realpath): Declare.
+ * modules/stdlib (Makefile.am): Substitute witnesses.
+ * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Provide defaults.
+ * modules/canonicalize-lgpl (Files): Drop canonicalize.h.
+ (Depends-on): Add extensions, stdlib.
+ (configure.ac): Mention functions we provide.
+ (Include): Mention <stdlib.h>.
+ * m4/canonicalize-lgpl.m4 (gl_CANONICALIZE_LGPL_SEPARATE): No need
+ to check for declaration of canonicalize_file_name.
+ (gl_CANONICALIZE_LGPL): Likewise. Don't define realpath, but do
+ check that it works. Set gnulib witnesses.
+ (gl_PREREQ_CANONICALIZE_LGPL): Assume unistd.h.
+ * lib/canonicalize.h (canonicalize_file_name): Drop declaration.
+ * tests/test-canonicalize-lgpl.c (includes): Use <stdlib.h>.
+ * NEWS: Document this.
+ * doc/glibc-functions/canonicalize_file_name.texi
+ (canonicalize_file_name): Likewise.
+ * doc/posix-functions/realpath.texi (realpath): Likewise.
+
canonicalize: leave canonicalize_file_name to canonicalize-lgpl
* m4/canonicalize.m4 (AC_FUNC_CANONICALIZE_FILE_NAME): Rename...
(gl_FUNC_CANONICALIZE_FILENAME_MODE): ...to this. Drop unneeded
diff --git a/NEWS b/NEWS
index 1ccdaea..9b67d72 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,10 @@ User visible incompatible changes
Date Modules Changes
+2009-09-10 canonicalize-lgpl
+ The include file is changed from "canonicalize.h"
+ to <stdlib.h>.
+
2009-09-10 canonicalize This module no longer provides
canonicalize_file_name; use the canonicalize-lgpl
module for that.
diff --git a/doc/glibc-functions/canonicalize_file_name.texi b/doc/glibc-
functions/canonicalize_file_name.texi
index c19a9b1..f034f81 100644
--- a/doc/glibc-functions/canonicalize_file_name.texi
+++ b/doc/glibc-functions/canonicalize_file_name.texi
@@ -2,15 +2,15 @@ canonicalize_file_name
@subsection @code{canonicalize_file_name}
@findex canonicalize_file_name
-Gnulib module: ---
+Gnulib module: canonicalize-lgpl
Portability problems fixed by Gnulib:
@itemize
address@hidden
+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.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
address@hidden
-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.
@end itemize
diff --git a/doc/posix-functions/realpath.texi b/doc/posix-
functions/realpath.texi
index 2515254..01ce781 100644
--- a/doc/posix-functions/realpath.texi
+++ b/doc/posix-functions/realpath.texi
@@ -4,22 +4,27 @@ realpath
POSIX specification: @url
{http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html}
-Gnulib module: ---
+Gnulib module: canonicalize-lgpl
Portability problems fixed by Gnulib:
@itemize
address@hidden
+This function is missing on some platforms:
+mingw, BeOS.
address@hidden
+This function does not allow for a NULL @samp{resolved} parameter on
+some platforms:
+Solaris.
address@hidden
+This function does not always return an absolute path on some
+platforms:
+Solaris.
@end itemize
Portability problems not fixed by Gnulib:
@itemize
@item
-This function is missing on some platforms:
-mingw, BeOS.
address@hidden
This function does not allow to determine the required size of output buffer;
+the use of a non-NULL @samp{resolved} buffer is non-portable, since
PATH_MAX --- if it is defined --- is nothing more than a guess.
@end itemize
-
-Extension: Gnulib provides a module @samp{canonicalize-lgpl} that defines a
-function @code{canonicalize_file_name} that is like @code{realpath} but without
-size limitations.
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index c8f313e..3c134b0 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -17,24 +17,16 @@
#include <config.h>
-/* Avoid a clash of our rpl_realpath() function with the prototype in
- <stdlib.h> on Solaris 2.5.1. */
-#undef realpath
-
#if !HAVE_CANONICALIZE_FILE_NAME || defined _LIBC
#include <alloca.h>
/* Specification. */
-#include "canonicalize.h"
+#include <stdlib.h>
#include <stddef.h>
-#include <stdlib.h>
#include <string.h>
-
-#if HAVE_UNISTD_H || defined _LIBC
-# include <unistd.h>
-#endif
+#include <unistd.h>
#include <limits.h>
@@ -42,7 +34,11 @@
# include <sys/param.h>
#endif
#ifndef MAXSYMLINKS
-# define MAXSYMLINKS 20
+# ifdef SYMLOOP_MAX
+# define MAXSYMLINKS SYMLOOP_MAX
+# else
+# define MAXSYMLINKS 20
+# endif
#endif
#include <sys/stat.h>
@@ -60,7 +56,7 @@
# define compat_symbol(lib, local, symbol, version)
# define weak_alias(local, symbol)
# define __canonicalize_file_name canonicalize_file_name
-# define __realpath rpl_realpath
+# define __realpath realpath
# include "pathmax.h"
# include "malloca.h"
# if HAVE_GETCWD
@@ -80,6 +76,7 @@
# endif
#endif
+#if !FUNC_REALPATH_WORKS
/* 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
@@ -328,6 +325,7 @@ error:
#ifdef _LIBC
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
#endif
+#endif /* !FUNC_REALPATH_WORKS */
#if SHLIB_COMPAT(libc, GLIBC_2_0, GLIBC_2_3)
diff --git a/lib/canonicalize.h b/lib/canonicalize.h
index 8ca4fb4..9ab2826 100644
--- a/lib/canonicalize.h
+++ b/lib/canonicalize.h
@@ -1,5 +1,5 @@
/* Return the canonical absolute name of a given file.
- Copyright (C) 1996-2007 Free Software Foundation, Inc.
+ Copyright (C) 1996-2007, 2009 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -17,7 +17,6 @@
#ifndef CANONICALIZE_H_
# define CANONICALIZE_H_
-# if GNULIB_CANONICALIZE
enum canonicalize_mode_t
{
/* All components must exist. */
@@ -36,17 +35,5 @@ typedef enum canonicalize_mode_t canonicalize_mode_t;
whether components must exist depends on the canonicalize_mode_t
argument. */
char *canonicalize_filename_mode (const char *, canonicalize_mode_t);
-# endif
-
-# if HAVE_DECL_CANONICALIZE_FILE_NAME
-# include <stdlib.h>
-# else
-/* Return a malloc'd string containing the canonical absolute name of
- the named file. If any file name component does not exist or is a
- symlink to a nonexistent file, return NULL. A canonical name does
- not contain any `.', `..' components nor any repeated file name
- separators ('/') or symlinks. */
-char *canonicalize_file_name (const char *);
-# endif
#endif /* !CANONICALIZE_H_ */
diff --git a/lib/stdlib.in.h b/lib/stdlib.in.h
index f05962e..13088ac 100644
--- a/lib/stdlib.in.h
+++ b/lib/stdlib.in.h
@@ -115,6 +115,18 @@ extern void * calloc (size_t nmemb, size_t size);
calloc (n, s))
#endif
+#if @GNULIB_CANONICALIZE_FILE_NAME@
+# if address@hidden@
+extern char *canonicalize_file_name (const char *name);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef canonicalize_file_name
+# define canonicalize_file_name(n) \
+ (GL_LINK_WARNING ("canonicalize_file_name is unportable - " \
+ "use gnulib module canonicalize-lgpl for portability"), \
+ canonicalize_file_name (n))
+#endif
+
#if @GNULIB_GETLOADAVG@
# if address@hidden@
/* Store max(NELEM,3) load average numbers in LOADAVG[].
@@ -292,6 +304,21 @@ extern void * realloc (void *ptr, size_t size);
realloc (p, s))
#endif
+#if @GNULIB_REALPATH@
+# if @REPLACE_REALPATH@
+# define realpath rpl_realpath
+# endif
+# if address@hidden@ || @REPLACE_REALPATH@
+extern char *realpath (const char *name, char *resolved);
+# endif
+#elif defined GNULIB_POSIXCHECK
+# undef realpath
+# define realpath(n,r) \
+ (GL_LINK_WARNING ("realpath is unportable - " \
+ "use gnulib module canonicalize-lgpl for portability"), \
+ realpath (n, r))
+#endif
+
#if @GNULIB_RPMATCH@
# if address@hidden@
/* Test a user response to a question.
diff --git a/m4/canonicalize-lgpl.m4 b/m4/canonicalize-lgpl.m4
index 3a8ee2f..85f7d76 100644
--- a/m4/canonicalize-lgpl.m4
+++ b/m4/canonicalize-lgpl.m4
@@ -8,12 +8,35 @@ AC_DEFUN([gl_CANONICALIZE_LGPL],
[
dnl Do this replacement check manually because the file name is shorter
dnl than the function name.
- AC_CHECK_DECLS_ONCE([canonicalize_file_name])
- AC_CHECK_FUNCS_ONCE([canonicalize_file_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])
- AC_DEFINE([realpath], [rpl_realpath],
- [Define to a replacement function name for realpath().])
+ 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 *name = realpath ("conftest.a", NULL);
+ return !(name && *name == '/');
+ ]])
+ ], [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
])
@@ -22,7 +45,7 @@ AC_DEFUN([gl_CANONICALIZE_LGPL],
# (no AC_LIBOBJ).
AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
[
- AC_CHECK_DECLS_ONCE([canonicalize_file_name])
+ AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS])
AC_CHECK_FUNCS_ONCE([canonicalize_file_name])
gl_PREREQ_CANONICALIZE_LGPL
])
@@ -30,6 +53,6 @@ AC_DEFUN([gl_CANONICALIZE_LGPL_SEPARATE],
# Prerequisites of lib/canonicalize-lgpl.c.
AC_DEFUN([gl_PREREQ_CANONICALIZE_LGPL],
[
- AC_CHECK_HEADERS_ONCE([sys/param.h unistd.h])
+ AC_CHECK_HEADERS_ONCE([sys/param.h])
AC_CHECK_FUNCS_ONCE([getcwd readlink])
])
diff --git a/m4/stdlib_h.m4 b/m4/stdlib_h.m4
index b7cf18c..9ac7383 100644
--- a/m4/stdlib_h.m4
+++ b/m4/stdlib_h.m4
@@ -1,4 +1,4 @@
-# stdlib_h.m4 serial 17
+# stdlib_h.m4 serial 18
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,
@@ -35,6 +35,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
[
GNULIB_ATOLL=0; AC_SUBST([GNULIB_ATOLL])
GNULIB_CALLOC_POSIX=0; AC_SUBST([GNULIB_CALLOC_POSIX])
+ GNULIB_CANONICALIZE_FILE_NAME=0; AC_SUBST([GNULIB_CANONICALIZE_FILE_NAME])
GNULIB_GETLOADAVG=0; AC_SUBST([GNULIB_GETLOADAVG])
GNULIB_GETSUBOPT=0; AC_SUBST([GNULIB_GETSUBOPT])
GNULIB_MALLOC_POSIX=0; AC_SUBST([GNULIB_MALLOC_POSIX])
@@ -44,6 +45,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
GNULIB_PUTENV=0; AC_SUBST([GNULIB_PUTENV])
GNULIB_RANDOM_R=0; AC_SUBST([GNULIB_RANDOM_R])
GNULIB_REALLOC_POSIX=0; AC_SUBST([GNULIB_REALLOC_POSIX])
+ GNULIB_REALPATH=0; AC_SUBST([GNULIB_REALPATH])
GNULIB_RPMATCH=0; AC_SUBST([GNULIB_RPMATCH])
GNULIB_SETENV=0; AC_SUBST([GNULIB_SETENV])
GNULIB_STRTOD=0; AC_SUBST([GNULIB_STRTOD])
@@ -53,6 +55,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
dnl Assume proper GNU behavior unless another module says otherwise.
HAVE_ATOLL=1; AC_SUBST([HAVE_ATOLL])
HAVE_CALLOC_POSIX=1; AC_SUBST([HAVE_CALLOC_POSIX])
+ HAVE_CANONICALIZE_FILE_NAME=1; AC_SUBST([HAVE_CANONICALIZE_FILE_NAME])
HAVE_DECL_GETLOADAVG=1; AC_SUBST([HAVE_DECL_GETLOADAVG])
HAVE_GETSUBOPT=1; AC_SUBST([HAVE_GETSUBOPT])
HAVE_MALLOC_POSIX=1; AC_SUBST([HAVE_MALLOC_POSIX])
@@ -60,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])
@@ -70,6 +74,7 @@ AC_DEFUN([gl_STDLIB_H_DEFAULTS],
HAVE_UNSETENV=1; AC_SUBST([HAVE_UNSETENV])
REPLACE_MKSTEMP=0; AC_SUBST([REPLACE_MKSTEMP])
REPLACE_PUTENV=0; AC_SUBST([REPLACE_PUTENV])
+ REPLACE_REALPATH=0; AC_SUBST([REPLACE_REALPATH])
REPLACE_STRTOD=0; AC_SUBST([REPLACE_STRTOD])
VOID_UNSETENV=0; AC_SUBST([VOID_UNSETENV])
])
diff --git a/modules/canonicalize-lgpl b/modules/canonicalize-lgpl
index b462c61..88d1602 100644
--- a/modules/canonicalize-lgpl
+++ b/modules/canonicalize-lgpl
@@ -1,26 +1,29 @@
Description:
-Canonical absolute file name (LGPLed version).
+realpath, canonical_file_name: Provide canonical absolute file name
Files:
-lib/canonicalize.h
lib/canonicalize-lgpl.c
m4/canonicalize-lgpl.m4
Depends-on:
alloca-opt
+extensions
malloca
memmove
pathmax
readlink
+stdlib
configure.ac:
gl_CANONICALIZE_LGPL
gl_MODULE_INDICATOR([canonicalize-lgpl])
+gl_STDLIB_MODULE_INDICATOR([canonicalize_file_name])
+gl_STDLIB_MODULE_INDICATOR([realpath])
Makefile.am:
Include:
-"canonicalize.h"
+<stdlib.h>
License:
LGPLv2+
diff --git a/modules/stdlib b/modules/stdlib
index b15f9ae..7de2cb0 100644
--- a/modules/stdlib
+++ b/modules/stdlib
@@ -28,6 +28,7 @@ stdlib.h: stdlib.in.h
-e 's|@''NEXT_STDLIB_H''@|$(NEXT_STDLIB_H)|g' \
-e 's|@''GNULIB_ATOLL''@|$(GNULIB_ATOLL)|g' \
-e 's|@''GNULIB_CALLOC_POSIX''@|$(GNULIB_CALLOC_POSIX)|g' \
+ -
e 's|@''GNULIB_CANONICALIZE_FILE_NAME''@|$(GNULIB_CANONICALIZE_FILE_NAME)|g' \
-e 's|@''GNULIB_GETLOADAVG''@|$(GNULIB_GETLOADAVG)|g' \
-e 's|@''GNULIB_GETSUBOPT''@|$(GNULIB_GETSUBOPT)|g' \
-e 's|@''GNULIB_MALLOC_POSIX''@|$(GNULIB_MALLOC_POSIX)|g' \
@@ -37,6 +38,7 @@ stdlib.h: stdlib.in.h
-e 's|@''GNULIB_PUTENV''@|$(GNULIB_PUTENV)|g' \
-e 's|@''GNULIB_RANDOM_R''@|$(GNULIB_RANDOM_R)|g' \
-e 's|@''GNULIB_REALLOC_POSIX''@|$(GNULIB_REALLOC_POSIX)|g' \
+ -e 's|@''GNULIB_REALPATH''@|$(GNULIB_REALPATH)|g' \
-e 's|@''GNULIB_RPMATCH''@|$(GNULIB_RPMATCH)|g' \
-e 's|@''GNULIB_SETENV''@|$(GNULIB_SETENV)|g' \
-e 's|@''GNULIB_STRTOD''@|$(GNULIB_STRTOD)|g' \
@@ -45,6 +47,7 @@ stdlib.h: stdlib.in.h
-e 's|@''GNULIB_UNSETENV''@|$(GNULIB_UNSETENV)|g' \
-e 's|@''HAVE_ATOLL''@|$(HAVE_ATOLL)|g' \
-e 's|@''HAVE_CALLOC_POSIX''@|$(HAVE_CALLOC_POSIX)|g' \
+ -
e 's|@''HAVE_CANONICALIZE_FILE_NAME''@|$(HAVE_CANONICALIZE_FILE_NAME)|g' \
-e 's|@''HAVE_DECL_GETLOADAVG''@|$(HAVE_DECL_GETLOADAVG)|g' \
-e 's|@''HAVE_GETSUBOPT''@|$(HAVE_GETSUBOPT)|g' \
-e 's|@''HAVE_MALLOC_POSIX''@|$(HAVE_MALLOC_POSIX)|g' \
@@ -53,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' \
@@ -63,6 +67,7 @@ stdlib.h: stdlib.in.h
-e 's|@''HAVE_UNSETENV''@|$(HAVE_UNSETENV)|g' \
-e 's|@''REPLACE_MKSTEMP''@|$(REPLACE_MKSTEMP)|g' \
-e 's|@''REPLACE_PUTENV''@|$(REPLACE_PUTENV)|g' \
+ -e 's|@''REPLACE_REALPATH''@|$(REPLACE_REALPATH)|g' \
-e 's|@''REPLACE_STRTOD''@|$(REPLACE_STRTOD)|g' \
-e 's|@''VOID_UNSETENV''@|$(VOID_UNSETENV)|g' \
-e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 87e5e46..74fbbbb 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -18,10 +18,9 @@
#include <config.h>
-#include "canonicalize.h"
+#include <stdlib.h>
#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#define ASSERT(expr) \
--
1.6.3.2
>From 645e6bfd9f9b9916f7af480b786e42a4da7fe177 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 16:28:38 -0600
Subject: [PATCH 5/6] canonicalize: don't lose errno
* lib/canonicalize.c (canonicalize_filename_mode): Protect errno
over calls to free.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 4 ++++
lib/canonicalize.c | 9 +++++----
2 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index c06de6f..71e6413 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2009-09-10 Eric Blake <address@hidden>
+ canonicalize: don't lose errno
+ * lib/canonicalize.c (canonicalize_filename_mode): Protect errno
+ over calls to free.
+
canonicalize-lgpl: use native realpath if it works
* lib/canonicalize-lgpl.c (realpath): Protect definition with
FUNC_REALPATH_WORKS.
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index 1312ff2..2ad063e 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -82,6 +82,7 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
char const *rname_limit;
size_t extra_len = 0;
Hash_table *ht = NULL;
+ int saved_errno;
if (name == NULL)
{
@@ -187,11 +188,10 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
the same symlink,NAME pair twice does indicate a loop. */
if (seen_triple (&ht, name, &st))
{
- __set_errno (ELOOP);
if (can_mode == CAN_MISSING)
continue;
- else
- goto error;
+ saved_errno = ELOOP;
+ goto error;
}
buf = areadlink_with_size (rname, st.st_size);
@@ -235,7 +235,7 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
{
if (!S_ISDIR (st.st_mode) && *end && (can_mode != CAN_MISSING))
{
- errno = ENOTDIR;
+ saved_errno = ENOTDIR;
goto error;
}
}
@@ -255,5 +255,6 @@ error:
free (rname);
if (ht)
hash_free (ht);
+ errno = saved_errno;
return NULL;
}
--
1.6.3.2
>From 71657333973cc0a4814c2c2fc2f76c648a937d28 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Thu, 10 Sep 2009 17:21:09 -0600
Subject: [PATCH 6/6] canonicalize: honor // if distinct from /
* modules/canonicalize (Files): Add double-slash-root.m4.
* m4/canonicalize.m4 (gl_FUNC_CANONICALIZE_FILENAME_MODE): Add
dependency.
* lib/canonicalize.c (DOUBLE_SLASH_IS_DISTINCT_ROOT): Provide
fallback definition.
(canonicalize_filename_mode): Use it to protect //.
* tests/test-canonicalize.c (main): Test this.
* tests/test-canonicalize.sh (tmpfiles): Add another symlink.
* modules/canonicalize-tests (Depends-on): Add same-inode.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 11 +++++++++++
lib/canonicalize.c | 17 ++++++++++++++++-
m4/canonicalize.m4 | 3 ++-
modules/canonicalize | 1 +
modules/canonicalize-tests | 1 +
tests/test-canonicalize.c | 42 ++++++++++++++++++++++++++++++++++++++++++
tests/test-canonicalize.sh | 4 +++-
7 files changed, 76 insertions(+), 3 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 71e6413..5ad92e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
2009-09-10 Eric Blake <address@hidden>
+ canonicalize: honor // if distinct from /
+ * modules/canonicalize (Files): Add double-slash-root.m4.
+ * m4/canonicalize.m4 (gl_FUNC_CANONICALIZE_FILENAME_MODE): Add
+ dependency.
+ * lib/canonicalize.c (DOUBLE_SLASH_IS_DISTINCT_ROOT): Provide
+ fallback definition.
+ (canonicalize_filename_mode): Use it to protect //.
+ * tests/test-canonicalize.c (main): Test this.
+ * tests/test-canonicalize.sh (tmpfiles): Add another symlink.
+ * modules/canonicalize-tests (Depends-on): Add same-inode.
+
canonicalize: don't lose errno
* lib/canonicalize.c (canonicalize_filename_mode): Protect errno
over calls to free.
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index 2ad063e..0d06e45 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -44,6 +44,10 @@
#include "pathmax.h"
#include "areadlink.h"
+#ifndef DOUBLE_SLASH_IS_DISTINCT_ROOT
+# define DOUBLE_SLASH_IS_DISTINCT_ROOT 0
+#endif
+
/* Return true if we've already seen the triple, <FILENAME, dev, ino>.
If *HT is not initialized, initialize it. */
static bool
@@ -120,6 +124,8 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
rname_limit = rname + PATH_MAX;
rname[0] = '/';
dest = rname + 1;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && name[1] == '/')
+ *dest++ = '/';
}
for (start = name; *start; start = end)
@@ -141,6 +147,9 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
/* Back up to previous component, ignore if at root already. */
if (dest > rname + 1)
while ((--dest)[-1] != '/');
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
+ && *dest == '/')
+ dest++;
}
else
{
@@ -223,7 +232,11 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
name = end = memcpy (extra_buf, buf, n);
if (buf[0] == '/')
- dest = rname + 1; /* It's an absolute symlink */
+ {
+ dest = rname + 1; /* It's an absolute symlink */
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && buf[1] == '/')
+ *dest++ = '/';
+ }
else
/* Back up to previous component, ignore if at root already: */
if (dest > rname + 1)
@@ -243,6 +256,8 @@ canonicalize_filename_mode (const char *name,
canonicalize_mode_t can_mode)
}
if (dest > rname + 1 && dest[-1] == '/')
--dest;
+ if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1 && *dest == '/')
+ dest++;
*dest = '\0';
free (extra_buf);
diff --git a/m4/canonicalize.m4 b/m4/canonicalize.m4
index b6f2341..9b74e6e 100644
--- a/m4/canonicalize.m4
+++ b/m4/canonicalize.m4
@@ -1,4 +1,4 @@
-#serial 13
+#serial 14
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software
# Foundation, Inc.
@@ -10,6 +10,7 @@
AC_DEFUN([gl_FUNC_CANONICALIZE_FILENAME_MODE],
[
+ AC_REQUIRE([gl_DOUBLE_SLASH_ROOT])
AC_LIBOBJ([canonicalize])
AC_CHECK_HEADERS_ONCE([sys/param.h])
])
diff --git a/modules/canonicalize b/modules/canonicalize
index 467ff10..8cb62c9 100644
--- a/modules/canonicalize
+++ b/modules/canonicalize
@@ -6,6 +6,7 @@ lib/canonicalize.h
lib/canonicalize.c
lib/pathmax.h
m4/canonicalize.m4
+m4/double-slash-root.m4
Depends-on:
areadlink-with-size
diff --git a/modules/canonicalize-tests b/modules/canonicalize-tests
index 9c539c6..a97d1ed 100644
--- a/modules/canonicalize-tests
+++ b/modules/canonicalize-tests
@@ -4,6 +4,7 @@ tests/test-canonicalize.c
Depends-on:
canonicalize-lgpl
+same-inode
configure.ac:
AC_CHECK_FUNCS_ONCE([symlink])
diff --git a/tests/test-canonicalize.c b/tests/test-canonicalize.c
index f0212e0..c50a115 100644
--- a/tests/test-canonicalize.c
+++ b/tests/test-canonicalize.c
@@ -23,6 +23,9 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+
+#include "same-inode.h"
#define ASSERT(expr) \
do \
@@ -99,7 +102,12 @@ main ()
/* Check that a missing directory yields NULL. */
{
+ /* Cygwin realpath() handles .. incorrectly. */
+#ifdef __CYGWIN__
+ char *result1 = NULL;
+#else
char *result1 = canonicalize_file_name ("t-can.tmp/ouk/..");
+#endif
char *result2 = canonicalize_filename_mode ("t-can.tmp/ouk/..",
CAN_EXISTING);
ASSERT (result1 == NULL);
ASSERT (result2 == NULL);
@@ -159,5 +167,39 @@ main ()
free (result2);
}
+ /* Check that // is honored correctly. */
+ {
+ struct stat st1;
+ struct stat st2;
+ char *result1 = canonicalize_file_name ("//.");
+ char *result2 = canonicalize_filename_mode ("//.", CAN_EXISTING);
+ char *result3 = canonicalize_file_name ("t-can.tmp/droot");
+ char *result4 = canonicalize_filename_mode ("t-can.tmp/droot",
CAN_EXISTING);
+ ASSERT (result1);
+ ASSERT (result2);
+ ASSERT (result3);
+ ASSERT (result4);
+ ASSERT (stat ("/", &st1) == 0);
+ ASSERT (stat ("//", &st2) == 0);
+ if (SAME_INODE (st1, st2))
+ {
+ ASSERT (strcmp (result1, "/") == 0);
+ ASSERT (strcmp (result2, "/") == 0);
+ ASSERT (strcmp (result3, "/") == 0);
+ ASSERT (strcmp (result4, "/") == 0);
+ }
+ else
+ {
+ ASSERT (strcmp (result1, "//") == 0);
+ ASSERT (strcmp (result2, "//") == 0);
+ ASSERT (strcmp (result3, "//") == 0);
+ ASSERT (strcmp (result4, "//") == 0);
+ }
+ free (result1);
+ free (result2);
+ free (result3);
+ free (result4);
+ }
+
return 0;
}
diff --git a/tests/test-canonicalize.sh b/tests/test-canonicalize.sh
index 224ec86..5a0cc69 100755
--- a/tests/test-canonicalize.sh
+++ b/tests/test-canonicalize.sh
@@ -26,12 +26,14 @@ test "x$HAVE_SYMLINK" = xyes \
# resolution of which the code dereferences the same symlink (S)
# two different times with no actual loop. In addition, the
# second and fourth calls to readlink must operate on S.
+# Also, ensure we handle // correctly.
(cd t-can.tmp \
&& ln -s s p \
&& ln -s d s \
&& mkdir d \
&& echo > d/2 \
- && ln -s ../s/2 d/1
+ && ln -s ../s/2 d/1 \
+ && ln -s //.//.. droot
) || exit 1
./test-canonicalize${EXEEXT}
--
1.6.3.2
- canonicalize-lgpl bug, Eric Blake, 2009/09/10
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/10
- Re: canonicalize-lgpl bug, Jim Meyering, 2009/09/10
- Re: canonicalize-lgpl bug,
Eric Blake <=
- Re: canonicalize-lgpl bug, Jim Meyering, 2009/09/11
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/11
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/11
- Re: canonicalize-lgpl bug, Jim Meyering, 2009/09/16
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/16
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/17
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/17
- Re: canonicalize-lgpl bug, Jim Meyering, 2009/09/17
- Re: canonicalize-lgpl bug, Jim Meyering, 2009/09/18
- Re: canonicalize-lgpl bug, Eric Blake, 2009/09/18