mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
Added moveDir (#6015)
This commit is contained in:
committed by
Andreas Rumpf
parent
baf685461b
commit
0345238d6e
@@ -666,29 +666,38 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [WriteDirEffect].}
|
||||
else:
|
||||
raiseOSError(osLastError(), $strerror(errno))
|
||||
|
||||
proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
|
||||
tags: [ReadIOEffect, WriteIOEffect].} =
|
||||
## Moves a file from `source` to `dest`. If this fails, `OSError` is raised.
|
||||
proc tryMoveFSObject(source, dest: string): bool =
|
||||
## Moves a file or directory from `source` to `dest`. Returns false in case
|
||||
## of `EXDEV` error. In case of other errors `OSError` is raised. Returns
|
||||
## true in case of success.
|
||||
when defined(Windows):
|
||||
when useWinUnicode:
|
||||
let s = newWideCString(source)
|
||||
let d = newWideCString(dest)
|
||||
if moveFileW(s, d) == 0'i32: raiseOSError(osLastError())
|
||||
if moveFileExW(s, d, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError())
|
||||
else:
|
||||
if moveFileA(source, dest) == 0'i32: raiseOSError(osLastError())
|
||||
if moveFileExA(source, dest, MOVEFILE_COPY_ALLOWED) == 0'i32: raiseOSError(osLastError())
|
||||
else:
|
||||
if c_rename(source, dest) != 0'i32:
|
||||
let err = osLastError()
|
||||
if err == EXDEV.OSErrorCode:
|
||||
# Fallback to copy & del
|
||||
copyFile(source, dest)
|
||||
try:
|
||||
removeFile(source)
|
||||
except:
|
||||
discard tryRemoveFile(dest)
|
||||
raise
|
||||
return false
|
||||
else:
|
||||
raiseOSError(err, $strerror(errno))
|
||||
return true
|
||||
|
||||
proc moveFile*(source, dest: string) {.rtl, extern: "nos$1",
|
||||
tags: [ReadIOEffect, WriteIOEffect].} =
|
||||
## Moves a file from `source` to `dest`. If this fails, `OSError` is raised.
|
||||
if not tryMoveFSObject(source, dest):
|
||||
when not defined(windows):
|
||||
# Fallback to copy & del
|
||||
copyFile(source, dest)
|
||||
try:
|
||||
removeFile(source)
|
||||
except:
|
||||
discard tryRemoveFile(dest)
|
||||
raise
|
||||
|
||||
proc execShellCmd*(command: string): int {.rtl, extern: "nos$1",
|
||||
tags: [ExecIOEffect].} =
|
||||
@@ -1369,6 +1378,14 @@ proc exclFilePermissions*(filename: string,
|
||||
## setFilePermissions(filename, getFilePermissions(filename)-permissions)
|
||||
setFilePermissions(filename, getFilePermissions(filename)-permissions)
|
||||
|
||||
proc moveDir*(source, dest: string) {.tags: [ReadIOEffect, WriteIOEffect].} =
|
||||
## Moves a directory from `source` to `dest`. If this fails, `OSError` is raised.
|
||||
if not tryMoveFSObject(source, dest):
|
||||
when not defined(windows):
|
||||
# Fallback to copy & del
|
||||
copyDir(source, dest)
|
||||
removeDir(source)
|
||||
|
||||
include ospaths
|
||||
|
||||
proc expandSymlink*(symlinkPath: string): string =
|
||||
|
||||
@@ -291,6 +291,14 @@ const
|
||||
FILE_ATTRIBUTE_TEMPORARY* = 256'i32
|
||||
|
||||
MAX_PATH* = 260
|
||||
|
||||
MOVEFILE_COPY_ALLOWED* = 0x2'i32
|
||||
MOVEFILE_CREATE_HARDLINK* = 0x10'i32
|
||||
MOVEFILE_DELAY_UNTIL_REBOOT* = 0x4'i32
|
||||
MOVEFILE_FAIL_IF_NOT_TRACKABLE* = 0x20'i32
|
||||
MOVEFILE_REPLACE_EXISTING* = 0x1'i32
|
||||
MOVEFILE_WRITE_THROUGH* = 0x8'i32
|
||||
|
||||
type
|
||||
WIN32_FIND_DATA* {.pure.} = object
|
||||
dwFileAttributes*: int32
|
||||
@@ -342,6 +350,9 @@ when useWinUnicode:
|
||||
|
||||
proc moveFileW*(lpExistingFileName, lpNewFileName: WideCString): WINBOOL {.
|
||||
importc: "MoveFileW", stdcall, dynlib: "kernel32".}
|
||||
proc moveFileExW*(lpExistingFileName, lpNewFileName: WideCString,
|
||||
flags: DWORD): WINBOOL {.
|
||||
importc: "MoveFileExW", stdcall, dynlib: "kernel32".}
|
||||
|
||||
proc getEnvironmentStringsW*(): WideCString {.
|
||||
stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".}
|
||||
@@ -369,6 +380,9 @@ else:
|
||||
|
||||
proc moveFileA*(lpExistingFileName, lpNewFileName: cstring): WINBOOL {.
|
||||
importc: "MoveFileA", stdcall, dynlib: "kernel32".}
|
||||
proc moveFileExA*(lpExistingFileName, lpNewFileName: WideCString,
|
||||
flags: DWORD): WINBOOL {.
|
||||
importc: "MoveFileExA", stdcall, dynlib: "kernel32".}
|
||||
|
||||
proc getEnvironmentStringsA*(): cstring {.
|
||||
stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".}
|
||||
|
||||
Reference in New Issue
Block a user