summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2016-09-17 18:58:47 +0200
committerGitHub <noreply@github.com>2016-09-17 18:58:47 +0200
commitf4f8827c0633678ef5828d3b36a1ed645744a7fd (patch)
tree901e82faad7c7684a5ff672bb30d3c218de90df7
parentf62ced80fcb5d860c13decd66af306a0753a81bf (diff)
parentfc0a3dceaf85fcce2ef3fcf8f6076c52deb2ff4e (diff)
downloadNim-f4f8827c0633678ef5828d3b36a1ed645744a7fd.tar.gz
Merge pull request #4784 from rudis/devel
os: always use pcLinkToDir as kind for links to directories
-rw-r--r--lib/pure/os.nim39
1 files changed, 29 insertions, 10 deletions
diff --git a/lib/pure/os.nim b/lib/pure/os.nim
index e7c5ad5f4..cdbe170cc 100644
--- a/lib/pure/os.nim
+++ b/lib/pure/os.nim
@@ -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