2007-09-12 Marek Habersack <mhabersack@novell.com>
authorMarek Habersack <grendel@twistedcode.net>
Wed, 12 Sep 2007 17:50:25 +0000 (17:50 -0000)
committerMarek Habersack <grendel@twistedcode.net>
Wed, 12 Sep 2007 17:50:25 +0000 (17:50 -0000)
            * io-portability.c
            find_file and find_in_dir moved to utils/mono-io-portability.c

2007-09-12  Marek Habersack  <mhabersack@novell.com>

            * mono-io-portability.c:
            (find_in_dir): moved from io-layer/io-portability.c
            (mono_portability_find_file): moved find_file from
            io-layer/io-portability.c, renamed and made MONO_INTERNAL.

            * mono-io-portability.h:
            Added a prototype for mono_portability_find_file.

2007-09-12  Marek Habersack  <mhabersack@novell.com>

            * image.c (do_mono_image_open): if assembly file fails to open and
            MONO_IOMAP is in effect, try to find the path in a
            case-insensitive way.

svn path=/trunk/mono/; revision=85694

mono/io-layer/ChangeLog
mono/io-layer/io-portability.c
mono/metadata/ChangeLog
mono/metadata/image.c
mono/utils/ChangeLog
mono/utils/mono-io-portability.c
mono/utils/mono-io-portability.h

index 8ff8cbd39624dc7940f6a1c2023b94dd4877b147..c24fcfb3f2c98024a559171c7ca49e654355f9ff 100644 (file)
@@ -4,6 +4,7 @@
        utils/mono-io-portability.c
        Do not initialize portability helpers here, it's done in
        mono_runtime_init.
+       find_file and find_in_dir moved to utils/mono-io-portability.c
 
 2007-09-09  Robert Jordan  <robertj@gmx.net>
 
index 25b04ae7f238e02f2c28806acec5ede520972a24..290ce90e47e33b2d31c83bc3c6a5416006f45063 100644 (file)
 
 #undef DEBUG
 
-/* Returns newly allocated string, or NULL on failure */
-static gchar *find_in_dir (DIR *current, const gchar *name)
-{
-       struct dirent *entry;
-
-#ifdef DEBUG
-       g_message ("%s: looking for [%s]\n", __func__, name);
-#endif
-       
-       while((entry = readdir (current)) != NULL) {
-#ifdef DEBUGX
-               g_message ("%s: found [%s]\n", __func__, entry->d_name);
-#endif
-               
-               if (!g_ascii_strcasecmp (name, entry->d_name)) {
-                       char *ret;
-                       
-#ifdef DEBUG
-                       g_message ("%s: matched [%s] to [%s]\n", __func__,
-                                  entry->d_name, name);
-#endif
-
-                       ret = g_strdup (entry->d_name);
-                       closedir (current);
-                       return ret;
-               }
-       }
-       
-#ifdef DEBUG
-       g_message ("%s: returning NULL\n", __func__);
-#endif
-       
-       closedir (current);
-       
-       return(NULL);
-}
-
-/* Returns newly-allocated string or NULL on failure */
-static gchar *find_file (const gchar *pathname, gboolean last_exists)
-{
-       gchar *new_pathname, **components, **new_components;
-       int num_components = 0, component = 0;
-       DIR *scanning = NULL;
-
-       if (IS_PORTABILITY_NONE) {
-               return(NULL);
-       }
-
-       new_pathname = g_strdup (pathname);
-       
-#ifdef DEBUG
-       g_message ("%s: Finding [%s] last_exists: %s\n", __func__, pathname,
-                  last_exists?"TRUE":"FALSE");
-#endif
-       
-       if (last_exists &&
-           access (new_pathname, F_OK) == 0) {
-#ifdef DEBUG
-               g_message ("%s: Found it without doing anything\n", __func__);
-#endif
-               return(new_pathname);
-       }
-       
-       /* First turn '\' into '/' and strip any drive letters */
-       g_strdelimit (new_pathname, "\\", '/');
-
-#ifdef DEBUG
-       g_message ("%s: Fixed slashes, now have [%s]\n", __func__,
-                  new_pathname);
-#endif
-       
-       if (IS_PORTABILITY_DRIVE &&
-           g_ascii_isalpha (new_pathname[0]) &&
-           (new_pathname[1] == ':')) {
-               int len = strlen (new_pathname);
-               
-               g_memmove (new_pathname, new_pathname+2, len - 2);
-               new_pathname[len - 2] = '\0';
-               
-#ifdef DEBUG
-               g_message ("%s: Stripped drive letter, now looking for [%s]\n",
-                          __func__, new_pathname);
-#endif
-       }
-       
-       if (last_exists &&
-           access (new_pathname, F_OK) == 0) {
-#ifdef DEBUG
-               g_message ("%s: Found it\n", __func__);
-#endif
-               
-               return(new_pathname);
-       }
-
-       /* OK, have to work harder.  Take each path component in turn
-        * and do a case-insensitive directory scan for it
-        */
-
-       if (!(IS_PORTABILITY_CASE)) {
-               g_free (new_pathname);
-               return(NULL);
-       }
-
-       components = g_strsplit (new_pathname, "/", 0);
-       if (components == NULL) {
-               /* This shouldn't happen */
-               g_free (new_pathname);
-               return(NULL);
-       }
-       
-       while(components[num_components] != NULL) {
-               num_components++;
-       }
-       g_free (new_pathname);
-       
-       if (num_components == 0){
-               return NULL;
-       }
-       
-
-       new_components = (gchar **)g_new0 (gchar **, num_components + 1);
-
-       if (num_components > 1) {
-               if (strcmp (components[0], "") == 0) {
-                       /* first component blank, so start at / */
-                       scanning = opendir ("/");
-                       if (scanning == NULL) {
-#ifdef DEBUG
-                               g_message ("%s: opendir 1 error: %s", __func__,
-                                          g_strerror (errno));
-#endif
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               
-                       new_components[component++] = g_strdup ("");
-               } else {
-                       DIR *current;
-                       gchar *entry;
-               
-                       current = opendir (".");
-                       if (current == NULL) {
-#ifdef DEBUG
-                               g_message ("%s: opendir 2 error: %s", __func__,
-                                          g_strerror (errno));
-#endif
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               
-                       entry = find_in_dir (current, components[0]);
-                       if (entry == NULL) {
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               
-                       scanning = opendir (entry);
-                       if (scanning == NULL) {
-#ifdef DEBUG
-                               g_message ("%s: opendir 3 error: %s", __func__,
-                                          g_strerror (errno));
-#endif
-                               g_free (entry);
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               
-                       new_components[component++] = entry;
-               }
-       } else {
-               if (last_exists) {
-                       if (strcmp (components[0], "") == 0) {
-                               /* First and only component blank */
-                               new_components[component++] = g_strdup ("");
-                       } else {
-                               DIR *current;
-                               gchar *entry;
-                               
-                               current = opendir (".");
-                               if (current == NULL) {
-#ifdef DEBUG
-                                       g_message ("%s: opendir 4 error: %s",
-                                                  __func__,
-                                                  g_strerror (errno));
-#endif
-                                       g_strfreev (new_components);
-                                       g_strfreev (components);
-                                       return(NULL);
-                               }
-                               
-                               entry = find_in_dir (current, components[0]);
-                               if (entry == NULL) {
-                                       g_strfreev (new_components);
-                                       g_strfreev (components);
-                                       return(NULL);
-                               }
-                               
-                               new_components[component++] = entry;
-                       }
-               } else {
-                               new_components[component++] = g_strdup (components[0]);
-               }
-       }
-
-#ifdef DEBUG
-       g_message ("%s: Got first entry: [%s]\n", __func__, new_components[0]);
-#endif
-
-       g_assert (component == 1);
-       
-       for(; component < num_components; component++) {
-               gchar *entry;
-               gchar *path_so_far;
-               
-               if (!last_exists &&
-                   component == num_components -1) {
-                       entry = g_strdup (components[component]);
-                       closedir (scanning);
-               } else {
-                       entry = find_in_dir (scanning, components[component]);
-                       if (entry == NULL) {
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               }
-               
-               new_components[component] = entry;
-               
-               if (component < num_components -1) {
-                       path_so_far = g_strjoinv ("/", new_components);
-
-                       scanning = opendir (path_so_far);
-                       g_free (path_so_far);
-                       if (scanning == NULL) {
-                               g_strfreev (new_components);
-                               g_strfreev (components);
-                               return(NULL);
-                       }
-               }
-       }
-       
-       g_strfreev (components);
-
-       new_pathname = g_strjoinv ("/", new_components);
-
-#ifdef DEBUG
-       g_message ("%s: pathname [%s] became [%s]\n", __func__, pathname,
-                  new_pathname);
-#endif
-       
-       g_strfreev (new_components);
-
-       if ((last_exists &&
-            access (new_pathname, F_OK) == 0) ||
-           (!last_exists)) {
-               return(new_pathname);
-       }
-       
-       g_free (new_pathname);
-       return(NULL);
-}
-
 int _wapi_open (const char *pathname, int flags, mode_t mode)
 {
        int fd;
        gchar *located_filename;
        
        if (flags & O_CREAT) {
-               located_filename = find_file (pathname, FALSE);
+               located_filename = mono_portability_find_file (pathname, FALSE);
                if (located_filename == NULL) {
                        fd = open (pathname, flags, mode);
                } else {
@@ -316,7 +49,7 @@ int _wapi_open (const char *pathname, int flags, mode_t mode)
                    (errno == ENOENT || errno == ENOTDIR) &&
                    IS_PORTABILITY_SET) {
                        int saved_errno = errno;
-                       located_filename = find_file (pathname, TRUE);
+                       located_filename = mono_portability_find_file (pathname, TRUE);
                        
                        if (located_filename == NULL) {
                                errno = saved_errno;
@@ -341,7 +74,7 @@ int _wapi_access (const char *pathname, int mode)
            (errno == ENOENT || errno == ENOTDIR) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (pathname, TRUE);
+               gchar *located_filename = mono_portability_find_file (pathname, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -364,7 +97,7 @@ int _wapi_chmod (const char *pathname, mode_t mode)
            (errno == ENOENT || errno == ENOTDIR) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (pathname, TRUE);
+               gchar *located_filename = mono_portability_find_file (pathname, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -387,7 +120,7 @@ int _wapi_utime (const char *filename, const struct utimbuf *buf)
            errno == ENOENT &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (filename, TRUE);
+               gchar *located_filename = mono_portability_find_file (filename, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -410,7 +143,7 @@ int _wapi_unlink (const char *pathname)
            (errno == ENOENT || errno == ENOTDIR || errno == EISDIR) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (pathname, TRUE);
+               gchar *located_filename = mono_portability_find_file (pathname, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -427,7 +160,7 @@ int _wapi_unlink (const char *pathname)
 int _wapi_rename (const char *oldpath, const char *newpath)
 {
        int ret;
-       gchar *located_newpath = find_file (newpath, FALSE);
+       gchar *located_newpath = mono_portability_find_file (newpath, FALSE);
        
        if (located_newpath == NULL) {
                ret = rename (oldpath, newpath);
@@ -439,7 +172,7 @@ int _wapi_rename (const char *oldpath, const char *newpath)
                     errno == ENOENT || errno == ENOTDIR || errno == EXDEV) &&
                    IS_PORTABILITY_SET) {
                        int saved_errno = errno;
-                       gchar *located_oldpath = find_file (oldpath, TRUE);
+                       gchar *located_oldpath = mono_portability_find_file (oldpath, TRUE);
                        
                        if (located_oldpath == NULL) {
                                g_free (located_oldpath);
@@ -467,7 +200,7 @@ int _wapi_stat (const char *path, struct stat *buf)
            (errno == ENOENT || errno == ENOTDIR) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (path, TRUE);
+               gchar *located_filename = mono_portability_find_file (path, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -490,7 +223,7 @@ int _wapi_lstat (const char *path, struct stat *buf)
            (errno == ENOENT || errno == ENOTDIR) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (path, TRUE);
+               gchar *located_filename = mono_portability_find_file (path, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -507,7 +240,7 @@ int _wapi_lstat (const char *path, struct stat *buf)
 int _wapi_mkdir (const char *pathname, mode_t mode)
 {
        int ret;
-       gchar *located_filename = find_file (pathname, FALSE);
+       gchar *located_filename = mono_portability_find_file (pathname, FALSE);
        
        if (located_filename == NULL) {
                ret = mkdir (pathname, mode);
@@ -528,7 +261,7 @@ int _wapi_rmdir (const char *pathname)
            (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (pathname, TRUE);
+               gchar *located_filename = mono_portability_find_file (pathname, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -551,7 +284,7 @@ int _wapi_chdir (const char *path)
            (errno == ENOENT || errno == ENOTDIR || errno == ENAMETOOLONG) &&
            IS_PORTABILITY_SET) {
                int saved_errno = errno;
-               gchar *located_filename = find_file (path, TRUE);
+               gchar *located_filename = mono_portability_find_file (path, TRUE);
                
                if (located_filename == NULL) {
                        errno = saved_errno;
@@ -617,7 +350,7 @@ GDir *_wapi_g_dir_open (const gchar *path, guint flags, GError **error)
             (*error)->code == G_FILE_ERROR_NOTDIR ||
             (*error)->code == G_FILE_ERROR_NAMETOOLONG) &&
            IS_PORTABILITY_SET) {
-               gchar *located_filename = find_file (path, TRUE);
+               gchar *located_filename = mono_portability_find_file (path, TRUE);
                GError *tmp_error = NULL;
                
                if (located_filename == NULL) {
index 41836eb1da207ad8bd97b3fb13d0d47d7c5e7156..26a23797bbb7c6cb0d5271c82dea9a1f6edd3551 100644 (file)
@@ -4,6 +4,10 @@
 
 2007-09-12  Marek Habersack  <mhabersack@novell.com>
 
+       * image.c (do_mono_image_open): if assembly file fails to open and
+       MONO_IOMAP is in effect, try to find the path in a
+       case-insensitive way.
+
        * appdomain.c (mono_runtime_init): do not install postload hooks -
        tests show that MS.NET doesn't use anything of that sort to
        trigger the AppDomain.AssemblyResolve event.
index a90ddb0033e26b7bb49d4dc420a95cceb5ac94c4..61c9e312550cc4a9ab477854815e36ebc87b8a3b 100644 (file)
@@ -26,6 +26,7 @@
 #include <mono/io-layer/io-layer.h>
 #include <mono/utils/mono-logger.h>
 #include <mono/utils/mono-path.h>
+#include <mono/utils/mono-io-portability.h>
 #include <mono/metadata/class-internals.h>
 #include <mono/metadata/assembly.h>
 #include <sys/types.h>
@@ -889,9 +890,19 @@ do_mono_image_open (const char *fname, MonoImageOpenStatus *status,
        struct stat stat_buf;
 
        if ((filed = fopen (fname, "rb")) == NULL){
-               if (status)
-                       *status = MONO_IMAGE_ERROR_ERRNO;
-               return NULL;
+               if (IS_PORTABILITY_SET) {
+                       gchar *ffname = mono_portability_find_file (fname, FALSE);
+                       if (ffname) {
+                               filed = fopen (ffname, "rb");
+                               g_free (ffname);
+                       }
+               }
+
+               if (filed == NULL) {
+                       if (status)
+                               *status = MONO_IMAGE_ERROR_ERRNO;
+                       return NULL;
+               }
        }
 
        if (fstat (fileno (filed), &stat_buf)) {
index af100d2bf1748f1e772a60f6a9c149dabb329513..217a5e064aa825eb5a01c4ed9ef1e3cc6b7ada8d 100644 (file)
@@ -6,9 +6,13 @@ Wed Sep 12 15:15:47 CEST 2007 Paolo Molaro <lupus@ximian.com>
 2007-09-12  Marek Habersack  <mhabersack@novell.com>
 
        * mono-io-portability.c: added. Moved options_init from io-layer.
+       (find_in_dir): moved from io-layer/io-portability.c
+       (mono_portability_find_file): moved find_file from
+       io-layer/io-portability.c, renamed and made MONO_INTERNAL.
 
        * mono-io-portability.h: added. Contains declarations utility
        functions and acros for checking whether MONO_IOMAP is in effect.
+       Added a prototype for mono_portability_find_file.
 
 2007-09-09  Zoltan Varga  <vargaz@gmail.com>
 
index e8e6c3fd0b92e204f99381789b56d590932d198e..ee963221f3cd5c2fc388ac01805d752d6d5ac4a1 100644 (file)
@@ -1,6 +1,8 @@
 #include "config.h"
 
-#include <glib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
 #include <mono/utils/mono-io-portability.h>
 
 int __mono_io_portability_helpers = PORTABILITY_UNKNOWN;
@@ -43,3 +45,270 @@ void mono_portability_helpers_init (void)
                 }
         }
 }
+
+/* Returns newly allocated string, or NULL on failure */
+static gchar *find_in_dir (DIR *current, const gchar *name)
+{
+       struct dirent *entry;
+
+#ifdef DEBUG
+       g_message ("%s: looking for [%s]\n", __func__, name);
+#endif
+       
+       while((entry = readdir (current)) != NULL) {
+#ifdef DEBUGX
+               g_message ("%s: found [%s]\n", __func__, entry->d_name);
+#endif
+               
+               if (!g_ascii_strcasecmp (name, entry->d_name)) {
+                       char *ret;
+                       
+#ifdef DEBUG
+                       g_message ("%s: matched [%s] to [%s]\n", __func__,
+                                  entry->d_name, name);
+#endif
+
+                       ret = g_strdup (entry->d_name);
+                       closedir (current);
+                       return ret;
+               }
+       }
+       
+#ifdef DEBUG
+       g_message ("%s: returning NULL\n", __func__);
+#endif
+       
+       closedir (current);
+       
+       return(NULL);
+}
+
+/* Returns newly-allocated string or NULL on failure */
+gchar *mono_portability_find_file (const gchar *pathname, gboolean last_exists)
+{
+       gchar *new_pathname, **components, **new_components;
+       int num_components = 0, component = 0;
+       DIR *scanning = NULL;
+
+       if (IS_PORTABILITY_NONE) {
+               return(NULL);
+       }
+
+       new_pathname = g_strdup (pathname);
+       
+#ifdef DEBUG
+       g_message ("%s: Finding [%s] last_exists: %s\n", __func__, pathname,
+                  last_exists?"TRUE":"FALSE");
+#endif
+       
+       if (last_exists &&
+           access (new_pathname, F_OK) == 0) {
+#ifdef DEBUG
+               g_message ("%s: Found it without doing anything\n", __func__);
+#endif
+               return(new_pathname);
+       }
+       
+       /* First turn '\' into '/' and strip any drive letters */
+       g_strdelimit (new_pathname, "\\", '/');
+
+#ifdef DEBUG
+       g_message ("%s: Fixed slashes, now have [%s]\n", __func__,
+                  new_pathname);
+#endif
+       
+       if (IS_PORTABILITY_DRIVE &&
+           g_ascii_isalpha (new_pathname[0]) &&
+           (new_pathname[1] == ':')) {
+               int len = strlen (new_pathname);
+               
+               g_memmove (new_pathname, new_pathname+2, len - 2);
+               new_pathname[len - 2] = '\0';
+               
+#ifdef DEBUG
+               g_message ("%s: Stripped drive letter, now looking for [%s]\n",
+                          __func__, new_pathname);
+#endif
+       }
+       
+       if (last_exists &&
+           access (new_pathname, F_OK) == 0) {
+#ifdef DEBUG
+               g_message ("%s: Found it\n", __func__);
+#endif
+               
+               return(new_pathname);
+       }
+
+       /* OK, have to work harder.  Take each path component in turn
+        * and do a case-insensitive directory scan for it
+        */
+
+       if (!(IS_PORTABILITY_CASE)) {
+               g_free (new_pathname);
+               return(NULL);
+       }
+
+       components = g_strsplit (new_pathname, "/", 0);
+       if (components == NULL) {
+               /* This shouldn't happen */
+               g_free (new_pathname);
+               return(NULL);
+       }
+       
+       while(components[num_components] != NULL) {
+               num_components++;
+       }
+       g_free (new_pathname);
+       
+       if (num_components == 0){
+               return NULL;
+       }
+       
+
+       new_components = (gchar **)g_new0 (gchar **, num_components + 1);
+
+       if (num_components > 1) {
+               if (strcmp (components[0], "") == 0) {
+                       /* first component blank, so start at / */
+                       scanning = opendir ("/");
+                       if (scanning == NULL) {
+#ifdef DEBUG
+                               g_message ("%s: opendir 1 error: %s", __func__,
+                                          g_strerror (errno));
+#endif
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               
+                       new_components[component++] = g_strdup ("");
+               } else {
+                       DIR *current;
+                       gchar *entry;
+               
+                       current = opendir (".");
+                       if (current == NULL) {
+#ifdef DEBUG
+                               g_message ("%s: opendir 2 error: %s", __func__,
+                                          g_strerror (errno));
+#endif
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               
+                       entry = find_in_dir (current, components[0]);
+                       if (entry == NULL) {
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               
+                       scanning = opendir (entry);
+                       if (scanning == NULL) {
+#ifdef DEBUG
+                               g_message ("%s: opendir 3 error: %s", __func__,
+                                          g_strerror (errno));
+#endif
+                               g_free (entry);
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               
+                       new_components[component++] = entry;
+               }
+       } else {
+               if (last_exists) {
+                       if (strcmp (components[0], "") == 0) {
+                               /* First and only component blank */
+                               new_components[component++] = g_strdup ("");
+                       } else {
+                               DIR *current;
+                               gchar *entry;
+                               
+                               current = opendir (".");
+                               if (current == NULL) {
+#ifdef DEBUG
+                                       g_message ("%s: opendir 4 error: %s",
+                                                  __func__,
+                                                  g_strerror (errno));
+#endif
+                                       g_strfreev (new_components);
+                                       g_strfreev (components);
+                                       return(NULL);
+                               }
+                               
+                               entry = find_in_dir (current, components[0]);
+                               if (entry == NULL) {
+                                       g_strfreev (new_components);
+                                       g_strfreev (components);
+                                       return(NULL);
+                               }
+                               
+                               new_components[component++] = entry;
+                       }
+               } else {
+                               new_components[component++] = g_strdup (components[0]);
+               }
+       }
+
+#ifdef DEBUG
+       g_message ("%s: Got first entry: [%s]\n", __func__, new_components[0]);
+#endif
+
+       g_assert (component == 1);
+       
+       for(; component < num_components; component++) {
+               gchar *entry;
+               gchar *path_so_far;
+               
+               if (!last_exists &&
+                   component == num_components -1) {
+                       entry = g_strdup (components[component]);
+                       closedir (scanning);
+               } else {
+                       entry = find_in_dir (scanning, components[component]);
+                       if (entry == NULL) {
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               }
+               
+               new_components[component] = entry;
+               
+               if (component < num_components -1) {
+                       path_so_far = g_strjoinv ("/", new_components);
+
+                       scanning = opendir (path_so_far);
+                       g_free (path_so_far);
+                       if (scanning == NULL) {
+                               g_strfreev (new_components);
+                               g_strfreev (components);
+                               return(NULL);
+                       }
+               }
+       }
+       
+       g_strfreev (components);
+
+       new_pathname = g_strjoinv ("/", new_components);
+
+#ifdef DEBUG
+       g_message ("%s: pathname [%s] became [%s]\n", __func__, pathname,
+                  new_pathname);
+#endif
+       
+       g_strfreev (new_components);
+
+       if ((last_exists &&
+            access (new_pathname, F_OK) == 0) ||
+           (!last_exists)) {
+               return(new_pathname);
+       }
+       
+       g_free (new_pathname);
+       return(NULL);
+}
index fc9de6ba7d5ba1181e2b09273eae91b44cf202a3..e3e16213bebcd6f2f452c16a787af86b975841a6 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __MONO_IO_PORTABILITY_H
 #define __MONO_IO_PORTABILITY_H
 
+#include <glib.h>
 #include <mono/utils/mono-compiler.h>
 
 enum {
@@ -10,7 +11,8 @@ enum {
         PORTABILITY_CASE        = 0x04,
 };
 
-void mono_portability_helpers_init () MONO_INTERNAL;
+void mono_portability_helpers_init (void) MONO_INTERNAL;
+gchar *mono_portability_find_file (const gchar *pathname, gboolean last_exists) MONO_INTERNAL;
 
 extern int __mono_io_portability_helpers MONO_INTERNAL;