#include <errno.h>
#include <string.h>
#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
/* This is only needed for the mono_path_canonicalize code, MAXSYMLINKS, could be moved */
+#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
+#endif
#include "mono-path.h"
+/* Embedded systems lack MAXSYMLINKS */
+#ifndef MAXSYMLINKS
+#define MAXSYMLINKS 3
+#endif
+
/* 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)
{
g_free (tmpdir);
}
+#ifdef HOST_WIN32
+ g_strdelimit (abspath, "/", '\\');
+#endif
abspath = g_strreverse (abspath);
backc = 0;
lastpos = pos + 1;
pos = strchr (lastpos, 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;
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
}