From 1afcef2f5a089648430a13b2a55ba1428c8d49c0 Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Sat, 16 Oct 2021 09:59:11 +0100 Subject: 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. --- win32/mingw.c | 25 ++++++++++++++++--------- 1 file 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) } #endif -static int is_symlink(DWORD attr, const char *pathname, WIN32_FIND_DATAA *fbuf) +static int get_symlink_data(DWORD attr, const char *pathname, + WIN32_FIND_DATAA *fbuf) { if (attr & FILE_ATTRIBUTE_REPARSE_POINT) { HANDLE handle = FindFirstFileA(pathname, fbuf); @@ -570,6 +571,16 @@ static int is_symlink(DWORD attr, const char *pathname, WIN32_FIND_DATAA *fbuf) return 0; } +static int is_symlink(const char *pathname) +{ + WIN32_FILE_ATTRIBUTE_DATA fdata; + WIN32_FIND_DATAA fbuf; + + if (!get_file_attr(pathname, &fdata)) + return get_symlink_data(fdata.dwFileAttributes, pathname, &fbuf); + return 0; +} + /* If follow is true then act like stat() and report on the link * target. Otherwise report on the link itself. */ @@ -592,7 +603,7 @@ static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf) buf->st_gid = DEFAULT_GID; buf->st_dev = buf->st_rdev = 0; - if (is_symlink(fdata.dwFileAttributes, file_name, &findbuf)) { + if (get_symlink_data(fdata.dwFileAttributes, file_name, &findbuf)) { char *name = auto_string(xmalloc_realpath(file_name)); if (follow) { @@ -942,14 +953,13 @@ char *mingw_getcwd(char *pointer, int len) #undef rename int mingw_rename(const char *pold, const char *pnew) { - struct mingw_stat st; DWORD attrs; /* * For non-symlinks, try native rename() first to get errno right. * It is based on MoveFile(), which cannot overwrite existing files. */ - if (mingw_lstat(pold, &st) || !S_ISLNK(st.st_mode)) { + if (!is_symlink(pold)) { if (!rename(pold, pnew)) return 0; if (errno != EEXIST) @@ -1420,11 +1430,10 @@ int mingw_mkdir(const char *path, int mode UNUSED_PARAM) #undef chdir int mingw_chdir(const char *dirname) { - struct stat st; int ret = -1; const char *realdir = dirname; - if (lstat(dirname, &st) == 0 && S_ISLNK(st.st_mode)) { + if (is_symlink(dirname)) { realdir = auto_string(xmalloc_readlink(dirname)); if (realdir) fix_path_case((char *)realdir); @@ -1496,7 +1505,6 @@ int fcntl(int fd, int cmd, ...) int mingw_unlink(const char *pathname) { int ret; - struct stat st; /* read-only files cannot be removed */ chmod(pathname, 0666); @@ -1504,10 +1512,9 @@ int mingw_unlink(const char *pathname) ret = unlink(pathname); if (ret == -1 && errno == EACCES) { /* a symlink to a directory needs to be removed by calling rmdir */ - if (lstat(pathname, &st) == 0 && S_ISLNK(st.st_mode)) { + if (is_symlink(pathname)) { return rmdir(pathname); } - errno = EACCES; } return ret; } -- cgit v1.2.3-55-g6feb