win,fs: fix mkdir returning EPERM on network drives
On Windows network drives (SSHFS/FTP), CreateDirectoryW returns ERROR_ACCESS_DENIED instead of ERROR_ALREADY_EXISTS when a directory already exists. This caused uv_fs_mkdir to return UV_EPERM instead of the expected UV_EEXIST. Fix by checking if ERROR_ACCESS_DENIED refers to an existing directory and mapping it to UV_EEXIST. Fixes: #4959
This commit is contained in:
parent
01250432eb
commit
7cda217af3
11
src/win/fs.c
11
src/win/fs.c
@ -1253,11 +1253,22 @@ static void fs__unlink(uv_fs_t* req) {
|
||||
|
||||
|
||||
void fs__mkdir(uv_fs_t* req) {
|
||||
DWORD attr;
|
||||
|
||||
/* TODO: use req->mode. */
|
||||
if (CreateDirectoryW(req->file.pathw, NULL)) {
|
||||
SET_REQ_RESULT(req, 0);
|
||||
} else {
|
||||
SET_REQ_WIN32_ERROR(req, GetLastError());
|
||||
if (req->sys_errno_ == ERROR_ACCESS_DENIED) {
|
||||
/* Check if the directory already exists. */
|
||||
attr = GetFileAttributesW(req->file.pathw);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES &&
|
||||
(attr & FILE_ATTRIBUTE_DIRECTORY)) {
|
||||
req->sys_errno_ = ERROR_ALREADY_EXISTS;
|
||||
req->result = UV_EEXIST;
|
||||
}
|
||||
}
|
||||
if (req->sys_errno_ == ERROR_INVALID_NAME ||
|
||||
req->sys_errno_ == ERROR_DIRECTORY)
|
||||
req->result = UV_EINVAL;
|
||||
|
||||
@ -4928,3 +4928,30 @@ TEST_IMPL(fs_wtf) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_IMPL(fs_mkdir_existing) {
|
||||
int r;
|
||||
uv_fs_t req;
|
||||
|
||||
loop = uv_default_loop();
|
||||
|
||||
/* Setup */
|
||||
unlink("test_dir/file");
|
||||
rmdir("test_dir");
|
||||
|
||||
/* Create directory */
|
||||
r = uv_fs_mkdir(NULL, &req, "test_dir", 0755, NULL);
|
||||
ASSERT_OK(r);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* Create directory again - synchronous */
|
||||
r = uv_fs_mkdir(NULL, &req, "test_dir", 0755, NULL);
|
||||
ASSERT_EQ(r, UV_EEXIST);
|
||||
uv_fs_req_cleanup(&req);
|
||||
|
||||
/* Cleanup */
|
||||
rmdir("test_dir");
|
||||
|
||||
MAKE_VALGRIND_HAPPY(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -365,6 +365,7 @@ TEST_DECLARE (fs_async_dir)
|
||||
TEST_DECLARE (fs_async_sendfile)
|
||||
TEST_DECLARE (fs_async_sendfile_nodata)
|
||||
TEST_DECLARE (fs_mkdtemp)
|
||||
TEST_DECLARE (fs_mkdir_existing)
|
||||
TEST_DECLARE (fs_mkstemp)
|
||||
TEST_DECLARE (fs_fstat)
|
||||
TEST_DECLARE (fs_fstat_stdio)
|
||||
@ -1089,6 +1090,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (fs_async_sendfile)
|
||||
TEST_ENTRY (fs_async_sendfile_nodata)
|
||||
TEST_ENTRY (fs_mkdtemp)
|
||||
TEST_ENTRY (fs_mkdir_existing)
|
||||
TEST_ENTRY (fs_mkstemp)
|
||||
TEST_ENTRY (fs_fstat)
|
||||
TEST_ENTRY (fs_fstat_stdio)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user