Skip to content

Commit d3bd6dc

Browse files
Roman Inflianskastimotheecour
andcommitted
Address comments in #16709
Co-authored-by: Timothee Cour <[email protected]>
1 parent 137d9fe commit d3bd6dc

File tree

11 files changed

+30
-24
lines changed

11 files changed

+30
-24
lines changed

changelog.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ with other backends. see #9125. Use `-d:nimLegacyJsRound` for previous behavior.
118118
symlinks point to).
119119
- `copyDir` and `copyDirWithPermissions` copy symlinks as symlinks (instead of
120120
skipping them as it was before).
121-
- `moveFile` and `moveDir` move symlinks as they are (instead of skipping them
121+
- `moveFile` and `moveDir` move symlinks as symlinks (instead of skipping them
122122
sometimes as it was before).
123123
- Added optional `followSymlinks` argument to `setFilePermissions`.
124124

lib/posix/posix.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -586,7 +586,7 @@ proc fstatvfs*(a1: cint, a2: var Statvfs): cint {.
586586
importc, header: "<sys/statvfs.h>".}
587587

588588
proc chmod*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.}
589-
when hasLchmod:
589+
when defined(osx) or defined(freebsd):
590590
proc lchmod*(a1: cstring, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.}
591591
proc fchmod*(a1: cint, a2: Mode): cint {.importc, header: "<sys/stat.h>", sideEffect.}
592592
proc fstat*(a1: cint, a2: var Stat): cint {.importc, header: "<sys/stat.h>", sideEffect.}

lib/posix/posix_haiku.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ when defined(nimHasStyleChecks):
1313
const
1414
hasSpawnH = true # should exist for every Posix system nowadays
1515
hasAioH = defined(linux)
16-
hasLchmod* = false
1716

1817
when defined(linux) and not defined(android):
1918
# On Linux:

lib/posix/posix_linux_amd64.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
const
1616
hasSpawnH = not defined(haiku) # should exist for every Posix system nowadays
1717
hasAioH = defined(linux)
18-
hasLchmod* = false
1918

2019
# On Linux:
2120
# timer_{create,delete,settime,gettime},

lib/posix/posix_macos_amd64.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ when defined(nimHasStyleChecks):
1313
const
1414
hasSpawnH = true # should exist for every Posix system nowadays
1515
hasAioH = false
16-
hasLchmod* = true
1716

1817
type
1918
DIR* {.importc: "DIR", header: "<dirent.h>",

lib/posix/posix_nintendoswitch.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
const
1313
hasSpawnH = true
1414
hasAioH = false
15-
hasLchmod* = false
1615

1716
type
1817
DIR* {.importc: "DIR", header: "<dirent.h>",

lib/posix/posix_openbsd_amd64.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ when defined(nimHasStyleChecks):
1313
const
1414
hasSpawnH = true # should exist for every Posix system nowadays
1515
hasAioH = false
16-
hasLchmod* = false
1716

1817
type
1918
DIR* {.importc: "DIR", header: "<dirent.h>",

lib/posix/posix_other.nim

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,10 @@ when defined(freertos):
1414
const
1515
hasSpawnH = false # should exist for every Posix system nowadays
1616
hasAioH = false
17-
hasLchmod* = false
1817
else:
1918
const
2019
hasSpawnH = true # should exist for every Posix system nowadays
2120
hasAioH = defined(linux)
22-
hasLchmod* = false
2321

2422
when defined(linux) and not defined(android):
2523
# On Linux:

lib/pure/os.nim

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -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.} =
16781679
proc 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>`_
@@ -1761,16 +1762,27 @@ proc copyFile*(source, dest: string, options = {cfSymlinkFollow}) {.rtl,
17611762
if isSymlink and cfSymlinkIgnore in options:
17621763
return
17631764
when defined(Windows):
1765+
proc handleOSError =
1766+
const ERROR_PRIVILEGE_NOT_HELD = 1314
1767+
let errCode = osLastError()
1768+
let context = $(source, dest, options)
1769+
if isSymlink and errCode.int32 == ERROR_PRIVILEGE_NOT_HELD:
1770+
stderr.write("Failed copy the symlink: error " & $errCode & ": " &
1771+
osErrorMsg(errCode) & "Additional info: " & context &
1772+
"\n")
1773+
else:
1774+
raiseOSError(errCode, context)
1775+
17641776
let dwCopyFlags = if cfSymlinkAsIs in options: COPY_FILE_COPY_SYMLINK else: 0'i32
17651777
var pbCancel = 0'i32
17661778
when useWinUnicode:
17671779
let s = newWideCString(source)
17681780
let d = newWideCString(dest)
17691781
if copyFileExW(s, d, nil, nil, addr pbCancel, dwCopyFlags) == 0'i32:
1770-
raiseOSError(osLastError(), $(source, dest, options))
1782+
handleOSError()
17711783
else:
17721784
if copyFileExA(source, dest, nil, nil, addr pbCancel, dwCopyFlags) == 0'i32:
1773-
raiseOSError(osLastError(), $(source, dest, options))
1785+
handleOSError()
17741786
elif hasCCopyfile:
17751787
let state = copyfile_state_alloc()
17761788
# xxx `COPYFILE_STAT` could be used for one-shot `copyFileWithPermissions`.

tests/stdlib/tos.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ Raises
2626
# test os path creation, iteration, and deletion
2727

2828
import os, strutils, pathnorm
29+
from stdtest/specialpaths import buildDir
2930

3031
block fileOperations:
3132
let files = @["these.txt", "are.x", "testing.r", "files.q"]
@@ -162,13 +163,12 @@ block fileOperations:
162163
else:
163164
const checkExpandSymlink = false
164165

165-
const buildDir = currentSourcePath.parentDir.parentDir/"build"
166166
const dname = buildDir/"D20210116T140629"
167167
const subDir = dname/"sub"
168168
const subDir2 = dname/"sub2"
169169
const brokenSymlinkName = "D20210101T191320_BROKEN_SYMLINK"
170170
const brokenSymlink = dname/brokenSymlinkName
171-
const brokenSymlinkSrc = "D20210101T191320_I_DO_NOT_EXIST"
171+
const brokenSymlinkSrc = "D20210101T191320_nonexistant"
172172
const brokenSymlinkCopy = brokenSymlink & "_COPY"
173173
const brokenSymlinkInSubDir = subDir/brokenSymlinkName
174174
const brokenSymlinkInSubDir2 = subDir2/brokenSymlinkName

0 commit comments

Comments
 (0)