@@ -1598,10 +1598,11 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission],
15981598 noWeirdTarget .} =
15991599 # # Sets the file permissions for `filename`.
16001600 # #
1601- # # If `` followSymlinks` ` set to true (default) and ``filename`` points to a
1601+ # # If `followSymlinks` set to true (default) and ``filename`` points to a
16021602 # # symlink, permissions are set to the file symlink points to.
1603- # # ``followSymlinks`` set to false do not affect on Windows and some POSIX
1604- # # systems (including Linux) which do not have ``lchmod`` available.
1603+ # # `followSymlinks` set to false is a noop on Windows and some POSIX
1604+ # # systems (including Linux) on which `lchmod` is either unavailable or always
1605+ # # fails, given that symlinks permissions there are not observed.
16051606 # #
16061607 # # `OSError` is raised in case of an error.
16071608 # # On Windows, only the ``readonly`` flag is changed, depending on
@@ -1625,7 +1626,7 @@ proc setFilePermissions*(filename: string, permissions: set[FilePermission],
16251626 if fpOthersExec in permissions: p = p or S_IXOTH .Mode
16261627
16271628 if not followSymlinks and filename.symlinkExists:
1628- when hasLchmod :
1629+ when declared (lchmod) :
16291630 if lchmod (filename, cast [Mode ](p)) != 0 :
16301631 raiseOSError (osLastError (), $ (filename, permissions))
16311632 else :
@@ -1653,16 +1654,16 @@ proc createSymlink*(src, dest: string) {.noWeirdTarget.} =
16531654 # #
16541655 # # **Warning**:
16551656 # # Some OS's (such as Microsoft Windows) restrict the creation
1656- # # of symlinks to root users (administrators).
1657+ # # of symlinks to root users (administrators) or users with developper mode enabled .
16571658 # #
16581659 # # See also:
16591660 # # * `createHardlink proc <#createHardlink,string,string>`_
16601661 # # * `expandSymlink proc <#expandSymlink,string>`_
16611662
16621663 when defined (Windows ):
1663- # 2 is the SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE. This allows
1664- # anyone with developer mode on to create a link
1665- let flag = dirExists (src).int32 or 2
1664+ const SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE = 2
1665+ # allows anyone with developer mode on to create a link
1666+ let flag = dirExists (src).int32 or SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
16661667 when useWinUnicode:
16671668 var wSrc = newWideCString (src)
16681669 var wDst = newWideCString (dest)
@@ -1678,7 +1679,7 @@ proc createSymlink*(src, dest: string) {.noWeirdTarget.} =
16781679proc expandSymlink * (symlinkPath: string ): string {.noWeirdTarget .} =
16791680 # # Returns a string representing the path to which the symbolic link points.
16801681 # #
1681- # # On Windows this is a noop, `` symlinkPath` ` is simply returned.
1682+ # # On Windows this is a noop, `symlinkPath` is simply returned.
16821683 # #
16831684 # # See also:
16841685 # # * `createSymlink proc <#createSymlink,string,string>`_
@@ -1740,16 +1741,27 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}) {.rtl,
17401741 if isSymlink and cfSymlinkIgnore in options:
17411742 return
17421743 when defined (Windows ):
1744+ proc handleOSError =
1745+ const ERROR_PRIVILEGE_NOT_HELD = 1314
1746+ let errCode = osLastError ()
1747+ let context = $ (source, dest, options)
1748+ if isSymlink and errCode.int32 == ERROR_PRIVILEGE_NOT_HELD :
1749+ stderr.write (" Failed copy the symlink: error " & $ errCode & " : " &
1750+ osErrorMsg (errCode) & " Additional info: " & context &
1751+ " \n " )
1752+ else :
1753+ raiseOSError (errCode, context)
1754+
17431755 let dwCopyFlags = if cfSymlinkAsIs in options: COPY_FILE_COPY_SYMLINK else : 0 'i32
17441756 var pbCancel = 0 'i32
17451757 when useWinUnicode:
17461758 let s = newWideCString (source)
17471759 let d = newWideCString (dest)
17481760 if copyFileExW (s, d, nil , nil , addr pbCancel, dwCopyFlags) == 0 'i32 :
1749- raiseOSError ( osLastError (), $ (source, dest, options) )
1761+ handleOSError ( )
17501762 else :
17511763 if copyFileExA (source, dest, nil , nil , addr pbCancel, dwCopyFlags) == 0 'i32 :
1752- raiseOSError ( osLastError (), $ (source, dest, options) )
1764+ handleOSError ( )
17531765 else :
17541766 if isSymlink and cfSymlinkAsIs in options:
17551767 createSymlink (expandSymlink (source), dest)
0 commit comments