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)