aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-10-16 09:59:11 +0100
committerRon Yorston <rmy@pobox.com>2021-10-16 09:59:11 +0100
commit1afcef2f5a089648430a13b2a55ba1428c8d49c0 (patch)
treeaf0af124036618764e847e88cfb57526242df99f
parentd78bd61e556d8cd728414b553edf3ccd30580b4d (diff)
downloadbusybox-w32-1afcef2f5a089648430a13b2a55ba1428c8d49c0.tar.gz
busybox-w32-1afcef2f5a089648430a13b2a55ba1428c8d49c0.tar.bz2
busybox-w32-1afcef2f5a089648430a13b2a55ba1428c8d49c0.zip
win32: code shrink
There are a few places in mingw.c where we want to determine if a file is a symbolic link. Previously these called mingw_lstat() which collects far more information than is actually needed. Create a new is_symlink() function which does the minimum work necessary.
-rw-r--r--win32/mingw.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index d4855a7e7..c59d8a7c8 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -557,7 +557,8 @@ static uid_t file_owner(HANDLE fh)
557} 557}
558#endif 558#endif
559 559
560static int is_symlink(DWORD attr, const char *pathname, WIN32_FIND_DATAA *fbuf) 560static int get_symlink_data(DWORD attr, const char *pathname,
561 WIN32_FIND_DATAA *fbuf)
561{ 562{
562 if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { 563 if (attr & FILE_ATTRIBUTE_REPARSE_POINT) {
563 HANDLE handle = FindFirstFileA(pathname, fbuf); 564 HANDLE handle = FindFirstFileA(pathname, fbuf);
@@ -570,6 +571,16 @@ static int is_symlink(DWORD attr, const char *pathname, WIN32_FIND_DATAA *fbuf)
570 return 0; 571 return 0;
571} 572}
572 573
574static int is_symlink(const char *pathname)
575{
576 WIN32_FILE_ATTRIBUTE_DATA fdata;
577 WIN32_FIND_DATAA fbuf;
578
579 if (!get_file_attr(pathname, &fdata))
580 return get_symlink_data(fdata.dwFileAttributes, pathname, &fbuf);
581 return 0;
582}
583
573/* If follow is true then act like stat() and report on the link 584/* If follow is true then act like stat() and report on the link
574 * target. Otherwise report on the link itself. 585 * target. Otherwise report on the link itself.
575 */ 586 */
@@ -592,7 +603,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
592 buf->st_gid = DEFAULT_GID; 603 buf->st_gid = DEFAULT_GID;
593 buf->st_dev = buf->st_rdev = 0; 604 buf->st_dev = buf->st_rdev = 0;
594 605
595 if (is_symlink(fdata.dwFileAttributes, file_name, &findbuf)) { 606 if (get_symlink_data(fdata.dwFileAttributes, file_name, &findbuf)) {
596 char *name = auto_string(xmalloc_realpath(file_name)); 607 char *name = auto_string(xmalloc_realpath(file_name));
597 608
598 if (follow) { 609 if (follow) {
@@ -942,14 +953,13 @@ char *mingw_getcwd(char *pointer, int len)
942#undef rename 953#undef rename
943int mingw_rename(const char *pold, const char *pnew) 954int mingw_rename(const char *pold, const char *pnew)
944{ 955{
945 struct mingw_stat st;
946 DWORD attrs; 956 DWORD attrs;
947 957
948 /* 958 /*
949 * For non-symlinks, try native rename() first to get errno right. 959 * For non-symlinks, try native rename() first to get errno right.
950 * It is based on MoveFile(), which cannot overwrite existing files. 960 * It is based on MoveFile(), which cannot overwrite existing files.
951 */ 961 */
952 if (mingw_lstat(pold, &st) || !S_ISLNK(st.st_mode)) { 962 if (!is_symlink(pold)) {
953 if (!rename(pold, pnew)) 963 if (!rename(pold, pnew))
954 return 0; 964 return 0;
955 if (errno != EEXIST) 965 if (errno != EEXIST)
@@ -1420,11 +1430,10 @@ int mingw_mkdir(const char *path, int mode UNUSED_PARAM)
1420#undef chdir 1430#undef chdir
1421int mingw_chdir(const char *dirname) 1431int mingw_chdir(const char *dirname)
1422{ 1432{
1423 struct stat st;
1424 int ret = -1; 1433 int ret = -1;
1425 const char *realdir = dirname; 1434 const char *realdir = dirname;
1426 1435
1427 if (lstat(dirname, &st) == 0 && S_ISLNK(st.st_mode)) { 1436 if (is_symlink(dirname)) {
1428 realdir = auto_string(xmalloc_readlink(dirname)); 1437 realdir = auto_string(xmalloc_readlink(dirname));
1429 if (realdir) 1438 if (realdir)
1430 fix_path_case((char *)realdir); 1439 fix_path_case((char *)realdir);
@@ -1496,7 +1505,6 @@ int fcntl(int fd, int cmd, ...)
1496int mingw_unlink(const char *pathname) 1505int mingw_unlink(const char *pathname)
1497{ 1506{
1498 int ret; 1507 int ret;
1499 struct stat st;
1500 1508
1501 /* read-only files cannot be removed */ 1509 /* read-only files cannot be removed */
1502 chmod(pathname, 0666); 1510 chmod(pathname, 0666);
@@ -1504,10 +1512,9 @@ int mingw_unlink(const char *pathname)
1504 ret = unlink(pathname); 1512 ret = unlink(pathname);
1505 if (ret == -1 && errno == EACCES) { 1513 if (ret == -1 && errno == EACCES) {
1506 /* a symlink to a directory needs to be removed by calling rmdir */ 1514 /* a symlink to a directory needs to be removed by calling rmdir */
1507 if (lstat(pathname, &st) == 0 && S_ISLNK(st.st_mode)) { 1515 if (is_symlink(pathname)) {
1508 return rmdir(pathname); 1516 return rmdir(pathname);
1509 } 1517 }
1510 errno = EACCES;
1511 } 1518 }
1512 return ret; 1519 return ret;
1513} 1520}