From f21dcde54b09913550036e6501cca935278597d9 Mon Sep 17 00:00:00 2001 From: Tom Smeding Date: Sun, 29 Mar 2026 23:25:10 +0200 Subject: Initial --- src/Mmap.hs | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/Mmap.hs (limited to 'src/Mmap.hs') diff --git a/src/Mmap.hs b/src/Mmap.hs new file mode 100644 index 0000000..bfe6042 --- /dev/null +++ b/src/Mmap.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE ForeignFunctionInterface #-} +module Mmap where + +import Control.Exception +import Data.ByteString (ByteString) +import qualified Data.ByteString.Unsafe as BS +import Foreign +import Foreign.C.Types +import System.Posix.IO +import System.Posix.Types + +foreign import ccall "ircbrowse_mmap" + c_mmap :: CInt -> Ptr CSize -> IO (Ptr Word8) + -- fd out length + +foreign import ccall "ircbrowse_munmap" + c_munmap :: Ptr Word8 -> CSize -> IO () + -- addr length + +mapFile :: FilePath -> IO ByteString +mapFile path = mask_ $ do + -- open can fail without repercussions + Fd fd <- openFd path ReadOnly defaultFileFlags + + -- do the mmap; if it fails, close the file, ignoring exceptions there + (addr, filelen) <- + catchNoPropagate @SomeException + (alloca $ \lengthp -> do + addr <- c_mmap fd lengthp + lengthval <- peek lengthp + return (addr, lengthval)) + (\e -> do + catch @SomeException (closeFd (Fd fd)) + (\_ -> return ()) + rethrowIO e) + + -- mmap succeeded, close the file + catchNoPropagate @SomeException (closeFd (Fd fd)) + (\e -> do + -- putStrLn ("[munmap " ++ show addr ++ " as close(2) handler]") + c_munmap addr filelen + rethrowIO e) + + -- close succeeded, we're safe now since bytestring construction will not + -- fail (and no exceptions are coming from outside as we're masked) + if addr == nullPtr + then fail "mapFile: could not mmap" + else BS.unsafePackCStringFinalizer addr (fromIntegral @CSize @Int filelen) + (do -- putStrLn ("[munmap " ++ show addr ++ "]") + c_munmap addr filelen) -- cgit v1.3