aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2023-08-21 12:36:14 +0100
committerRon Yorston <rmy@pobox.com>2023-08-21 12:46:52 +0100
commit9a80d9752d5d1867c0730c1f5bca12abd994907e (patch)
treea40ed36d21d8386864963087863104a9c51187b7
parent67ed7484be88e3be5a5a51f404f1325a569be173 (diff)
downloadbusybox-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.h1
-rw-r--r--libbb/xreadlink.c2
-rw-r--r--win32/mingw.c26
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;
495ssize_t mingw_read(int fd, void *buf, size_t count); 495ssize_t mingw_read(int fd, void *buf, size_t count);
496int mingw_close(int fd); 496int mingw_close(int fd);
497int pipe(int filedes[2]); 497int pipe(int filedes[2]);
498ssize_t readlink(const char *pathname, char *buf, size_t bufsiz);
499NOIMPL(setgid,gid_t gid UNUSED_PARAM); 498NOIMPL(setgid,gid_t gid UNUSED_PARAM);
500NOIMPL(setegid,gid_t gid UNUSED_PARAM); 499NOIMPL(setegid,gid_t gid UNUSED_PARAM);
501NOIMPL(setsid,void); 500NOIMPL(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
20char* FAST_FUNC xmalloc_readlink(const char *path) 21char* 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
1645ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) 1645char * 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
1702const char *get_busybox_exec_path(void) 1706const char *get_busybox_exec_path(void)