diff options
Diffstat (limited to '')
-rw-r--r-- | libbb/xreadlink.c | 45 |
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 | ||
20 | char* FAST_FUNC xmalloc_readlink(const char *path) | 21 | char* 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 | ||