From 9a80d9752d5d1867c0730c1f5bca12abd994907e Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Mon, 21 Aug 2023 12:36:14 +0100 Subject: win32: replace readlink(2) The Windows implementation of readlink(2) has caused problems in the past. As, for example, with commit c29dc205d2 (win32: fix implementation of readlink(2)). Most uses of readlink(2) in BusyBox are actually calls to the (considerably more convenient) library function xmalloc_readlink(). Implement a Windows version of that and used it instead of readlink(2). This improves the handling of symbolic links (and similar reparse points) in CJK and UTF-8 code pages. Saves 48-80 bytes. --- include/mingw.h | 1 - libbb/xreadlink.c | 2 ++ win32/mingw.c | 26 +++++++++++++++----------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/include/mingw.h b/include/mingw.h index 6e851b43d..1dcc84bde 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -495,7 +495,6 @@ ssize_t mingw_open_read_close(const char *fn, void *buf, size_t size) FAST_FUNC; ssize_t mingw_read(int fd, void *buf, size_t count); int mingw_close(int fd); int pipe(int filedes[2]); -ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); NOIMPL(setgid,gid_t gid UNUSED_PARAM); NOIMPL(setegid,gid_t gid UNUSED_PARAM); NOIMPL(setsid,void); diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index e6cf90310..fc10a2939 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c @@ -17,6 +17,7 @@ * NOTE: This function returns a malloced char* that you will have to free * yourself. */ +#if !ENABLE_PLATFORM_MINGW32 char* FAST_FUNC xmalloc_readlink(const char *path) { enum { GROWBY = 80 }; /* how large we will grow strings by */ @@ -38,6 +39,7 @@ char* FAST_FUNC xmalloc_readlink(const char *path) return buf; } +#endif /* * This routine is not the same as realpath(), which diff --git a/win32/mingw.c b/win32/mingw.c index fec6df73a..8588b1a86 100644 --- a/win32/mingw.c +++ b/win32/mingw.c @@ -673,8 +673,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) buf->st_tag = get_symlink_data(buf->st_attr, file_name, &findbuf); if (buf->st_tag) { - ssize_t len; - char content[PATH_MAX]; + char *content; if (follow) { /* The file size and times are wrong when Windows follows @@ -687,8 +686,9 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) /* Get the contents of a symlink, not its target. */ buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; - len = readlink(file_name, content, PATH_MAX); - buf->st_size = (len < 0 || len == PATH_MAX) ? 0 : len; + content = xmalloc_readlink(file_name); + buf->st_size = content ? strlen(content) : 0; + free(content); buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime)); buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime)); buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime)); @@ -1642,9 +1642,11 @@ typedef struct { } APPEXECLINK_BUFFER; #define SRPB rptr->SymbolicLinkReparseBuffer -ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) +char * FAST_FUNC xmalloc_readlink(const char *pathname) { HANDLE h; + char *buf; + int bufsiz; h = CreateFile(pathname, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); @@ -1688,15 +1690,17 @@ ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) if (name) { name[len] = 0; name = normalize_ntpath(name); - len = wcslen(name); - if (len > bufsiz) - len = bufsiz; - if (WideCharToMultiByte(CP_ACP, 0, name, len, buf, bufsiz, 0, 0)) - return len; + bufsiz = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, 0, 0); + if (bufsiz) { + buf = xmalloc(bufsiz); + if (WideCharToMultiByte(CP_ACP, 0, name, -1, buf, bufsiz, 0, 0)) + return buf; + free(buf); + } } } errno = err_win_to_posix(); - return -1; + return NULL; } const char *get_busybox_exec_path(void) -- cgit v1.2.3-55-g6feb