From 247d0da188e70949a48739fc42dbf5da4d7b8b40 Mon Sep 17 00:00:00 2001 From: Igor Zinkovsky Date: Wed, 11 Jan 2012 19:34:56 -0800 Subject: [PATCH] update libuv to 855764406e fixes #2521 --- deps/uv/src/win/fs.c | 74 +++++++++++++++++++++++++++----------- deps/uv/src/win/internal.h | 4 +-- deps/uv/src/win/util.c | 23 ++++++++++++ 3 files changed, 77 insertions(+), 24 deletions(-) diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 78ccffab6b58..d7087b1f55b6 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -490,38 +490,69 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) { void fs__stat(uv_fs_t* req, const wchar_t* path) { + HANDLE file; + WIN32_FIND_DATAW ent; int result; - unsigned short mode; - fs__open(req, path, _O_RDONLY, 0); - if (req->result == -1) { + req->ptr = NULL; + + file = FindFirstFileExW(path, FindExInfoStandard, &ent, + FindExSearchNameMatch, NULL, 0); + + if (file == INVALID_HANDLE_VALUE) { + SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); return; } - result = _fstati64(req->result, &req->stat); - if (result == -1) { - req->ptr = NULL; - } else { + FindClose(file); - /* - * VC CRT doesn't properly set S_IFDIR in _fstati64, - * so we set it here if path is a directory. - */ - if (GetFileAttributesW(path) & FILE_ATTRIBUTE_DIRECTORY) { - mode = req->stat.st_mode; - mode &= ~_S_IFMT; - mode |= _S_IFDIR; - - req->stat.st_mode = mode; - assert((req->stat.st_mode & _S_IFMT) == _S_IFDIR); + if (ent.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT && + ent.dwReserved0 == IO_REPARSE_TAG_SYMLINK) { + fs__open(req, path, _O_RDONLY, 0); + if (req->result != -1) { + result = _fstati64(req->result, &req->stat); + _close(req->result); + + if (result != -1) { + req->ptr = &req->stat; + } + + SET_REQ_RESULT(req, result); } - req->ptr = &req->stat; + return; } - _close(req->result); + req->stat.st_ino = 0; + req->stat.st_uid = 0; + req->stat.st_gid = 0; + req->stat.st_mode = 0; + req->stat.st_rdev = 0; + req->stat.st_dev = 0; + req->stat.st_nlink = 1; - SET_REQ_RESULT(req, result); + if (ent.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) { + req->stat.st_mode |= (_S_IREAD + (_S_IREAD >> 3) + (_S_IREAD >> 6)); + } else { + req->stat.st_mode |= ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3) + + ((_S_IREAD|_S_IWRITE) >> 6)); + } + + if (ent.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + req->stat.st_mode |= _S_IFDIR; + } else { + req->stat.st_mode |= _S_IFREG; + } + + uv_filetime_to_time_t(&ent.ftLastWriteTime, &(req->stat.st_mtime)); + uv_filetime_to_time_t(&ent.ftLastAccessTime, &(req->stat.st_atime)); + uv_filetime_to_time_t(&ent.ftCreationTime, &(req->stat.st_ctime)); + + req->stat.st_size = ((int64_t)ent.nFileSizeHigh << 32) + + (int64_t)ent.nFileSizeLow; + + req->ptr = &req->stat; + req->result = 0; } @@ -1543,3 +1574,4 @@ void uv_fs_req_cleanup(uv_fs_t* req) { req->flags |= UV_FS_CLEANEDUP; } + diff --git a/deps/uv/src/win/internal.h b/deps/uv/src/win/internal.h index deb8972c5a87..336349b1fab4 100644 --- a/deps/uv/src/win/internal.h +++ b/deps/uv/src/win/internal.h @@ -284,10 +284,8 @@ void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle); /* Utils */ int uv_parent_pid(); - - +void uv_filetime_to_time_t(FILETIME* file_time, time_t* stat_time); void uv_fatal_error(const int errorno, const char* syscall); - uv_err_code uv_translate_sys_error(int sys_errno); #define SET_REQ_STATUS(req, status) \ diff --git a/deps/uv/src/win/util.c b/deps/uv/src/win/util.c index fcdeafc72281..0fcfb9c3d206 100644 --- a/deps/uv/src/win/util.c +++ b/deps/uv/src/win/util.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "uv.h" #include "internal.h" @@ -236,3 +237,25 @@ int uv_parent_pid() { CloseHandle(handle); return parent_pid; } + + +void uv_filetime_to_time_t(FILETIME* file_time, time_t* stat_time) { + FILETIME local_time; + SYSTEMTIME system_time; + struct tm time; + + if ((file_time->dwLowDateTime || file_time->dwHighDateTime) && + FileTimeToLocalFileTime(file_time, &local_time) && + FileTimeToSystemTime(&local_time, &system_time)) { + time.tm_year = system_time.wYear - 1900; + time.tm_mon = system_time.wMonth - 1; + time.tm_mday = system_time.wDay; + time.tm_hour = system_time.wHour; + time.tm_min = system_time.wMinute; + time.tm_sec = system_time.wSecond; + + *stat_time = mktime(&time); + } else { + *stat_time = 0; + } +}