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:
Simon Ruderich
2016-09-17 01:45:02 +02:00
parent d250f06550
commit fc0a3dceaf

View File

@@ -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