os.nim - Modify removeFile to use native Windows API calls

This commit is contained in:
Clay Sweetser 2013-12-18 15:32:26 -05:00
commit c26e787e5d

View file

@ -972,8 +972,16 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
when not defined(ENOENT): when not defined(ENOENT):
var ENOENT {.importc, header: "<errno.h>".}: cint var ENOENT {.importc, header: "<errno.h>".}: cint
when not defined(EACCES):
var EACCES {.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
@ -981,11 +989,18 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
## On Windows, ignores the read-only attribute. ## On Windows, ignores the read-only attribute.
if cremove(file) != 0'i32 and errno != ENOENT: if cremove(file) != 0'i32 and errno != ENOENT:
when defined(Windows): when defined(Windows):
if errno == EACCES: # Turn this into a case stmt? when useWinUnicode:
setFilePermissions(file, {fpUserWrite}) # Use lower level code? let f = newWideCString(file)
if cremove(file) != 0'i32 and errno != ENOENT:
raise newException(EOS, $strerror(errno))
else: 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:
raise newException(EOS, $strerror(errno)) raise newException(EOS, $strerror(errno))
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1", proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",