aboutsummaryrefslogtreecommitdiff
path: root/libbb/xreadlink.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libbb/xreadlink.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 2682f6975..fc10a2939 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -17,6 +17,7 @@
17 * NOTE: This function returns a malloced char* that you will have to free 17 * NOTE: This function returns a malloced char* that you will have to free
18 * yourself. 18 * yourself.
19 */ 19 */
20#if !ENABLE_PLATFORM_MINGW32
20char* FAST_FUNC xmalloc_readlink(const char *path) 21char* FAST_FUNC xmalloc_readlink(const char *path)
21{ 22{
22 enum { GROWBY = 80 }; /* how large we will grow strings by */ 23 enum { GROWBY = 80 }; /* how large we will grow strings by */
@@ -38,6 +39,7 @@ char* FAST_FUNC xmalloc_readlink(const char *path)
38 39
39 return buf; 40 return buf;
40} 41}
42#endif
41 43
42/* 44/*
43 * This routine is not the same as realpath(), which 45 * This routine is not the same as realpath(), which
@@ -64,19 +66,26 @@ char* FAST_FUNC xmalloc_follow_symlinks(const char *path)
64 linkpath = xmalloc_readlink(buf); 66 linkpath = xmalloc_readlink(buf);
65 if (!linkpath) { 67 if (!linkpath) {
66 /* not a symlink, or doesn't exist */ 68 /* not a symlink, or doesn't exist */
67 if (errno == EINVAL || errno == ENOENT) 69 if (errno == EINVAL || errno == ENOENT || (ENABLE_PLATFORM_MINGW32 && errno == ENOSYS))
68 return buf; 70 return buf;
69 goto free_buf_ret_null; 71 goto free_buf_ret_null;
70 } 72 }
71 73
72 if (!--looping) { 74 if (!--looping) {
75#if ENABLE_PLATFORM_MINGW32
76 errno = ELOOP;
77#endif
73 free(linkpath); 78 free(linkpath);
74 free_buf_ret_null: 79 free_buf_ret_null:
75 free(buf); 80 free(buf);
76 return NULL; 81 return NULL;
77 } 82 }
78 83
84#if ENABLE_PLATFORM_MINGW32
85 if (is_relative_path(linkpath)) {
86#else
79 if (*linkpath != '/') { 87 if (*linkpath != '/') {
88#endif
80 bufsize += strlen(linkpath); 89 bufsize += strlen(linkpath);
81 buf = xrealloc(buf, bufsize); 90 buf = xrealloc(buf, bufsize);
82 lpc = bb_get_last_path_component_strip(buf); 91 lpc = bb_get_last_path_component_strip(buf);
@@ -149,7 +158,11 @@ char* FAST_FUNC xmalloc_realpath_coreutils(char *path)
149 * $ realpath symlink 158 * $ realpath symlink
150 * /usr/bin/qwe 159 * /usr/bin/qwe
151 */ 160 */
161#if ENABLE_PLATFORM_MINGW32
162 if (is_relative_path(target)) {
163#else
152 if (target[0] != '/') { 164 if (target[0] != '/') {
165#endif
153 /* 166 /*
154 * $ ln -s target_does_not_exist symlink 167 * $ ln -s target_does_not_exist symlink
155 * $ readlink -f symlink 168 * $ readlink -f symlink
@@ -168,6 +181,35 @@ char* FAST_FUNC xmalloc_realpath_coreutils(char *path)
168 return buf; 181 return buf;
169 } 182 }
170 183
184#if ENABLE_PLATFORM_MINGW32
185 /* ignore leading and trailing slashes */
186 /* but keep leading slashes of UNC path */
187 if (!is_unc_path(path)) {
188 while (is_dir_sep(path[0]) && is_dir_sep(path[1]))
189 ++path;
190 }
191 i = strlen(path) - 1;
192 while (i > 0 && is_dir_sep(path[i]))
193 i--;
194 c = path[i + 1];
195 path[i + 1] = '\0';
196
197 last_slash = get_last_slash(path);
198 if (last_slash == path + root_len(path))
199 buf = xstrdup(path);
200 else if (last_slash) {
201 char c2 = *last_slash;
202 *last_slash = '\0';
203 buf = xmalloc_realpath(path);
204 *last_slash++ = c2;
205 if (buf) {
206 unsigned len = strlen(buf);
207 buf = xrealloc(buf, len + strlen(last_slash) + 2);
208 buf[len++] = c2;
209 strcpy(buf + len, last_slash);
210 }
211 }
212#else
171 /* ignore leading and trailing slashes */ 213 /* ignore leading and trailing slashes */
172 while (path[0] == '/' && path[1] == '/') 214 while (path[0] == '/' && path[1] == '/')
173 ++path; 215 ++path;
@@ -191,6 +233,7 @@ char* FAST_FUNC xmalloc_realpath_coreutils(char *path)
191 strcpy(buf + len, last_slash); 233 strcpy(buf + len, last_slash);
192 } 234 }
193 } 235 }
236#endif
194 path[i + 1] = c; 237 path[i + 1] = c;
195 } 238 }
196 239