diff options
author | Ron Yorston <rmy@pobox.com> | 2022-09-27 08:35:14 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-09-27 11:18:29 +0100 |
commit | 1b3002fb63f83498d210cfb1cc189313df0eb8c5 (patch) | |
tree | cf9915aadb967168c6e6fe2568ef45a02ad67f9a | |
parent | 182e489d9bc1b935fc5494b5c9ef47f47a6173d5 (diff) | |
download | busybox-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.c | 25 |
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 | } |