X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-io-portability.c;h=54c6320d2b6f6a08bc8fc2fe249f315bbde8cac8;hb=67cdb994067c13b3fabf40c50029e18ac5351d37;hp=0f50172ef4ce4c0c6863568a882ddbb5a1cbe6da;hpb=7790e3db2cb7858cab7c59c056609c22f83c4b71;p=mono.git diff --git a/mono/utils/mono-io-portability.c b/mono/utils/mono-io-portability.c index 0f50172ef4c..54c6320d2b6 100644 --- a/mono/utils/mono-io-portability.c +++ b/mono/utils/mono-io-portability.c @@ -4,38 +4,27 @@ #ifdef HAVE_UNISTD_H #include #endif +#include #include +#include -#ifdef PLATFORM_WIN32 -int __mono_io_portability_helpers = PORTABILITY_NONE; - -void -mono_portability_helpers_init (void) -{ -} - -gchar * -mono_portability_find_file (const gchar *pathname, gboolean last_exists) -{ - g_assert_not_reached(); - return NULL; -} - -#else +#ifndef DISABLE_PORTABILITY #include -int __mono_io_portability_helpers = PORTABILITY_UNKNOWN; +int mono_io_portability_helpers = PORTABILITY_UNKNOWN; + +static inline gchar *mono_portability_find_file_internal (GString **report, const gchar *pathname, gboolean last_exists); void mono_portability_helpers_init (void) { const gchar *env; - if (__mono_io_portability_helpers != PORTABILITY_UNKNOWN) + if (mono_io_portability_helpers != PORTABILITY_UNKNOWN) return; - __mono_io_portability_helpers = PORTABILITY_NONE; - + mono_io_portability_helpers = PORTABILITY_NONE; + env = g_getenv ("MONO_IOMAP"); if (env != NULL) { /* parse the environment setting and set up some vars @@ -55,15 +44,14 @@ void mono_portability_helpers_init (void) options[i]); #endif if (!strncasecmp (options[i], "drive", 5)) { - __mono_io_portability_helpers |= PORTABILITY_DRIVE; + mono_io_portability_helpers |= PORTABILITY_DRIVE; } else if (!strncasecmp (options[i], "case", 4)) { - __mono_io_portability_helpers |= PORTABILITY_CASE; + mono_io_portability_helpers |= PORTABILITY_CASE; } else if (!strncasecmp (options[i], "all", 3)) { - __mono_io_portability_helpers |= (PORTABILITY_DRIVE | - PORTABILITY_CASE); - } + mono_io_portability_helpers |= (PORTABILITY_DRIVE | PORTABILITY_CASE); + } } - } + } } /* Returns newly allocated string, or NULL on failure */ @@ -103,17 +91,66 @@ static gchar *find_in_dir (DIR *current, const gchar *name) return(NULL); } -/* Returns newly-allocated string or NULL on failure */ +static inline void append_report (GString **report, const gchar *format, ...) +{ + va_list ap; + if (!*report) + *report = g_string_new (""); + + va_start (ap, format); + g_string_append_vprintf (*report, format, ap); + va_end (ap); +} + +static inline void do_mono_profiler_iomap (GString **report, const char *pathname, const char *new_pathname) +{ + char *rep = NULL; + GString *tmp = report ? *report : NULL; + + if (tmp) { + if (tmp->len > 0) + rep = g_string_free (tmp, FALSE); + else + g_string_free (tmp, TRUE); + *report = NULL; + } + + mono_profiler_iomap (rep, pathname, new_pathname); + g_free (rep); +} + gchar *mono_portability_find_file (const gchar *pathname, gboolean last_exists) +{ + GString *report = NULL; + gchar *ret; + + if (!pathname || !pathname [0]) + return NULL; + ret = mono_portability_find_file_internal (&report, pathname, last_exists); + + if (report) + g_string_free (report, TRUE); + + return ret; +} + +/* Returns newly-allocated string or NULL on failure */ +static inline gchar *mono_portability_find_file_internal (GString **report, const gchar *pathname, gboolean last_exists) { gchar *new_pathname, **components, **new_components; int num_components = 0, component = 0; DIR *scanning = NULL; + size_t len; + gboolean drive_stripped = FALSE; + gboolean do_report = (mono_profiler_get_events () & MONO_PROFILE_IOMAP_EVENTS) != 0; if (IS_PORTABILITY_NONE) { return(NULL); } + if (do_report) + append_report (report, " - Requested file path: '%s'\n", pathname); + new_pathname = g_strdup (pathname); #ifdef DEBUG @@ -144,19 +181,34 @@ gchar *mono_portability_find_file (const gchar *pathname, gboolean last_exists) g_memmove (new_pathname, new_pathname+2, len - 2); new_pathname[len - 2] = '\0'; - + + if (do_report) { + append_report (report, " - Stripped drive letter.\n"); + drive_stripped = TRUE; + } #ifdef DEBUG g_message ("%s: Stripped drive letter, now looking for [%s]\n", __func__, new_pathname); #endif } - + + len = strlen (new_pathname); + if (len > 1 && new_pathname [len - 1] == '/') { + new_pathname [len - 1] = 0; +#ifdef DEBUG + g_message ("%s: requested name had a trailing /, rewritten to '%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 - + if (do_report && drive_stripped) + do_mono_profiler_iomap (report, pathname, new_pathname); + return(new_pathname); } @@ -326,12 +378,13 @@ gchar *mono_portability_find_file (const gchar *pathname, gboolean last_exists) if ((last_exists && access (new_pathname, F_OK) == 0) || (!last_exists)) { + if (do_report && strcmp (pathname, new_pathname) != 0) + do_mono_profiler_iomap (report, pathname, new_pathname); + return(new_pathname); } - + g_free (new_pathname); return(NULL); } - - #endif