diff options
author | Ron Yorston <rmy@pobox.com> | 2021-08-12 11:39:12 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-08-12 11:49:56 +0100 |
commit | da7efea0e7520f7ce8627acc9f4037a2f875c47e (patch) | |
tree | 61f27c5f9bfe600a4bde12fb464e281ba7a28500 | |
parent | 602137d1637787c334a1b858e2d4e7a5feb3fb1b (diff) | |
download | busybox-w32-da7efea0e7520f7ce8627acc9f4037a2f875c47e.tar.gz busybox-w32-da7efea0e7520f7ce8627acc9f4037a2f875c47e.tar.bz2 busybox-w32-da7efea0e7520f7ce8627acc9f4037a2f875c47e.zip |
win32: better handling of nested symlinks
Our realpath(3) implementation uses xmalloc_follow_symlinks() to
expand symlinks. This detects when symlinks are too deeply nested
but didn't set errno, so anything calling realpath(3) was unable to
say what had gone wrong. (For example, 'ls -L' or 'stat -L'.)
Set errno to ELOOP.
This then leads to the problem that Windows doesn't know about
ELOOP so reports 'Unknown error'. Add a replacement for strerror(3)
which returns a sensible message.
Costs 96 bytes.
-rw-r--r-- | include/mingw.h | 3 | ||||
-rw-r--r-- | libbb/xreadlink.c | 3 | ||||
-rw-r--r-- | win32/mingw.c | 8 |
3 files changed, 14 insertions, 0 deletions
diff --git a/include/mingw.h b/include/mingw.h index c4849215b..03ef89029 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -209,6 +209,9 @@ int unsetenv(const char *env); | |||
209 | * string.h | 209 | * string.h |
210 | */ | 210 | */ |
211 | char *strndup(char const *s, size_t n); | 211 | char *strndup(char const *s, size_t n); |
212 | char *mingw_strerror(int errnum); | ||
213 | |||
214 | #define strerror mingw_strerror | ||
212 | 215 | ||
213 | /* | 216 | /* |
214 | * strings.h | 217 | * strings.h |
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index f0a63fd9b..b64654b33 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -70,6 +70,9 @@ char* FAST_FUNC xmalloc_follow_symlinks(const char *path) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | if (!--looping) { | 72 | if (!--looping) { |
73 | #if ENABLE_PLATFORM_MINGW32 | ||
74 | errno = ELOOP; | ||
75 | #endif | ||
73 | free(linkpath); | 76 | free(linkpath); |
74 | free_buf_ret_null: | 77 | free_buf_ret_null: |
75 | free(buf); | 78 | free(buf); |
diff --git a/win32/mingw.c b/win32/mingw.c index 49dcd89d8..c592b8d2c 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -161,6 +161,14 @@ int err_win_to_posix(void) | |||
161 | return error; | 161 | return error; |
162 | } | 162 | } |
163 | 163 | ||
164 | #undef strerror | ||
165 | char *mingw_strerror(int errnum) | ||
166 | { | ||
167 | if (errnum == ELOOP) | ||
168 | return (char *)"Too many levels of symbolic links"; | ||
169 | return strerror(errnum); | ||
170 | } | ||
171 | |||
164 | static int zero_fd = -1; | 172 | static int zero_fd = -1; |
165 | static int rand_fd = -1; | 173 | static int rand_fd = -1; |
166 | 174 | ||