aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-09-27 08:35:14 +0100
committerRon Yorston <rmy@pobox.com>2022-09-27 11:18:29 +0100
commit1b3002fb63f83498d210cfb1cc189313df0eb8c5 (patch)
treecf9915aadb967168c6e6fe2568ef45a02ad67f9a
parent182e489d9bc1b935fc5494b5c9ef47f47a6173d5 (diff)
downloadbusybox-w32-1b3002fb63f83498d210cfb1cc189313df0eb8c5.tar.gz
busybox-w32-1b3002fb63f83498d210cfb1cc189313df0eb8c5.tar.bz2
busybox-w32-1b3002fb63f83498d210cfb1cc189313df0eb8c5.zip
win32: use xmalloc_follow_symlinks() in stat(2)
Commit 31467ddfc (win32: changes to stat(2) implementation) followed symlinks manually. Unfortunately the implementation was incorrect. Use xmalloc_follow_symlinks() instead. Saves 32-48 bytes.
-rw-r--r--win32/mingw.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index d26f9f2ff..d5d944a9d 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -630,7 +630,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
630 WIN32_FIND_DATAA findbuf; 630 WIN32_FIND_DATAA findbuf;
631 DWORD low, high; 631 DWORD low, high;
632 off64_t size; 632 off64_t size;
633 char lname[PATH_MAX]; 633 char *lname = NULL;
634#if ENABLE_FEATURE_EXTRA_FILE_DATA 634#if ENABLE_FEATURE_EXTRA_FILE_DATA
635 DWORD flags; 635 DWORD flags;
636 BY_HANDLE_FILE_INFORMATION hdata; 636 BY_HANDLE_FILE_INFORMATION hdata;
@@ -646,30 +646,22 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
646 buf->st_tag = get_symlink_data(buf->st_attr, file_name, &findbuf); 646 buf->st_tag = get_symlink_data(buf->st_attr, file_name, &findbuf);
647 647
648 if (buf->st_tag) { 648 if (buf->st_tag) {
649 ssize_t len = readlink(file_name, lname, PATH_MAX); 649 ssize_t len;
650 if (len < 0) { 650 char content[PATH_MAX];
651 err = errno;
652 break;
653 } else if (len == PATH_MAX) {
654 errno = ENAMETOOLONG;
655 break;
656 }
657 651
658 if (follow) { 652 if (follow) {
659 /* The file size and times are wrong when Windows follows 653 /* The file size and times are wrong when Windows follows
660 * a symlink. Use the symlink target instead. */ 654 * a symlink. Use the symlink target instead. */
661 if (follow++ > MAXSYMLINKS) { 655 file_name = lname = xmalloc_follow_symlinks(file_name);
662 err = ELOOP; 656 if (!lname)
663 break; 657 return -1;
664 }
665 lname[len] = '\0';
666 file_name = lname;
667 continue; 658 continue;
668 } 659 }
669 660
670 /* Get the contents of a symlink, not its target. */ 661 /* Get the contents of a symlink, not its target. */
671 buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO; 662 buf->st_mode = S_IFLNK|S_IRWXU|S_IRWXG|S_IRWXO;
672 buf->st_size = len; 663 len = readlink(file_name, content, PATH_MAX);
664 buf->st_size = (len < 0 || len == PATH_MAX) ? 0 : len;
673 buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime)); 665 buf->st_atim = filetime_to_timespec(&(findbuf.ftLastAccessTime));
674 buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime)); 666 buf->st_mtim = filetime_to_timespec(&(findbuf.ftLastWriteTime));
675 buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime)); 667 buf->st_ctim = filetime_to_timespec(&(findbuf.ftCreationTime));
@@ -733,6 +725,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
733 buf->st_blocks = ((size+4095)>>12)<<3; 725 buf->st_blocks = ((size+4095)>>12)<<3;
734 return 0; 726 return 0;
735 } 727 }
728 free(lname);
736 errno = err; 729 errno = err;
737 return -1; 730 return -1;
738} 731}