diff options
-rw-r--r-- | lib/pure/os.nim | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim index bd5e83432..688f9a88f 100644 --- a/lib/pure/os.nim +++ b/lib/pure/os.nim @@ -836,9 +836,11 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", ## ## If this fails, `EOS` is raised. On the Windows platform this proc will ## copy the source file's attributes into dest. On other platforms you need - ## to use getFilePermissions and setFilePermissions to copy them by hand, - ## otherwise `dest` will inherit the default permissions of a newly created - ## file for the user. + ## to use getFilePermissions and setFilePermissions to copy them by hand (or + ## use the convenience copyFileWithPermissions() proc), otherwise `dest` will + ## inherit the default permissions of a newly created file for the user. If + ## `dest` already exists, the file attributes will be preserved and the + ## content overwritten. when defined(Windows): when useWinUnicode: let s = newWideCString(source) @@ -1383,6 +1385,26 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {. var res2 = SetFileAttributesA(filename, res) if res2 == - 1'i32: OSError(OSLastError()) +proc copyFileWithPermissions*(source, dest: string, + ignorePermissionErrors = true) = + ## Copies a file from `source` to `dest` preserving file permissions. + ## + ## This is a wrapper proc around copyFile, getFilePermissions and + ## setFilePermissions on non Windows platform. On windows this proc is just a + ## wrapper for copyFile since that proc already copies attributes. + ## + ## On non windows systems permissions are copied after the file itself has + ## been copied, which won't happen atomically and could lead to a race + ## condition. If ignorePermissionErrors is true, errors while reading/setting + ## file attributes will be ignored, otherwise will raise `OSError`. + copyFile(source, dest) + when not defined(Windows): + try: + setFilePermissions(dest, getFilePermissions(source)) + except: + if not ignorePermissionErrors: + raise + proc inclFilePermissions*(filename: string, permissions: set[TFilePermission]) {. rtl, extern: "nos$1", tags: [FReadDir, FWriteDir].} = |