X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-path.c;h=88b5d25a71904ff89e0923b1b7f967034f0b3c34;hb=6f76efaedfbbd4be65d20073b7389c59111cf7d8;hp=99e82ce71ae337ebee7efad7fead01fc6d7ec23d;hpb=27ae9063e5d655b4512f11baa4bcbcc9348f34de;p=mono.git diff --git a/mono/utils/mono-path.c b/mono/utils/mono-path.c index 99e82ce71ae..88b5d25a719 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) { @@ -39,12 +44,17 @@ mono_path_canonicalize (const char *path) if (g_path_is_absolute (path)) { abspath = g_strdup (path); } else { +#ifdef __native_client__ + gchar *tmpdir = "."; + abspath = g_build_filename (tmpdir, path, NULL); +#else gchar *tmpdir = g_get_current_dir (); abspath = g_build_filename (tmpdir, path, NULL); g_free (tmpdir); +#endif } -#ifdef PLATFORM_WIN32 +#ifdef HOST_WIN32 g_strdelimit (abspath, "/", '\\'); #endif abspath = g_strreverse (abspath); @@ -73,25 +83,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 = 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 defined(PLATFORM_NO_SYMLINKS) - return mono_path_canonicalize (path); -#else char *p, *concat, *dir; char buffer [PATH_MAX+1]; int n, iterations = 0; @@ -120,6 +144,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 }