Bug 921229 - Remove files with the read-only flag set. r=yoric

This commit is contained in:
Felix H. Dahlke 2013-10-29 09:27:01 +01:00
parent 6333fdb2b2
commit 67d88b1309
4 changed files with 44 additions and 5 deletions

View File

@ -651,6 +651,9 @@ static const dom::ConstantSpec gWinProperties[] =
INT_CONSTANT(MOVEFILE_COPY_ALLOWED),
INT_CONSTANT(MOVEFILE_REPLACE_EXISTING),
// GetFileAttributes error constant
INT_CONSTANT(INVALID_FILE_ATTRIBUTES),
// Errors
INT_CONSTANT(ERROR_ACCESS_DENIED),
INT_CONSTANT(ERROR_DIR_NOT_EMPTY),

View File

@ -345,6 +345,17 @@
"FlushFileBuffers", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*file*/ Type.HANDLE);
declareLazyFFI(SysFile, "GetFileAttributes", libc,
"GetFileAttributesW", ctypes.winapi_abi,
/*return*/ Type.DWORD,
/*fileName*/ Type.path);
declareLazyFFI(SysFile, "SetFileAttributes", libc,
"SetFileAttributesW", ctypes.winapi_abi,
/*return*/ Type.zero_or_nothing,
/*fileName*/ Type.path,
/*fileAttributes*/ Type.DWORD);
};
exports.OS.Win = {

View File

@ -382,14 +382,27 @@
* @throws {OS.File.Error} In case of I/O error.
*/
File.remove = function remove(path, options = {}) {
let result = WinFile.DeleteFile(path);
if (!result) {
if ((!("ignoreAbsent" in options) || options.ignoreAbsent) &&
ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND) {
if (WinFile.DeleteFile(path)) {
return;
}
if (ctypes.winLastError == Const.ERROR_FILE_NOT_FOUND) {
if ((!("ignoreAbsent" in options) || options.ignoreAbsent)) {
return;
}
throw new File.Error("remove");
} else if (ctypes.winLastError == Const.ERROR_ACCESS_DENIED) {
let attributes = WinFile.GetFileAttributes(path);
if (attributes != Const.INVALID_FILE_ATTRIBUTES &&
attributes & Const.FILE_ATTRIBUTE_READONLY) {
let newAttributes = attributes & ~Const.FILE_ATTRIBUTE_READONLY;
if (WinFile.SetFileAttributes(path, newAttributes) &&
WinFile.DeleteFile(path)) {
return;
}
}
}
throw new File.Error("remove");
};
/**

View File

@ -844,4 +844,16 @@ function test_remove_file()
OS.File.remove(absent_file_name);
});
ok(!exn, "test_remove_file: ignoreAbsent works");
if (OS.Win) {
let file_name = "test_osfile_front_file_to_remove.tmp";
let file = OS.File.open(file_name, {write: true});
file.close();
ok(OS.File.exists(file_name), "test_remove_file: test file exists");
OS.Win.File.SetFileAttributes(file_name,
OS.Constants.Win.FILE_ATTRIBUTE_READONLY);
OS.File.remove(file_name);
ok(!OS.File.exists(file_name),
"test_remove_file: test file has been removed");
}
}