Last active
February 27, 2018 12:44
-
-
Save krisis/e80b8cf6aeae4f3b08a448607afd5022 to your computer and use it in GitHub Desktop.
Haskell FFI for `getmntent(3)`, `setmntent(3)`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ForeignFunctionInterface #-} | |
module MountUtils where | |
import Control.Monad (liftM) | |
import Foreign.C.Types | |
import Foreign.C.String | |
import Foreign.Ptr | |
import Foreign.Storable | |
import Foreign.Marshal.Alloc | |
#include "mntent.h" | |
#c | |
typedef struct mntent mntent_t; | |
#endc | |
-- FILE* is a opaque type | |
{#pointer *FILE as MntHandle newtype#} | |
data MntEnt = MntEnt | |
{ mntFSName :: String | |
, mntDir :: String | |
, mntType :: String | |
, mntOpts :: String | |
, mntFreq :: Integer | |
, mntPassNum :: Integer | |
} deriving Show | |
{#pointer *mntent_t as MntEntPtr -> MntEnt#} | |
instance Storable MntEnt where | |
sizeOf _ = {#sizeof mntent_t #} | |
alignment _ = 4 | |
peek p = do | |
fsName <- ({#get mntent_t->mnt_fsname#} p) | |
fsDir <- ({#get mntent_t->mnt_dir#} p) | |
fsType <- ({#get mntent_t->mnt_type#} p) | |
fsOpts <- ({#get mntent_t->mnt_opts#} p) | |
fsFreq <- ({#get mntent_t->mnt_freq#} p) | |
fsPassNum <- ({#get mntent_t->mnt_passno#} p) | |
fsNameStr <- peekCString fsName | |
fsDirStr <- peekCString fsDir | |
fsTypeStr <- peekCString fsType | |
fsOptsStr <- peekCString fsOpts | |
return $ MntEnt fsNameStr fsDirStr fsTypeStr fsOptsStr (fromIntegral fsFreq) (fromIntegral fsPassNum) | |
poke p x = do | |
fsName <- newCString $ mntFSName x | |
fsDir <- newCString $ mntDir x | |
fsType <- newCString $ mntType x | |
fsOpts <- newCString $ mntOpts x | |
{#set mntent_t.mnt_fsname#} p fsName | |
{#set mntent_t.mnt_dir#} p fsDir | |
{#set mntent_t.mnt_type#} p fsType | |
{#set mntent_t.mnt_opts#} p fsOpts | |
{#set mntent_t.mnt_freq#} p (fromIntegral $ mntFreq x) | |
{#set mntent_t.mnt_passno#} p (fromIntegral $ mntPassNum x) | |
mapM_ free [fsName, fsDir, fsType, fsOpts] | |
{#fun unsafe setmntent as ^ {`String', `String'} -> `MntHandle'#} | |
getmntent :: (MntHandle) -> IO ((MntEntPtr)) | |
getmntent h = getmntent'_ h | |
foreign import ccall unsafe "Sample.chs.h getmntent" | |
getmntent'_ :: ((MntHandle) -> (IO (C2HSImp.Ptr (MntEnt)))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
To run this,
Install
c2hs
executable to generate Haskell bindings from C libsCommand to generate Haskell binding module
Compile the generated Haskell binding module