From 74d686547e67da3eeae327c84c63f83833205890 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Tue, 14 Apr 2020 17:07:35 +0200 Subject: [PATCH] Fix humongous bug with fdopendir on mac https://opensource.apple.com/source/Libc/Libc-1244.1.7/include/dirent.h.auto.html ccall picks the wrong one, causes crashes and truncated d_name entries. Wrapping the function in a small C shim, as well as using the CAPI, fixes this. --- hpath-posix/cbits/dirutils.c | 2 +- hpath-posix/cbits/dirutils.h | 2 ++ .../System/Posix/RawFilePath/Directory/Traversals.hs | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/hpath-posix/cbits/dirutils.c b/hpath-posix/cbits/dirutils.c index 660607d..2ba92ab 100644 --- a/hpath-posix/cbits/dirutils.c +++ b/hpath-posix/cbits/dirutils.c @@ -1,7 +1,7 @@ #include "dirutils.h" + unsigned int __posixdir_d_type(struct dirent* d) { return(d -> d_type); } - diff --git a/hpath-posix/cbits/dirutils.h b/hpath-posix/cbits/dirutils.h index fd93b2e..e2d7498 100644 --- a/hpath-posix/cbits/dirutils.h +++ b/hpath-posix/cbits/dirutils.h @@ -7,7 +7,9 @@ #include #include + extern unsigned int __posixdir_d_type(struct dirent* d) ; + #endif diff --git a/hpath-posix/src/System/Posix/RawFilePath/Directory/Traversals.hs b/hpath-posix/src/System/Posix/RawFilePath/Directory/Traversals.hs index 229c071..bdb3ece 100644 --- a/hpath-posix/src/System/Posix/RawFilePath/Directory/Traversals.hs +++ b/hpath-posix/src/System/Posix/RawFilePath/Directory/Traversals.hs @@ -10,6 +10,7 @@ -- Traversal and read operations on directories. +{-# LANGUAGE CApiFFI #-} {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE OverloadedStrings #-} @@ -173,11 +174,15 @@ foreign import ccall unsafe "__hscore_d_name" foreign import ccall unsafe "__posixdir_d_type" c_type :: Ptr CDirent -> IO DirType -foreign import ccall "realpath" +foreign import capi "stdlib.h realpath" c_realpath :: CString -> CString -> IO CString -foreign import ccall unsafe "fdopendir" - c_fdopendir :: Posix.Fd -> IO (Ptr ()) +-- Using normal 'ccall' here lead to memory bugs, crashes +-- and corrupted d_name entries. It appears there are two fdopendirs: +-- https://opensource.apple.com/source/Libc/Libc-1244.1.7/include/dirent.h.auto.html +-- The capi call picks the correct one. +foreign import capi unsafe "dirent.h fdopendir" + c_fdopendir :: Posix.Fd -> IO (Ptr CDir) ---------------------------------------------------------- -- less dodgy but still lower-level