mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 03:44:14 +00:00
Merge pull request #762 from Varriount/os/fix-removeFile2
Fix os.removeFile behavior on windows (again)
This commit is contained in:
@@ -970,17 +970,37 @@ proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
|
||||
if crename(source, dest) != 0'i32:
|
||||
raise newException(EOS, $strerror(errno))
|
||||
|
||||
when not defined(ENOENT):
|
||||
when not defined(ENOENT) and not defined(Windows):
|
||||
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].} =
|
||||
## Removes the `file`. If this fails, `EOS` is raised. This does not fail
|
||||
## if the file never existed in the first place.
|
||||
## On Windows, ignores the read-only attribute.
|
||||
when defined(Windows):
|
||||
setFilePermissions(file, {fpUserWrite})
|
||||
if cremove(file) != 0'i32 and errno != ENOENT:
|
||||
raise newException(EOS, $strerror(errno))
|
||||
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:
|
||||
raise newException(EOS, $strerror(errno))
|
||||
|
||||
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
|
||||
tags: [FExecIO].} =
|
||||
|
||||
@@ -416,17 +416,17 @@ var
|
||||
SOMAXCONN* {.importc, header: "Winsock2.h".}: cint
|
||||
INVALID_SOCKET* {.importc, header: "Winsock2.h".}: TSocketHandle
|
||||
SOL_SOCKET* {.importc, header: "Winsock2.h".}: cint
|
||||
SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording
|
||||
SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen()
|
||||
SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse
|
||||
SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive
|
||||
SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses
|
||||
SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs
|
||||
SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible
|
||||
SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present
|
||||
SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line
|
||||
|
||||
SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint
|
||||
SO_DEBUG* {.importc, header: "Winsock2.h".}: cint ## turn on debugging info recording
|
||||
SO_ACCEPTCONN* {.importc, header: "Winsock2.h".}: cint # socket has had listen()
|
||||
SO_REUSEADDR* {.importc, header: "Winsock2.h".}: cint # allow local address reuse
|
||||
SO_KEEPALIVE* {.importc, header: "Winsock2.h".}: cint # keep connections alive
|
||||
SO_DONTROUTE* {.importc, header: "Winsock2.h".}: cint # just use interface addresses
|
||||
SO_BROADCAST* {.importc, header: "Winsock2.h".}: cint # permit sending of broadcast msgs
|
||||
SO_USELOOPBACK* {.importc, header: "Winsock2.h".}: cint # bypass hardware when possible
|
||||
SO_LINGER* {.importc, header: "Winsock2.h".}: cint # linger on close if data present
|
||||
SO_OOBINLINE* {.importc, header: "Winsock2.h".}: cint # leave received OOB data in line
|
||||
|
||||
SO_DONTLINGER* {.importc, header: "Winsock2.h".}: cint
|
||||
SO_EXCLUSIVEADDRUSE* {.importc, header: "Winsock2.h".}: cint # disallow local address reuse
|
||||
|
||||
proc `==`*(x, y: TSocketHandle): bool {.borrow.}
|
||||
@@ -553,18 +553,26 @@ const
|
||||
|
||||
FILE_FLAG_BACKUP_SEMANTICS* = 33554432'i32
|
||||
|
||||
# Error Constants
|
||||
const
|
||||
ERROR_ACCESS_DENIED* = 5
|
||||
|
||||
when useWinUnicode:
|
||||
proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD,
|
||||
lpSecurityAttributes: pointer,
|
||||
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
||||
hTemplateFile: THANDLE): THANDLE {.
|
||||
stdcall, dynlib: "kernel32", importc: "CreateFileW".}
|
||||
proc DeleteFileW*(pathName: widecstring): int32 {.
|
||||
importc: "DeleteFileW", dynlib: "kernel32", stdcall.}
|
||||
else:
|
||||
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
|
||||
lpSecurityAttributes: pointer,
|
||||
dwCreationDisposition, dwFlagsAndAttributes: DWORD,
|
||||
hTemplateFile: THANDLE): THANDLE {.
|
||||
stdcall, dynlib: "kernel32", importc: "CreateFileA".}
|
||||
proc DeleteFileA*(pathName: cstring): int32 {.
|
||||
importc: "DeleteFileA", dynlib: "kernel32", stdcall.}
|
||||
|
||||
proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
|
||||
importc: "SetEndOfFile".}
|
||||
|
||||
Reference in New Issue
Block a user