Skip to content

Commit

Permalink
win, fs: fix uv_fs_unlink for +R -A files
Browse files Browse the repository at this point in the history
uv_fs_unlink would fail for read-only files with Archive attribute
cleared. This fixes this issue.

PR-URL: #1774
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
  • Loading branch information
bzoz committed Mar 21, 2018
1 parent ee875f9 commit edf05b9
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/win/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,9 @@ void fs__unlink(uv_fs_t* req) {
/* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 };

basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY);
basic.FileAttributes = info.dwFileAttributes
& ~(FILE_ATTRIBUTE_READONLY)
| FILE_ATTRIBUTE_ARCHIVE;

status = pNtSetInformationFile(handle,
&iosb,
Expand Down
58 changes: 58 additions & 0 deletions test/test-fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1474,6 +1474,64 @@ TEST_IMPL(fs_unlink_readonly) {
return 0;
}

#ifdef _WIN32
TEST_IMPL(fs_unlink_archive_readonly) {
int r;
uv_fs_t req;
uv_file file;

/* Setup. */
unlink("test_file");

loop = uv_default_loop();

r = uv_fs_open(NULL,
&req,
"test_file",
O_RDWR | O_CREAT,
S_IWUSR | S_IRUSR,
NULL);
ASSERT(r >= 0);
ASSERT(req.result >= 0);
file = req.result;
uv_fs_req_cleanup(&req);

iov = uv_buf_init(test_buf, sizeof(test_buf));
r = uv_fs_write(NULL, &req, file, &iov, 1, -1, NULL);
ASSERT(r == sizeof(test_buf));
ASSERT(req.result == sizeof(test_buf));
uv_fs_req_cleanup(&req);

close(file);

/* Make the file read-only and clear archive flag */
r = SetFileAttributes("test_file", FILE_ATTRIBUTE_READONLY);
ASSERT(r != 0);
uv_fs_req_cleanup(&req);

check_permission("test_file", 0400);

/* Try to unlink the file */
r = uv_fs_unlink(NULL, &req, "test_file", NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);

/*
* Run the loop just to check we don't have make any extraneous uv_ref()
* calls. This should drop out immediately.
*/
uv_run(loop, UV_RUN_DEFAULT);

/* Cleanup. */
uv_fs_chmod(NULL, &req, "test_file", 0600, NULL);
uv_fs_req_cleanup(&req);
unlink("test_file");

MAKE_VALGRIND_HAPPY();
return 0;
}
#endif

TEST_IMPL(fs_chown) {
int r;
Expand Down
6 changes: 6 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,9 @@ TEST_DECLARE (fs_access)
TEST_DECLARE (fs_chmod)
TEST_DECLARE (fs_copyfile)
TEST_DECLARE (fs_unlink_readonly)
#ifdef _WIN32
TEST_DECLARE (fs_unlink_archive_readonly)
#endif
TEST_DECLARE (fs_chown)
TEST_DECLARE (fs_link)
TEST_DECLARE (fs_readlink)
Expand Down Expand Up @@ -815,6 +818,9 @@ TASK_LIST_START
TEST_ENTRY (fs_chmod)
TEST_ENTRY (fs_copyfile)
TEST_ENTRY (fs_unlink_readonly)
#ifdef _WIN32
TEST_ENTRY (fs_unlink_archive_readonly)
#endif
TEST_ENTRY (fs_chown)
TEST_ENTRY (fs_utime)
TEST_ENTRY (fs_futime)
Expand Down

0 comments on commit edf05b9

Please sign in to comment.