2 * mono-path.c: Routines for handling path names.
5 * Gonzalo Paniagua Javier (gonzalo@novell.com)
6 * Miguel de Icaza (miguel@novell.com)
8 * (C) 2006 Novell, Inc. http://www.novell.com
19 /* This is only needed for the mono_path_canonicalize code, MAXSYMLINKS, could be moved */
20 #ifdef HAVE_SYS_PARAM_H
21 #include <sys/param.h>
24 #include "mono-path.h"
26 /* Resolves '..' and '.' references in a path. If the path provided is relative,
27 * it will be relative to the current directory */
29 mono_path_canonicalize (const char *path)
31 gchar *abspath, *pos, *lastpos, *dest;
34 if (g_path_is_absolute (path)) {
35 abspath = g_strdup (path);
37 gchar *tmpdir = g_get_current_dir ();
38 abspath = g_build_filename (tmpdir, path, NULL);
42 abspath = g_strreverse (abspath);
45 dest = lastpos = abspath;
46 pos = strchr (lastpos, G_DIR_SEPARATOR);
49 int len = pos - lastpos;
50 if (len == 1 && lastpos [0] == '.') {
52 } else if (len == 2 && lastpos [0] == '.' && lastpos [1] == '.') {
59 /* The two strings can overlap */
60 memmove (dest, lastpos, len + 1);
65 pos = strchr (lastpos, G_DIR_SEPARATOR);
68 if (dest != lastpos) strcpy (dest, lastpos);
69 return g_strreverse (abspath);
73 * This ensures that the path that we store points to the final file
74 * not a path to a symlink.
77 mono_path_resolve_symlinks (const char *path)
80 return mono_path_canonicalize (path);
82 char *p, *concat, *dir;
83 char buffer [PATH_MAX+1];
84 int n, iterations = 0;
89 n = readlink (p, buffer, sizeof (buffer)-1);
92 p = mono_path_canonicalize (copy);
98 if (!g_path_is_absolute (buffer)) {
99 dir = g_path_get_dirname (p);
100 concat = g_build_filename (dir, buffer, NULL);
103 concat = g_strdup (buffer);
106 p = mono_path_canonicalize (concat);
108 } while (iterations < MAXSYMLINKS);