summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorHans Raaf <hara@oderwat.de>2016-07-16 22:44:19 +0200
committerHans Raaf <hara@oderwat.de>2016-07-17 01:07:09 +0200
commitc00bb2ca82e7bed4e8b88418becc9daf2148e970 (patch)
tree7e1d04689759889578439178c800864acc69ce7c /lib
parent2ac21261b4ab0ed134b380060ab2fc7c978003d3 (diff)
downloadNim-c00bb2ca82e7bed4e8b88418becc9daf2148e970.tar.gz
findExe() now by default follows symlinks.
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/ospaths.nim28
1 files changed, 26 insertions, 2 deletions
diff --git a/lib/pure/ospaths.nim b/lib/pure/ospaths.nim
index 65588529e..98ffc2272 100644
--- a/lib/pure/ospaths.nim
+++ b/lib/pure/ospaths.nim
@@ -556,12 +556,21 @@ when declared(getEnv) or defined(nimscript):
           yield substr(s, first, last-1)
           inc(last)
 
-  proc findExe*(exe: string): string {.
+  when not defined(windows) and declared(os):
+    proc checkSymlink(path: string): bool =
+      var rawInfo: Stat
+      if lstat(path, rawInfo) < 0'i32:
+        raiseOSError(osLastError())
+      S_ISLNK(rawInfo.st_mode)
+
+  proc findExe*(exe: string, followSymlinks: bool = true): string {.
     tags: [ReadDirEffect, ReadEnvEffect, ReadIOEffect].} =
     ## Searches for `exe` in the current working directory and then
     ## in directories listed in the ``PATH`` environment variable.
     ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe`
     ## is added the `ExeExt <#ExeExt>`_ file extension if it has none.
+    ## If the system supports symlinks it also resolves them until it
+    ## meets the actual file. This behavior can be disabled if desired.
     result = addFileExt(exe, ExeExt)
     if existsFile(result): return
     var path = string(getEnv("PATH"))
@@ -572,7 +581,22 @@ when declared(getEnv) or defined(nimscript):
                result
       else:
         var x = expandTilde(candidate) / result
-      if existsFile(x): return x
+      if existsFile(x):
+        when not defined(windows) and declared(os):
+          while followSymlinks: # doubles as if here
+            if x.checkSymlink:
+              var r = newString(256)
+              var len = readlink(x, r, 256)
+              if len < 0:
+                raiseOSError(osLastError())
+              if len > 256:
+                r = newString(len+1)
+                len = readlink(x, r, len)
+              setLen(r, len)
+              x = r
+            else:
+              break
+        return x
     result = ""
 
 when defined(nimscript) or (defined(nimdoc) and not declared(os)):