Mercurial > hg > xemacs-beta
comparison src/realpath.c @ 412:697ef44129c6 r21-2-14
Import from CVS: tag r21-2-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:20:41 +0200 |
parents | de805c49cfc1 |
children | 11054d720c21 |
comparison
equal
deleted
inserted
replaced
411:12e008d41344 | 412:697ef44129c6 |
---|---|
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
21 Boston, MA 02111-1307, USA. */ | 21 Boston, MA 02111-1307, USA. */ |
22 | 22 |
23 /* Synched up with: Not in FSF. */ | 23 /* Synched up with: Not in FSF. */ |
24 | 24 |
25 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | 26 #include <config.h> |
27 #endif | |
26 | 28 |
27 #include <sys/types.h> | 29 #include <sys/types.h> |
30 #if defined(HAVE_UNISTD_H) || defined(STDC_HEADERS) | |
31 #include <unistd.h> | |
32 #endif | |
28 #include <stdio.h> | 33 #include <stdio.h> |
29 #include <string.h> | 34 #include <string.h> |
35 #ifdef _POSIX_VERSION | |
36 #include <limits.h> /* for PATH_MAX */ | |
37 #else | |
38 #include <sys/param.h> /* for MAXPATHLEN */ | |
39 #endif | |
30 #include <errno.h> | 40 #include <errno.h> |
31 #include <limits.h> | 41 #ifndef STDC_HEADERS |
32 | 42 extern int errno; |
33 #ifdef HAVE_UNISTD_H | 43 #endif |
34 #include <unistd.h> | 44 |
35 #endif | 45 #ifdef WINDOWSNT |
36 | |
37 #if defined (HAVE_SYS_PARAM_H) | |
38 #include <sys/param.h> | |
39 #endif | |
40 | |
41 #ifdef WIN32_NATIVE | |
42 #include <direct.h> | 46 #include <direct.h> |
43 #endif | 47 #endif |
44 | 48 |
45 #include <sys/stat.h> /* for S_IFLNK */ | 49 #include <sys/stat.h> /* for S_IFLNK */ |
46 | 50 |
47 #if !defined (HAVE_GETCWD) && defined (HAVE_GETWD) | |
48 #undef getcwd | |
49 #define getcwd(buffer, len) getwd (buffer) | |
50 #endif | |
51 | |
52 #ifndef PATH_MAX | 51 #ifndef PATH_MAX |
53 # if defined (_POSIX_PATH_MAX) | 52 #ifdef _POSIX_VERSION |
54 # define PATH_MAX _POSIX_PATH_MAX | 53 #define PATH_MAX _POSIX_PATH_MAX |
55 # elif defined (MAXPATHLEN) | 54 #else |
56 # define PATH_MAX MAXPATHLEN | 55 #ifdef MAXPATHLEN |
57 # else | 56 #define PATH_MAX MAXPATHLEN |
58 # define PATH_MAX 1024 | 57 #else |
59 # endif | 58 #define PATH_MAX 1024 |
59 #endif | |
60 #endif | |
60 #endif | 61 #endif |
61 | 62 |
62 #define MAX_READLINKS 32 | 63 #define MAX_READLINKS 32 |
63 | 64 |
64 char * xrealpath (const char *path, char resolved_path []); | 65 #ifdef __STDC__ |
65 char * | 66 char *xrealpath(const char *path, char resolved_path []) |
66 xrealpath (const char *path, char resolved_path []) | 67 #else |
68 char *xrealpath(path, resolved_path) | |
69 const char *path; | |
70 char resolved_path []; | |
71 #endif | |
67 { | 72 { |
68 char copy_path[PATH_MAX]; | 73 char copy_path[PATH_MAX]; |
69 char *new_path = resolved_path; | 74 char *new_path = resolved_path; |
70 char *max_path; | 75 char *max_path; |
71 #ifdef S_IFLNK | 76 #ifdef S_IFLNK |
73 char link_path[PATH_MAX]; | 78 char link_path[PATH_MAX]; |
74 int n; | 79 int n; |
75 #endif | 80 #endif |
76 | 81 |
77 /* Make a copy of the source path since we may need to modify it. */ | 82 /* Make a copy of the source path since we may need to modify it. */ |
78 strcpy (copy_path, path); | 83 strcpy(copy_path, path); |
79 path = copy_path; | 84 path = copy_path; |
80 max_path = copy_path + PATH_MAX - 2; | 85 max_path = copy_path + PATH_MAX - 2; |
81 #ifdef WIN32_NATIVE | 86 #ifdef WINDOWSNT |
82 /* | 87 /* |
83 ** In NT we have two different cases: (1) the path name begins | 88 ** In NT we have two different cases: (1) the path name begins |
84 ** with a drive letter, e.g., "C:"; and (2) the path name begins | 89 ** with a drive letter, e.g., "C:"; and (2) the path name begins |
85 ** with just a slash, which roots to the current drive. In the | 90 ** with just a slash, which roots to the current drive. In the |
86 ** first case we are going to leave things alone, in the second | 91 ** first case we are going to leave things alone, in the second |
102 ** No drive letter, but a beginning slash? Prepend the drive | 107 ** No drive letter, but a beginning slash? Prepend the drive |
103 ** letter... | 108 ** letter... |
104 */ | 109 */ |
105 else if (*path == '/') | 110 else if (*path == '/') |
106 { | 111 { |
107 getcwd (new_path, PATH_MAX - 1); | 112 getcwd(new_path, PATH_MAX - 1); |
108 new_path += 3; | 113 new_path += 3; |
109 path++; | 114 path++; |
110 } | 115 } |
111 | 116 |
112 /* | 117 /* |
113 ** Just a path name, prepend the current directory | 118 ** Just a path name, prepend the current directory |
114 */ | 119 */ |
115 else | 120 else |
116 { | 121 { |
117 getcwd (new_path, PATH_MAX - 1); | 122 getcwd(new_path, PATH_MAX - 1); |
118 new_path += strlen(new_path); | 123 new_path += strlen(new_path); |
119 if (new_path[-1] != '/') | 124 if (new_path[-1] != '/') |
120 *new_path++ = '/'; | 125 *new_path++ = '/'; |
121 } | 126 } |
122 | 127 |
123 #else | 128 #else |
124 /* If it's a relative pathname use getcwd for starters. */ | 129 /* If it's a relative pathname use getwd for starters. */ |
125 if (*path != '/') | 130 if (*path != '/') |
126 { | 131 { |
127 getcwd (new_path, PATH_MAX - 1); | 132 #ifdef HAVE_GETCWD |
133 getcwd(new_path, PATH_MAX - 1); | |
134 #else | |
135 getwd(new_path); | |
136 #endif | |
128 new_path += strlen(new_path); | 137 new_path += strlen(new_path); |
129 if (new_path[-1] != '/') | 138 if (new_path[-1] != '/') |
130 *new_path++ = '/'; | 139 *new_path++ = '/'; |
131 } | 140 } |
132 else | 141 else |
152 { | 161 { |
153 path++; | 162 path++; |
154 continue; | 163 continue; |
155 } | 164 } |
156 | 165 |
157 /* Handle ".." */ | 166 if (path[1] == '.') |
158 if (path[1] == '.' && | 167 { |
159 (path[2] == '\0' || path[2] == '/')) | 168 if (path[2] == '\0' || path[2] == '/') |
160 { | 169 { |
161 path += 2; | 170 path += 2; |
162 | 171 |
163 /* Ignore ".." at root. */ | 172 /* Ignore ".." at root. */ |
164 if (new_path == resolved_path + 1) | 173 if (new_path == resolved_path + 1) |
165 continue; | 174 continue; |
166 | 175 |
167 /* Handle ".." by backing up. */ | 176 /* Handle ".." by backing up. */ |
168 while ((--new_path)[-1] != '/') | 177 while ((--new_path)[-1] != '/') |
169 ; | 178 ; |
170 continue; | 179 continue; |
180 } | |
171 } | 181 } |
172 } | 182 } |
173 | 183 |
174 /* Safely copy the next pathname component. */ | 184 /* Safely copy the next pathname component. */ |
175 while (*path != '\0' && *path != '/') | 185 while (*path != '\0' && *path != '/') |
183 } | 193 } |
184 | 194 |
185 #ifdef S_IFLNK | 195 #ifdef S_IFLNK |
186 /* See if latest pathname component is a symlink. */ | 196 /* See if latest pathname component is a symlink. */ |
187 *new_path = '\0'; | 197 *new_path = '\0'; |
188 n = readlink (resolved_path, link_path, PATH_MAX - 1); | 198 n = readlink(resolved_path, link_path, PATH_MAX - 1); |
189 | 199 |
190 if (n < 0) | 200 if (n < 0) |
191 { | 201 { |
192 /* EINVAL means the file exists but isn't a symlink. */ | 202 /* EINVAL means the file exists but isn't a symlink. */ |
193 if (errno != EINVAL) | 203 if (errno != EINVAL) |