* lib/canonicalize-lgpl.c (filesystem_name)[__MINGW32__]: New static
function.
(realpath_stk)[__MINGW32__]: Use it to return correct canonicalized
casing.
* tests/test-canonicalize-lgpl.c (main)[__MINGW32__]: Test it.
---
lib/canonicalize-lgpl.c| 37 ++
tests/test-canonicalize-lgpl.c | 12 +++
2 files changed, 49 insertions(+)
diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index 92e9639720..baabcbdc25 100644
--- a/lib/canonicalize-lgpl.c
+++ b/lib/canonicalize-lgpl.c
@@ -41,6 +41,11 @@
#include
#include
+#if __MINGW32__
+#include
+#include
+#endif
+
#ifdef _LIBC
# include
# define GCC_LINT 1
@@ -180,6 +185,33 @@ get_path_max (void)
return path_max < 0 ? 1024 : path_max <= IDX_MAX ? path_max : IDX_MAX;
}
+#if __MINGW32__
+/* Return the basename of NAME as found on the filesystem, which may
+ or may not canonicalize the casing, or NULL if not found. */
+static char *
+filesystem_name (char const *name)
+{
+ char base_buf[PATH_MAX];
+ strcpy (base_buf, name);
+ char *base = basename (base_buf);
+
+ int select_base (struct dirent const* entry)
+ {
+return strcasecmp (entry->d_name, base) == 0;
+ }
+
+ char dir_buf[PATH_MAX];
+ strcpy (dir_buf, name);
+ char *dir = dirname (dir_buf);
+
+ struct dirent **name_list;
+ int i = scandir (dir, &name_list, select_base, NULL);
+ if (i == 1)
+return name_list[0]->d_name;
+ return NULL;
+}
+#endif
+
/* Act like __realpath (see below), with an additional argument
rname_buf that can be used as temporary storage.
@@ -322,6 +354,11 @@ realpath_stk (const char *name, char *resolved,
{
buf = link_buffer.data;
idx_t bufsize = link_buffer.length;
+#if __MINGW32__
+ char *fname = filesystem_name (rname);
+ if (fname)
+strcpy (rname + strlen (rname) - strlen (fname), fname);
+#endif
n = __readlink (rname, buf, bufsize - 1);
if (n < bufsize - 1)
break;
diff --git a/tests/test-canonicalize-lgpl.c b/tests/test-canonicalize-lgpl.c
index c0a5a55150..cf41a2a628 100644
--- a/tests/test-canonicalize-lgpl.c
+++ b/tests/test-canonicalize-lgpl.c
@@ -279,6 +279,18 @@ main (void)
free (result2);
}
+#if __MINGW32__
+ /* Check that \\ are changed into / and casing is canonicalized. */
+ {
+int fd = creat (BASE "/MinGW", 0600);
+ASSERT (0 <= fd);
+ASSERT (close (fd) == 0);
+
+char *result = canonicalize_file_name (BASE "\\mingw");
+ASSERT (strcmp (result, BASE "/MinGW");
+free (result);
+ }
+#endif
/* Cleanup. */
ASSERT (remove (BASE "/droot") == 0);