win,fs: fix readlink errno for a non-symlink file (#3719)

In Node.js, fs.readlink() on a non-symlink file used to throw an UNKNOWN
error on Windows. This change maps ERROR_NOT_A_REPARSE_POINT to
UV_EINVAL, so that now it throws EINVAL just like other platforms.

This is handled explicitly in `fs__readlink`, since elsewhere it might
map to EPERM instead (such as in `link`).
This commit is contained in:
Darshan Sen 2023-01-18 08:34:52 +05:30 committed by GitHub
parent 1279a20c03
commit 7fd7e8264f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 13 deletions

View File

@ -2662,7 +2662,10 @@ static void fs__readlink(uv_fs_t* req) {
}
if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) {
SET_REQ_WIN32_ERROR(req, GetLastError());
DWORD error = GetLastError();
SET_REQ_WIN32_ERROR(req, error);
if (error == ERROR_NOT_A_REPARSE_POINT)
req->result = UV_EINVAL;
CloseHandle(handle);
return;
}

View File

@ -2047,20 +2047,53 @@ TEST_IMPL(fs_link) {
TEST_IMPL(fs_readlink) {
uv_fs_t req;
/* Must return UV_ENOENT on an inexistent file */
{
uv_fs_t req;
loop = uv_default_loop();
ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(dummy_cb_count == 1);
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
loop = uv_default_loop();
ASSERT(0 == uv_fs_readlink(loop, &req, "no_such_file", dummy_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(dummy_cb_count == 1);
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL));
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
ASSERT(UV_ENOENT == uv_fs_readlink(NULL, &req, "no_such_file", NULL));
ASSERT_NULL(req.ptr);
ASSERT(req.result == UV_ENOENT);
uv_fs_req_cleanup(&req);
}
/* Must return UV_EINVAL on a non-symlink file */
{
int r;
uv_fs_t req;
uv_file file;
/* Setup */
/* Create a non-symlink file */
r = uv_fs_open(NULL, &req, "test_file", O_RDWR | O_CREAT,
S_IWUSR | S_IRUSR, NULL);
ASSERT_GE(r, 0);
ASSERT_GE(req.result, 0);
file = req.result;
uv_fs_req_cleanup(&req);
r = uv_fs_close(NULL, &req, file, NULL);
ASSERT_EQ(r, 0);
ASSERT_EQ(req.result, 0);
uv_fs_req_cleanup(&req);
/* Test */
r = uv_fs_readlink(NULL, &req, "test_file", NULL);
ASSERT_EQ(r, UV_EINVAL);
uv_fs_req_cleanup(&req);
/* Cleanup */
unlink("test_file");
}
MAKE_VALGRIND_HAPPY();
return 0;