>From e8f8f8dc840bfd2c960f86a5e6799420ec755e8c Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen
Date: Tue, 1 Feb 2011 14:47:50 +0100
Subject: [PATCH 6/6] canonicalize-lgpl: Add an implementation for canonicalize_file_name.
2011-02-01 Jan Nieuwenhuizen
* lib/canonicalize-lgpl.c (__realpath)[__MINGW32__]: Add an
implementation for canonicalize_file_name. This marked the first
running of guile.exe (1.9) in wine.
* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Do not abort
on `nonexistent/..'; in Windows that works fine.
---
ChangeLog | 9 ++++
lib/canonicalize-lgpl.c | 87 ++++++++++++++++++++++++++++++++++++++++
tests/test-canonicalize-lgpl.c | 8 ++++
3 files changed, 104 insertions(+), 0 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 86217e6..112f02e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
2011-02-01 Jan Nieuwenhuizen
+ * lib/canonicalize-lgpl.c (__realpath)[__MINGW32__]: Add an
+ implementation for canonicalize_file_name. This marked the first
+ running of guile.exe (1.9) in wine.
+
+ * tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Do not abort
+ on `nonexistent/..'; in Windows that works fine.
+
+2011-02-01 Jan Nieuwenhuizen
+
* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Add basic sanity
checks for mingw along with debug printing to demonstrate brokenness.
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 9bfb44f..3c22195 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -84,6 +84,9 @@
#endif
#if !FUNC_REALPATH_WORKS || defined _LIBC
+
+#ifndef __MINGW32__
+
/* 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
@@ -342,6 +345,90 @@ error:
}
return NULL;
}
+
+#else /* __MINGW32__ */
+#include
+#include
+#include
+
+static char const *
+slashify (char const *str)
+{
+ char *p = (char*)str;
+
+ while (*p)
+ {
+ if (*p == '\\')
+ *p = '/';
+ p++;
+ }
+ return str;
+}
+
+static char *
+strlower (char *str)
+{
+ char *p = str;
+ while (*p)
+ {
+ *p = (char)tolower (*p);
+ p++;
+ }
+ return str;
+}
+
+char *
+__realpath (const char *name, char *resolved)
+{
+ char *rpath = NULL;
+
+ if (name == NULL)
+ {
+ /* As per Single Unix Specification V2 we must return an error if
+ either parameter is a null pointer. We extend this to allow
+ the RESOLVED parameter to be NULL in case the we are expected to
+ allocate the room for the return value. */
+ __set_errno (EINVAL);
+ return NULL;
+ }
+
+ if (name[0] == '\0')
+ {
+ /* As per Single Unix Specification V2 we must return an error if
+ the name argument points to an empty string. */
+ __set_errno (ENOENT);
+ return NULL;
+ }
+
+ if (resolved == NULL)
+ {
+ rpath = malloc (PATH_MAX + 1);
+ if (rpath == NULL)
+ {
+ /* It's easier to set errno to ENOMEM than to rely on the
+ 'malloc-posix' gnulib module. */
+ errno = ENOMEM;
+ return NULL;
+ }
+ }
+ else
+ rpath = resolved;
+
+ GetFullPathName (name, PATH_MAX, rpath, NULL);
+ slashify (rpath);
+ strlower (rpath);
+ struct stat st;
+ if (lstat (rpath, &st) < 0)
+ {
+ if (resolved == NULL)
+ free (rpath);
+ return NULL;
+ }
+ return rpath;
+}
+
+#endif /* __MINGW32__ */
+
versioned_symbol (libc, __realpath, realpath, GLIBC_2_3);
#endif /* !FUNC_REALPATH_WORKS || defined _LIBC */
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index 18f0005..ff7664d 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -98,9 +98,17 @@ main (void)
{
char *result;
errno = 0;
+ result = canonicalize_file_name (BASE "/zzz");
+ ASSERT (result == NULL);
+ ASSERT (errno == ENOENT);
result = canonicalize_file_name (BASE "/zzz/..");
+#ifndef __MINGW32__
ASSERT (result == NULL);
ASSERT (errno == ENOENT);
+#else /* __MINGW32__ */
+ /* Windows is OK with asking for: non-existent/.. */
+ ASSERT (result != NULL);
+#endif /* __MINGW32__ */
}
#ifdef __MINGW32__
--
1.7.1