summary refs log tree commit diff stats
path: root/lib/system
diff options
context:
space:
mode:
authorAndreas Rumpf <rumpf_a@web.de>2016-03-23 11:22:50 +0100
committerAndreas Rumpf <rumpf_a@web.de>2016-03-23 11:22:50 +0100
commit7b071a755528b6398b1cbe45dfb147841626a649 (patch)
treedbcf3b531acc78e56040ce28d2ea7fa79125b32f /lib/system
parenta119238b8a42e44d34b0871c6f4c0b7ca724ae10 (diff)
parentdfba0bdcafb69fe408048924d86d33bf6718cffa (diff)
downloadNim-7b071a755528b6398b1cbe45dfb147841626a649.tar.gz
Merge pull request #3963 from def-/compiler-dir
Don't try to read directories as files
Diffstat (limited to 'lib/system')
-rw-r--r--lib/system/sysio.nim21
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/system/sysio.nim b/lib/system/sysio.nim
index 78c7b1ca1..d0bba6775 100644
--- a/lib/system/sysio.nim
+++ b/lib/system/sysio.nim
@@ -270,12 +270,33 @@ const
     # we always use binary here as for Nim the OS line ending
     # should not be translated.
 
+when defined(posix) and not defined(nimscript):
+  type
+    Mode {.importc: "mode_t", header: "<sys/types.h>".} = cint
+
+    Stat {.importc: "struct stat",
+             header: "<sys/stat.h>", final, pure.} = object ## struct stat
+      st_mode: Mode        ## Mode of file
+
+  proc S_ISDIR(m: Mode): bool {.importc, header: "<sys/stat.h>".}
+    ## Test for a directory.
+
+  proc fstat(a1: cint, a2: var Stat): cint {.importc, header: "<sys/stat.h>".}
 
 proc open(f: var File, filename: string,
           mode: FileMode = fmRead,
           bufSize: int = -1): bool =
   var p: pointer = fopen(filename, FormatOpen[mode])
   if p != nil:
+    when defined(posix) and not defined(nimscript):
+      # How `fopen` handles opening a directory is not specified in ISO C and
+      # POSIX. We do not want to handle directories as regular files that can
+      # be opened.
+      var f2 = cast[File](p)
+      var res: Stat
+      if fstat(getFileHandle(f2), res) >= 0'i32 and S_ISDIR(res.st_mode):
+        close(f2)
+        return false
     result = true
     f = cast[File](p)
     if bufSize > 0 and bufSize <= high(cint).int: