From 0345238d6e90cf4daffe301e0c82a6e30741b2e2 Mon Sep 17 00:00:00 2001 From: Yuriy Glukhov Date: Tue, 27 Jun 2017 11:09:41 +0300 Subject: Added moveDir (#6015) --- lib/pure/os.nim | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) (limited to 'lib/pure') diff --git a/lib/pure/os.nim b/lib/pure/os.nim index 98b6aa309..b4cbd200c 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -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 = -- cgit 1.4.1-2-gfad0