Merge pull request #1892 from jhasse/windows-readonly

Delete read-only files on Windows, too
This commit is contained in:
Jan Niklas Hasse 2021-02-10 08:51:56 +01:00 committed by GitHub
commit a999fdb0d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 25 additions and 2 deletions

View File

@ -265,6 +265,23 @@ FileReader::Status RealDiskInterface::ReadFile(const string& path,
}
int RealDiskInterface::RemoveFile(const string& path) {
#ifdef _WIN32
DWORD attributes = GetFileAttributes(path.c_str());
if (attributes == INVALID_FILE_ATTRIBUTES &&
GetLastError() == ERROR_FILE_NOT_FOUND) {
return 1;
}
if (attributes & FILE_ATTRIBUTE_READONLY) {
// On non-Windows systems remove will happily delete read-only files. On
// Windows Ninja should behave the same. See
// https://github.com/ninja-build/ninja/issues/1886
SetFileAttributes(path.c_str(), attributes & ~FILE_ATTRIBUTE_READONLY);
}
if (!DeleteFile(path.c_str())) {
Error("remove(%s): %s", path.c_str(), GetLastErrorString().c_str());
return -1;
}
#else
if (remove(path.c_str()) < 0) {
switch (errno) {
case ENOENT:
@ -273,9 +290,9 @@ int RealDiskInterface::RemoveFile(const string& path) {
Error("remove(%s): %s", path.c_str(), strerror(errno));
return -1;
}
} else {
return 0;
}
#endif
return 0;
}
void RealDiskInterface::AllowStatCache(bool allow) {

View File

@ -211,6 +211,12 @@ TEST_F(DiskInterfaceTest, RemoveFile) {
EXPECT_EQ(0, disk_.RemoveFile(kFileName));
EXPECT_EQ(1, disk_.RemoveFile(kFileName));
EXPECT_EQ(1, disk_.RemoveFile("does not exist"));
#ifdef _WIN32
ASSERT_TRUE(Touch(kFileName));
EXPECT_EQ(0, system((std::string("attrib +R ") + kFileName).c_str()));
EXPECT_EQ(0, disk_.RemoveFile(kFileName));
EXPECT_EQ(1, disk_.RemoveFile(kFileName));
#endif
}
struct StatTest : public StateTestWithBuiltinRules,