Hi,

Attached is a patch that fixes canonicalize_file_name for mingw.

I realise that it doesn't go so far as to stat each component,
so there is room for improvement.  The original is useless for
mingw, and this patch makes guile happy.

Greetings,
Jan.

-- 
Jan Nieuwenhuizen <jann...@gnu.org> | GNU LilyPond http://lilypond.org
Freelance IT http://JoyofSource.com | AvatarĀ®  http://AvatarAcademy.nl  
>From b53c12f8f3c861824582150c1b2ec6595a6e5965 Mon Sep 17 00:00:00 2001
From: Jan Nieuwenhuizen <jann...@gnu.org>
Date: Mon, 31 Jan 2011 21:38:57 +0100
Subject: [PATCH] Add an implementation of gnulib's canonicalize_file_name for mingw.

This marked the first sensible running of guile.exe (1.9) in wine.
---
 lib/canonicalize-lgpl.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/lib/canonicalize-lgpl.c b/lib/canonicalize-lgpl.c
index ec55f26..2464bad 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,81 @@ error:
   }
   return NULL;
 }
+
+#else /* __MINGW32__ */
+#include <direct.h>
+#include <windows.h>
+
+static char const*
+slashify (char const *str)
+{
+  char *p = (char*)str;
+  
+  while (*p)
+    {
+      if (*p == '\\')
+	*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;
+
+  strncpy (rpath, name, PATH_MAX);
+  size_t len = strlen (name);
+  if (len > PATH_MAX)
+    len = PATH_MAX;
+  rpath[len] = '\0';
+  
+  slashify (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 */
 
-- 
1.7.1

Reply via email to