mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 17:34:43 +00:00
os: always use pcLinkToDir as kind for links to directories
Only the OS-specific case in walkDir() handled that correctly. Adapt the general case and handle it in getFileInfo().
This commit is contained in:
@@ -865,6 +865,20 @@ type
|
||||
|
||||
{.deprecated: [TPathComponent: PathComponent].}
|
||||
|
||||
|
||||
when defined(posix):
|
||||
proc getSymlinkFileKind(path: string): PathComponent =
|
||||
# Helper function.
|
||||
var s: Stat
|
||||
assert(path != "")
|
||||
if stat(path, s) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
if S_ISDIR(s.st_mode):
|
||||
result = pcLinkToDir
|
||||
else:
|
||||
result = pcLinkToFile
|
||||
|
||||
|
||||
proc staticWalkDir(dir: string; relative: bool): seq[
|
||||
tuple[kind: PathComponent, path: string]] =
|
||||
discard
|
||||
@@ -931,13 +945,15 @@ iterator walkDir*(dir: string; relative=false): tuple[kind: PathComponent, path:
|
||||
if x.d_type == DT_DIR: k = pcDir
|
||||
if x.d_type == DT_LNK:
|
||||
if dirExists(y): k = pcLinkToDir
|
||||
else: k = succ(k)
|
||||
else: k = pcLinkToFile
|
||||
yield (k, y)
|
||||
continue
|
||||
|
||||
if lstat(y, s) < 0'i32: break
|
||||
if S_ISDIR(s.st_mode): k = pcDir
|
||||
if S_ISLNK(s.st_mode): k = succ(k)
|
||||
if S_ISDIR(s.st_mode):
|
||||
k = pcDir
|
||||
elif S_ISLNK(s.st_mode):
|
||||
k = getSymlinkFileKind(y)
|
||||
yield (k, y)
|
||||
|
||||
iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {.
|
||||
@@ -1502,7 +1518,7 @@ type
|
||||
lastWriteTime*: Time # Time file was last modified/written to.
|
||||
creationTime*: Time # Time file was created. Not supported on all systems!
|
||||
|
||||
template rawToFormalFileInfo(rawInfo, formalInfo): untyped =
|
||||
template rawToFormalFileInfo(rawInfo, path, formalInfo): untyped =
|
||||
## Transforms the native file info structure into the one nim uses.
|
||||
## 'rawInfo' is either a 'TBY_HANDLE_FILE_INFORMATION' structure on Windows,
|
||||
## or a 'Stat' structure on posix
|
||||
@@ -1557,8 +1573,11 @@ template rawToFormalFileInfo(rawInfo, formalInfo): untyped =
|
||||
checkAndIncludeMode(S_IXOTH, fpOthersExec)
|
||||
|
||||
formalInfo.kind = pcFile
|
||||
if S_ISDIR(rawInfo.st_mode): formalInfo.kind = pcDir
|
||||
if S_ISLNK(rawInfo.st_mode): formalInfo.kind.inc()
|
||||
if S_ISDIR(rawInfo.st_mode):
|
||||
formalInfo.kind = pcDir
|
||||
elif S_ISLNK(rawInfo.st_mode):
|
||||
assert(path != "") # symlinks can't occur for file handles
|
||||
formalInfo.kind = getSymlinkFileKind(path)
|
||||
|
||||
proc getFileInfo*(handle: FileHandle): FileInfo =
|
||||
## Retrieves file information for the file object represented by the given
|
||||
@@ -1574,12 +1593,12 @@ proc getFileInfo*(handle: FileHandle): FileInfo =
|
||||
var realHandle = get_osfhandle(handle)
|
||||
if getFileInformationByHandle(realHandle, addr rawInfo) == 0:
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
rawToFormalFileInfo(rawInfo, "", result)
|
||||
else:
|
||||
var rawInfo: Stat
|
||||
if fstat(handle, rawInfo) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
rawToFormalFileInfo(rawInfo, "", result)
|
||||
|
||||
proc getFileInfo*(file: File): FileInfo =
|
||||
if file.isNil:
|
||||
@@ -1608,7 +1627,7 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
|
||||
raiseOSError(osLastError())
|
||||
if getFileInformationByHandle(handle, addr rawInfo) == 0:
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
rawToFormalFileInfo(rawInfo, path, result)
|
||||
discard closeHandle(handle)
|
||||
else:
|
||||
var rawInfo: Stat
|
||||
@@ -1618,7 +1637,7 @@ proc getFileInfo*(path: string, followSymlink = true): FileInfo =
|
||||
else:
|
||||
if lstat(path, rawInfo) < 0'i32:
|
||||
raiseOSError(osLastError())
|
||||
rawToFormalFileInfo(rawInfo, result)
|
||||
rawToFormalFileInfo(rawInfo, path, result)
|
||||
|
||||
proc isHidden*(path: string): bool =
|
||||
## Determines whether a given path is hidden or not. Returns false if the
|
||||
|
||||
Reference in New Issue
Block a user