Merge pull request #762 from Varriount/os/fix-removeFile2

Fix os.removeFile behavior on windows (again)
This commit is contained in:
Andreas Rumpf 2013-12-18 13:24:20 -08:00
commit e0f95b5d27
2 changed files with 43 additions and 15 deletions

View file

@ -970,15 +970,35 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
if crename(source, dest) != 0'i32: if crename(source, dest) != 0'i32:
raise newException(EOS, $strerror(errno)) raise newException(EOS, $strerror(errno))
when not defined(ENOENT): when not defined(ENOENT) and not defined(Windows):
var ENOENT {.importc, header: "<errno.h>".}: cint var ENOENT {.importc, header: "<errno.h>".}: cint
when defined(Windows):
when useWinUnicode:
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileW(file)
template SetFileAttributes(file, attrs: expr): expr {.immediate.} =
SetFileAttributesW(file, attrs)
else:
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileA(file)
template SetFileAttributes(file, attrs: expr): expr {.immediate.} =
SetFileAttributesA(file, attrs)
proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
## Removes the `file`. If this fails, `EOS` is raised. This does not fail ## Removes the `file`. If this fails, `EOS` is raised. This does not fail
## if the file never existed in the first place. ## if the file never existed in the first place.
## On Windows, ignores the read-only attribute. ## On Windows, ignores the read-only attribute.
when defined(Windows): when defined(Windows):
setFilePermissions(file, {fpUserWrite}) when useWinUnicode:
let f = newWideCString(file)
else:
let f = file
if DeleteFile(f) == 0:
if GetLastError() == ERROR_ACCESS_DENIED:
if SetFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0:
OSError(OSLastError())
if DeleteFile(f) == 0:
OSError(OSLastError())
else:
if cremove(file) != 0'i32 and errno != ENOENT: if cremove(file) != 0'i32 and errno != ENOENT:
raise newException(EOS, $strerror(errno)) raise newException(EOS, $strerror(errno))

View file

@ -553,18 +553,26 @@ const
FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32 FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
# Error Constants
const
ERROR_ACCESS_DENIED* = 5
when useWinUnicode: when useWinUnicode:
proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD, proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD,
lpSecurityAttributes: pointer, lpSecurityAttributes: pointer,
dwCreationDisposition, dwFlagsAndAttributes: DWORD, dwCreationDisposition, dwFlagsAndAttributes: DWORD,
hTemplateFile: THANDLE): THANDLE {. hTemplateFile: THANDLE): THANDLE {.
stdcall, dynlib: "kernel32", importc: "CreateFileW".} stdcall, dynlib: "kernel32", importc: "CreateFileW".}
proc DeleteFileW*(pathName: widecstring): int32 {.
importc: "DeleteFileW", dynlib: "kernel32", stdcall.}
else: else:
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
lpSecurityAttributes: pointer, lpSecurityAttributes: pointer,
dwCreationDisposition, dwFlagsAndAttributes: DWORD, dwCreationDisposition, dwFlagsAndAttributes: DWORD,
hTemplateFile: THANDLE): THANDLE {. hTemplateFile: THANDLE): THANDLE {.
stdcall, dynlib: "kernel32", importc: "CreateFileA".} stdcall, dynlib: "kernel32", importc: "CreateFileA".}
proc DeleteFileA*(pathName: cstring): int32 {.
importc: "DeleteFileA", dynlib: "kernel32", stdcall.}
proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "SetEndOfFile".} importc: "SetEndOfFile".}