#include #ifdef HAVE_LIMITS_H # include #endif module System.Directory.Internal.Posix where #ifndef mingw32_HOST_OS import Control.Monad ((>=>)) import Control.Exception (bracket) import Foreign import Foreign.C -- we use the 'free' from the standard library here since it's not entirely -- clear whether Haskell's 'free' corresponds to the same one foreign import ccall unsafe "free" c_free :: Ptr a -> IO () c_PATH_MAX :: Maybe Int #ifdef PATH_MAX c_PATH_MAX | c_PATH_MAX' > toInteger maxValue = Nothing | otherwise = Just (fromInteger c_PATH_MAX') where c_PATH_MAX' = (#const PATH_MAX) maxValue = maxBound `asTypeOf` case c_PATH_MAX of ~(Just x) -> x #else c_PATH_MAX = Nothing #endif foreign import ccall "realpath" c_realpath :: CString -> CString -> IO CString withRealpath :: CString -> (CString -> IO a) -> IO a withRealpath path action = case c_PATH_MAX of Nothing -> -- newer versions of POSIX support cases where the 2nd arg is NULL; -- hopefully that is the case here, as there is no safer way bracket (realpath nullPtr) c_free action Just pathMax -> -- allocate one extra just to be safe allocaBytes (pathMax + 1) (realpath >=> action) where realpath = throwErrnoIfNull "" . c_realpath path #endif