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
17 /* This is only needed for the mono_path_canonicalize code, MAXSYMLINKS, could be moved */
18 #include <sys/param.h>
20 #include "mono-path.h"
22 /* Resolves '..' and '.' references in a path. If the path provided is relative,
23 * it will be relative to the current directory */
25 mono_path_canonicalize (const char *path
)
27 gchar
*abspath
, *pos
, *lastpos
, *dest
;
30 if (g_path_is_absolute (path
)) {
31 abspath
= g_strdup (path
);
33 gchar
*tmpdir
= g_get_current_dir ();
34 abspath
= g_build_filename (tmpdir
, path
, NULL
);
38 abspath
= g_strreverse (abspath
);
41 dest
= lastpos
= abspath
;
42 pos
= strchr (lastpos
, G_DIR_SEPARATOR
);
45 int len
= pos
- lastpos
;
46 if (len
== 1 && lastpos
[0] == '.') {
48 } else if (len
== 2 && lastpos
[0] == '.' && lastpos
[1] == '.') {
55 /* The two strings can overlap */
56 memmove (dest
, lastpos
, len
+ 1);
61 pos
= strchr (lastpos
, G_DIR_SEPARATOR
);
64 if (dest
!= lastpos
) strcpy (dest
, lastpos
);
65 return g_strreverse (abspath
);
69 * This ensures that the path that we store points to the final file
70 * not a path to a symlink.
73 mono_path_resolve_symlinks (const char *path
)
76 return mono_path_canonicalize (path
);
78 char *p
, *concat
, *dir
;
79 char buffer
[PATH_MAX
+1];
80 int n
, iterations
= 0;
85 n
= readlink (p
, buffer
, sizeof (buffer
)-1);
88 p
= mono_path_canonicalize (copy
);
94 if (!g_path_is_absolute (buffer
)) {
95 dir
= g_path_get_dirname (p
);
96 concat
= g_build_filename (dir
, buffer
, NULL
);
99 concat
= g_strdup (buffer
);
102 p
= mono_path_canonicalize (concat
);
104 } while (iterations
< MAXSYMLINKS
);