X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-path.c;h=f87c9f39bb3ea0764d1493166e5d9598d75a11ee;hb=f6b8e1f10d5cd18826aad50e5a2b8d2aabf3222a;hp=05065f0710165aaefe8907eda5dfba2f05dd1aad;hpb=1c2dafec93184d177f3d08236a35fe32ac3c2171;p=mono.git diff --git a/mono/utils/mono-path.c b/mono/utils/mono-path.c index 05065f07101..f87c9f39bb3 100644 --- a/mono/utils/mono-path.c +++ b/mono/utils/mono-path.c @@ -30,6 +30,11 @@ /* Resolves '..' and '.' references in a path. If the path provided is relative, * it will be relative to the current directory */ + +/* For Native Client, the above is not true. Since there is no getcwd we fill */ +/* in the file being passed in relative to '.' and don't resolve it */ + +/* There are a couple of tests for this method in mono/test/mono-path.cs */ gchar * mono_path_canonicalize (const char *path) { @@ -44,7 +49,7 @@ mono_path_canonicalize (const char *path) g_free (tmpdir); } -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 g_strdelimit (abspath, "/", '\\'); #endif abspath = g_strreverse (abspath); @@ -73,25 +78,39 @@ mono_path_canonicalize (const char *path) pos = strchr (lastpos, G_DIR_SEPARATOR); } -#ifdef PLATFORM_WIN32 /* For UNC paths the first '\' is removed. */ - if (*(lastpos-1) == G_DIR_SEPARATOR && *(lastpos-2) == G_DIR_SEPARATOR) +#ifdef HOST_WIN32 + /* Avoid removing the first '\' for UNC paths. We must make sure that it's indeed an UNC path + by checking if the \\ pair happens exactly at the end of the string. + */ + if (*(lastpos-1) == G_DIR_SEPARATOR && *(lastpos-2) == G_DIR_SEPARATOR && *lastpos == 0) lastpos = lastpos-1; #endif if (dest != lastpos) strcpy (dest, lastpos); - return g_strreverse (abspath); + + g_strreverse (abspath); + + /* We strip away all trailing dir separators. This is not correct for the root directory, + * since we'll return an empty string, so re-append a dir separator if there is none in the + * result */ + if (strchr (abspath, G_DIR_SEPARATOR) == NULL) { + int len = strlen (abspath); + abspath = (gchar *) g_realloc (abspath, len + 2); + abspath [len] = G_DIR_SEPARATOR; + abspath [len+1] = 0; + } + + return abspath; } /* * This ensures that the path that we store points to the final file * not a path to a symlink. */ -gchar * -mono_path_resolve_symlinks (const char *path) +#if !defined(PLATFORM_NO_SYMLINKS) +static gchar * +resolve_symlink (const char *path) { -#if PLATFORM_WIN32 - return mono_path_canonicalize (path); -#else char *p, *concat, *dir; char buffer [PATH_MAX+1]; int n, iterations = 0; @@ -120,6 +139,39 @@ mono_path_resolve_symlinks (const char *path) g_free (concat); } while (iterations < MAXSYMLINKS); + return p; +} +#endif + +gchar * +mono_path_resolve_symlinks (const char *path) +{ +#if defined(PLATFORM_NO_SYMLINKS) + return mono_path_canonicalize (path); +#else + gchar **split = g_strsplit (path, G_DIR_SEPARATOR_S, -1); + gchar *p = g_strdup (""); + int i; + + for (i = 0; split [i] != NULL; i++) { + gchar *tmp = NULL; + + // resolve_symlink of "" goes into canonicalize which resolves to cwd + if (strcmp (split [i], "") != 0) { + tmp = g_strdup_printf ("%s%s", p, split [i]); + g_free (p); + p = resolve_symlink (tmp); + g_free (tmp); + } + + if (split [i+1] != NULL) { + tmp = g_strdup_printf ("%s%s", p, G_DIR_SEPARATOR_S); + g_free (p); + p = tmp; + } + } + + g_strfreev (split); return p; #endif }