>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