diff options
author | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
commit | 0ecf1aea459571b48dc68ddc2b7b9265740fa960 (patch) | |
tree | 491d6184a44b8b525a4ca35759d622aecd7f6344 /libbb/xreadlink.c | |
parent | 4859ddcb20616718efbea12c6bf8b27c469b68de (diff) | |
parent | aaf3d5ba74c5da97ff80b61f30cb8dd225d39096 (diff) | |
download | busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.gz busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.bz2 busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb/xreadlink.c')
-rw-r--r-- | libbb/xreadlink.c | 75 |
1 files changed, 45 insertions, 30 deletions
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index 31680810b..024ee9047 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -130,7 +130,7 @@ char* FAST_FUNC xmalloc_realpath(const char *path) | |||
130 | #endif | 130 | #endif |
131 | } | 131 | } |
132 | 132 | ||
133 | char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | 133 | char* FAST_FUNC xmalloc_realpath_coreutils(char *path) |
134 | { | 134 | { |
135 | char *buf; | 135 | char *buf; |
136 | 136 | ||
@@ -144,32 +144,19 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | |||
144 | * (the directory must exist). | 144 | * (the directory must exist). |
145 | */ | 145 | */ |
146 | if (!buf && errno == ENOENT) { | 146 | if (!buf && errno == ENOENT) { |
147 | char *last_slash = strrchr(path, '/'); | 147 | char *target, c, *last_slash; |
148 | if (last_slash) { | 148 | size_t i; |
149 | *last_slash++ = '\0'; | 149 | |
150 | buf = xmalloc_realpath(path); | 150 | target = xmalloc_readlink(path); |
151 | if (buf) { | 151 | if (target) { |
152 | unsigned len = strlen(buf); | 152 | /* |
153 | buf = xrealloc(buf, len + strlen(last_slash) + 2); | 153 | * $ ln -s /bin/qwe symlink # note: /bin is a link to /usr/bin |
154 | buf[len++] = '/'; | 154 | * $ readlink -f symlink |
155 | strcpy(buf + len, last_slash); | 155 | * /usr/bin/qwe |
156 | } | 156 | * $ realpath symlink |
157 | } else { | 157 | * /usr/bin/qwe |
158 | char *target = xmalloc_readlink(path); | 158 | */ |
159 | if (target) { | 159 | if (target[0] != '/') { |
160 | char *cwd; | ||
161 | if (target[0] == '/') { | ||
162 | /* | ||
163 | * $ ln -s /bin/qwe symlink # note: /bin is a link to /usr/bin | ||
164 | * $ readlink -f symlink | ||
165 | * /usr/bin/qwe/target_does_not_exist | ||
166 | * $ realpath symlink | ||
167 | * /usr/bin/qwe/target_does_not_exist | ||
168 | */ | ||
169 | buf = xmalloc_realpath_coreutils(target); | ||
170 | free(target); | ||
171 | return buf; | ||
172 | } | ||
173 | /* | 160 | /* |
174 | * $ ln -s target_does_not_exist symlink | 161 | * $ ln -s target_does_not_exist symlink |
175 | * $ readlink -f symlink | 162 | * $ readlink -f symlink |
@@ -177,13 +164,41 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | |||
177 | * $ realpath symlink | 164 | * $ realpath symlink |
178 | * /CURDIR/target_does_not_exist | 165 | * /CURDIR/target_does_not_exist |
179 | */ | 166 | */ |
180 | cwd = xrealloc_getcwd_or_warn(NULL); | 167 | char *cwd = xrealloc_getcwd_or_warn(NULL); |
181 | buf = concat_path_file(cwd, target); | 168 | char *tmp = concat_path_file(cwd, target); |
182 | free(cwd); | 169 | free(cwd); |
183 | free(target); | 170 | free(target); |
184 | return buf; | 171 | target = tmp; |
172 | } | ||
173 | buf = xmalloc_realpath_coreutils(target); | ||
174 | free(target); | ||
175 | return buf; | ||
176 | } | ||
177 | |||
178 | /* ignore leading and trailing slashes */ | ||
179 | while (path[0] == '/' && path[1] == '/') | ||
180 | ++path; | ||
181 | i = strlen(path) - 1; | ||
182 | while (i > 0 && path[i] == '/') | ||
183 | i--; | ||
184 | c = path[i + 1]; | ||
185 | path[i + 1] = '\0'; | ||
186 | |||
187 | last_slash = strrchr(path, '/'); | ||
188 | if (last_slash == path) | ||
189 | buf = xstrdup(path); | ||
190 | else if (last_slash) { | ||
191 | *last_slash = '\0'; | ||
192 | buf = xmalloc_realpath(path); | ||
193 | *last_slash++ = '/'; | ||
194 | if (buf) { | ||
195 | unsigned len = strlen(buf); | ||
196 | buf = xrealloc(buf, len + strlen(last_slash) + 2); | ||
197 | buf[len++] = '/'; | ||
198 | strcpy(buf + len, last_slash); | ||
185 | } | 199 | } |
186 | } | 200 | } |
201 | path[i + 1] = c; | ||
187 | } | 202 | } |
188 | 203 | ||
189 | return buf; | 204 | return buf; |