diff options
author | Ron Yorston <rmy@pobox.com> | 2023-08-21 12:36:14 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2023-08-21 12:46:52 +0100 |
commit | 9a80d9752d5d1867c0730c1f5bca12abd994907e (patch) | |
tree | a40ed36d21d8386864963087863104a9c51187b7 | |
parent | 67ed7484be88e3be5a5a51f404f1325a569be173 (diff) | |
download | busybox-w32-9a80d9752d5d1867c0730c1f5bca12abd994907e.tar.gz busybox-w32-9a80d9752d5d1867c0730c1f5bca12abd994907e.tar.bz2 busybox-w32-9a80d9752d5d1867c0730c1f5bca12abd994907e.zip |
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.
-rw-r--r-- | include/mingw.h | 1 | ||||
-rw-r--r-- | libbb/xreadlink.c | 2 | ||||
-rw-r--r-- | 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; | |||
495 | ssize_t mingw_read(int fd, void *buf, size_t count); | 495 | ssize_t mingw_read(int fd, void *buf, size_t count); |
496 | int mingw_close(int fd); | 496 | int mingw_close(int fd); |
497 | int pipe(int filedes[2]); | 497 | int pipe(int filedes[2]); |
498 | ssize_t readlink(const char *pathname, char *buf, size_t bufsiz); | ||
499 | NOIMPL(setgid,gid_t gid UNUSED_PARAM); | 498 | NOIMPL(setgid,gid_t gid UNUSED_PARAM); |
500 | NOIMPL(setegid,gid_t gid UNUSED_PARAM); | 499 | NOIMPL(setegid,gid_t gid UNUSED_PARAM); |
501 | NOIMPL(setsid,void); | 500 | 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 @@ | |||
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 |
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) | |||
673 | buf->st_tag = get_symlink_data(buf->st_attr, file_name, &findbuf); | 673 | buf->st_tag = get_symlink_data(buf->st_attr, file_name, &findbuf); |
674 | 674 | ||
675 | if (buf->st_tag) { | 675 | if (buf->st_tag) { |
676 | ssize_t len; | 676 | char *content; |
677 | char content[PATH_MAX]; | ||
678 | 677 | ||
679 | if (follow) { | 678 | if (follow) { |
680 | /* The file size and times are wrong when Windows follows | 679 | /* 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) | |||
687 | 686 | ||
688 | /* Get the contents of a symlink, not its target. */ | 687 | /* Get the contents of a symlink, not its target. */ |
689 | buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; | 688 | buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; |
690 | len = readlink(file_name, content, PATH_MAX); | 689 | content = xmalloc_readlink(file_name); |
691 | buf->st_size = (len < 0 || len == PATH_MAX) ? 0 : len; | 690 | buf->st_size = content ? strlen(content) : 0; |
691 | free(content); | ||
692 | buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime)); | 692 | buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime)); |
693 | buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime)); | 693 | buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime)); |
694 | buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime)); | 694 | buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime)); |
@@ -1642,9 +1642,11 @@ typedef struct { | |||
1642 | } APPEXECLINK_BUFFER; | 1642 | } APPEXECLINK_BUFFER; |
1643 | 1643 | ||
1644 | #define SRPB rptr->SymbolicLinkReparseBuffer | 1644 | #define SRPB rptr->SymbolicLinkReparseBuffer |
1645 | ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) | 1645 | char * FAST_FUNC xmalloc_readlink(const char *pathname) |
1646 | { | 1646 | { |
1647 | HANDLE h; | 1647 | HANDLE h; |
1648 | char *buf; | ||
1649 | int bufsiz; | ||
1648 | 1650 | ||
1649 | h = CreateFile(pathname, 0, 0, NULL, OPEN_EXISTING, | 1651 | h = CreateFile(pathname, 0, 0, NULL, OPEN_EXISTING, |
1650 | FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); | 1652 | 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) | |||
1688 | if (name) { | 1690 | if (name) { |
1689 | name[len] = 0; | 1691 | name[len] = 0; |
1690 | name = normalize_ntpath(name); | 1692 | name = normalize_ntpath(name); |
1691 | len = wcslen(name); | 1693 | bufsiz = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, 0, 0); |
1692 | if (len > bufsiz) | 1694 | if (bufsiz) { |
1693 | len = bufsiz; | 1695 | buf = xmalloc(bufsiz); |
1694 | if (WideCharToMultiByte(CP_ACP, 0, name, len, buf, bufsiz, 0, 0)) | 1696 | if (WideCharToMultiByte(CP_ACP, 0, name, -1, buf, bufsiz, 0, 0)) |
1695 | return len; | 1697 | return buf; |
1698 | free(buf); | ||
1699 | } | ||
1696 | } | 1700 | } |
1697 | } | 1701 | } |
1698 | errno = err_win_to_posix(); | 1702 | errno = err_win_to_posix(); |
1699 | return -1; | 1703 | return NULL; |
1700 | } | 1704 | } |
1701 | 1705 | ||
1702 | const char *get_busybox_exec_path(void) | 1706 | const char *get_busybox_exec_path(void) |