From 67cd05472e0c3b2859469d2f1d83400b99464447 Mon Sep 17 00:00:00 2001 From: Bert Belder Date: Thu, 2 Feb 2012 17:42:08 +0100 Subject: [PATCH] uv: upgrade to 267e75d --- deps/uv/include/uv.h | 3 +- deps/uv/src/unix/error.c | 1 + deps/uv/src/win/error.c | 2 +- deps/uv/src/win/fs.c | 184 ++++++--------------------------------- deps/uv/test/test-fs.c | 26 ++++++ 5 files changed, 57 insertions(+), 159 deletions(-) diff --git a/deps/uv/include/uv.h b/deps/uv/include/uv.h index 629435274e..23e5e21d14 100644 --- a/deps/uv/include/uv.h +++ b/deps/uv/include/uv.h @@ -116,7 +116,8 @@ typedef intptr_t ssize_t; XX( 46, ESHUTDOWN, "") \ XX( 47, EEXIST, "file already exists") \ XX( 48, ESRCH, "no such process") \ - XX( 49, ENAMETOOLONG, "name too long") + XX( 49, ENAMETOOLONG, "name too long") \ + XX( 50, EPERM, "operation not permitted") #define UV_ERRNO_GEN(val, name, s) UV_##name = val, diff --git a/deps/uv/src/unix/error.c b/deps/uv/src/unix/error.c index 80d3270db0..1d38623f0b 100644 --- a/deps/uv/src/unix/error.c +++ b/deps/uv/src/unix/error.c @@ -59,6 +59,7 @@ void uv_fatal_error(const int errorno, const char* syscall) { uv_err_code uv_translate_sys_error(int sys_errno) { switch (sys_errno) { case 0: return UV_OK; + case EPERM: return UV_EPERM; case ENOSYS: return UV_ENOSYS; case ENOTSOCK: return UV_ENOTSOCK; case ENOENT: return UV_ENOENT; diff --git a/deps/uv/src/win/error.c b/deps/uv/src/win/error.c index 59c9ea8346..779061031f 100644 --- a/deps/uv/src/win/error.c +++ b/deps/uv/src/win/error.c @@ -69,7 +69,7 @@ uv_err_code uv_translate_sys_error(int sys_errno) { case ERROR_SUCCESS: return UV_OK; case ERROR_FILE_NOT_FOUND: return UV_ENOENT; case ERROR_PATH_NOT_FOUND: return UV_ENOENT; - case ERROR_ACCESS_DENIED: return UV_EACCES; + case ERROR_ACCESS_DENIED: return UV_EPERM; case ERROR_NOACCESS: return UV_EACCES; case WSAEACCES: return UV_EACCES; case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; diff --git a/deps/uv/src/win/fs.c b/deps/uv/src/win/fs.c index 5248ac2a99..12ad514c48 100644 --- a/deps/uv/src/win/fs.c +++ b/deps/uv/src/win/fs.c @@ -489,191 +489,61 @@ void fs__readdir(uv_fs_t* req, const wchar_t* path, int flags) { } -#define IS_SLASH(c) \ - ((wchar_t) c == L'/' || (wchar_t) c == L'\\') -#define IS_COLON(c) \ - ((wchar_t) c == L':') -#define IS_LETTER(c) \ - ((((wchar_t) c >= L'a') && ((wchar_t) c <= L'z')) || \ - (((wchar_t) c >= L'A') && ((wchar_t) c <= L'Z'))) -#define IS_QUESTION(c) \ - ((wchar_t) c == L'?') - - -static int uv__count_slash_separated_words(const wchar_t* pos, - const wchar_t* end, - int limit) { - char last_was_slash = 1, count = 0; - - for (; pos < end; pos++) { - if (IS_SLASH(*pos)) { - /* Don't accept double slashes */ - if (last_was_slash) { - return 0; - } else { - last_was_slash = 1; - } - } else { - if (last_was_slash) { - /* Found a new word */ - count++; - if (count > limit) { - return -1; - } - last_was_slash = 0; - } - } - } - - return count; -} - -/* - * Returns true if the given path is a root directory. The following patterns - * are recognized: - * \ - * c:\ (must have trailing slash) - * \\server\share (trailing slash optional) - * \\?\c: (trailing slash optional) - * \\?\UNC\server\share (trailing slash optional) - */ -static int uv__is_root(const wchar_t* path) { - size_t len = wcslen(path); - - /* Test for \ */ - if (len == 1 && IS_SLASH(path[0])) { - return 1; - } - - if (len < 3) { - return 0; - } - - /* Test for c:\ */ - if (IS_LETTER(path[0]) && IS_COLON(path[1]) && IS_SLASH(path[2])) { - return 1; - } - - if (!IS_SLASH(path[0]) || !IS_SLASH(path[1])) { - return 0; - } - - /* Test for \\server\share */ - if (!IS_QUESTION(path[2])) { - return uv__count_slash_separated_words(path + 2, path + len, 2) == 2; - } - - if (!IS_SLASH(path[3])) { - return 0; - } - - if ((len == 6 || len == 7) && - IS_LETTER(path[4]) && IS_COLON(path[5]) && - (len == 6 || IS_SLASH(path[6]))) { - return 1; - } - - /* Test for \\?\UNC\server\share */ - if (len >= 8 && - (path[4] == L'u' || path[4] == L'U') && - (path[5] == L'n' || path[5] == L'N') && - (path[6] == L'c' || path[6] == L'C') && - IS_SLASH(path[7])) { - return uv__count_slash_separated_words(path + 8, path + len, 2) == 2; - } - - return 0; -} - - -void fs__stat(uv_fs_t* req, const wchar_t* path) { - HANDLE file; - WIN32_FIND_DATAW ent; +static void fs__stat(uv_fs_t* req, const wchar_t* path) { + HANDLE handle; int result; + BY_HANDLE_FILE_INFORMATION info; req->ptr = NULL; - if (uv__is_root(path)) { - /* We can't stat root directories like c:\. _wstati64 can't either, but */ - /* it will make up something reasonable. */ - DWORD drive_type = GetDriveTypeW(path); - if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) { - req->last_error = ERROR_PATH_NOT_FOUND; - req->errorno = UV_ENOENT; - req->result = -1; - return; - } - - memset(&req->stat, 0, sizeof req->stat); - - req->stat.st_nlink = 1; - req->stat.st_mode = ((_S_IREAD|_S_IWRITE) + ((_S_IREAD|_S_IWRITE) >> 3) + - ((_S_IREAD|_S_IWRITE) >> 6)) | S_IFDIR; - - req->last_error = ERROR_SUCCESS; - req->errorno = UV_OK; - req->result = 0; - req->ptr = &req->stat; + handle = CreateFileW(path, + FILE_READ_ATTRIBUTES, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + NULL, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS, + NULL); + if (handle == INVALID_HANDLE_VALUE) { + SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); return; } - file = FindFirstFileExW(path, FindExInfoStandard, &ent, - FindExSearchNameMatch, NULL, 0); - - if (file == INVALID_HANDLE_VALUE) { + if (!GetFileInformationByHandle(handle, &info)) { SET_REQ_RESULT_WIN32_ERROR(req, GetLastError()); + CloseHandle(handle); return; } - FindClose(file); - - 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); - } + memset(&req->stat, 0, sizeof req->stat); - return; - } + /* TODO: set st_dev and st_ino? */ - 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; - - if (ent.dwFileAttributes & FILE_ATTRIBUTE_READONLY ) { + if (info.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) { + if (info.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)); + uv_filetime_to_time_t(&info.ftLastWriteTime, &(req->stat.st_mtime)); + uv_filetime_to_time_t(&info.ftLastAccessTime, &(req->stat.st_atime)); + uv_filetime_to_time_t(&info.ftCreationTime, &(req->stat.st_ctime)); + + req->stat.st_size = ((int64_t) info.nFileSizeHigh << 32) + + (int64_t) info.nFileSizeLow; - req->stat.st_size = ((int64_t)ent.nFileSizeHigh << 32) + - (int64_t)ent.nFileSizeLow; + req->stat.st_nlink = info.nNumberOfLinks; req->ptr = &req->stat; req->result = 0; + + CloseHandle(handle); } diff --git a/deps/uv/test/test-fs.c b/deps/uv/test/test-fs.c index b88636b01d..109ae014b4 100644 --- a/deps/uv/test/test-fs.c +++ b/deps/uv/test/test-fs.c @@ -184,6 +184,13 @@ static void chown_cb(uv_fs_t* req) { uv_fs_req_cleanup(req); } +static void chown_root_cb(uv_fs_t* req) { + ASSERT(req->fs_type == UV_FS_CHOWN); + ASSERT(req->result == -1); + ASSERT(req->errorno == UV_EPERM); + chown_cb_count++; + uv_fs_req_cleanup(req); +} static void unlink_cb(uv_fs_t* req) { ASSERT(req == &unlink_req); @@ -1018,6 +1025,12 @@ TEST_IMPL(fs_chown) { uv_run(loop); ASSERT(chown_cb_count == 1); + /* chown to root (fail) */ + chown_cb_count = 0; + r = uv_fs_chown(loop, &req, "test_file", 0, 0, chown_root_cb); + uv_run(loop); + ASSERT(chown_cb_count == 1); + /* async fchown */ r = uv_fs_fchown(loop, &req, file, -1, -1, fchown_cb); ASSERT(r == 0); @@ -1296,6 +1309,19 @@ TEST_IMPL(fs_stat_root) { r = uv_fs_stat(loop, &stat_req, "\\", NULL); ASSERT(r == 0); + r = uv_fs_stat(loop, &stat_req, "..\\..\\..\\..\\..\\..\\..", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(loop, &stat_req, "..", NULL); + ASSERT(r == 0); + + r = uv_fs_stat(loop, &stat_req, "..\\", NULL); + ASSERT(r == 0); + + /* stats the current directory on c: */ + r = uv_fs_stat(loop, &stat_req, "c:", NULL); + ASSERT(r == 0); + r = uv_fs_stat(loop, &stat_req, "c:\\", NULL); ASSERT(r == 0);