module System.PIO.Linux (
FilePath,
FileDescriptor,
IOMode(..),
fdOpen,
fdClose,
fdPutBuf,
fdGetBuf,
) where
import Foreign.Ptr(Ptr)
import Foreign.C.String(CString,withCString)
import Prelude hiding (FilePath)
import Foreign.C.Error(throwErrno)
type FilePath = String
type FileDescriptor = Int
foreign import ccall "o_rdonly" o_rdonly :: Int
foreign import ccall "o_wronly" o_wronly :: Int
foreign import ccall "o_rdwr" o_rdwr :: Int
foreign import ccall "open" linux_open :: CString -> Int -> IO Int
foreign import ccall "close" linux_close :: Int -> IO Int
foreign import ccall "write" linux_write :: Int -> Ptr a -> Int -> IO Int
foreign import ccall "read" linux_read :: Int -> Ptr a -> Int -> IO Int
data IOMode = ReadMode
| WriteMode
| ReadWriteMode
instance Enum IOMode where
toEnum n | n == o_rdonly = ReadMode
| n == o_wronly = WriteMode
| n == o_rdwr = ReadWriteMode
| otherwise = error "toEnum: convert error"
fromEnum ReadMode = o_rdonly
fromEnum WriteMode = o_wronly
fromEnum ReadWriteMode = o_rdwr
fdOpen :: FilePath -> IOMode -> IO FileDescriptor
fdOpen path mode = withCString path $
\cpath -> linux_open cpath (fromEnum mode) >>= \fd -> case fd of
1 -> throwErrno "fdOpen"
otherwise -> return fd
fdClose :: FileDescriptor -> IO ()
fdClose fd = linux_close fd >>= \rc -> case rc of
1 -> throwErrno "fdClose"
otherwise -> return ()
fdPutBuf :: FileDescriptor -> Ptr a -> Int -> IO ()
fdPutBuf fd buf bufLen = linux_write fd buf bufLen >>= \rc -> case rc of
1 -> throwErrno "fdPutBuf"
otherwise -> return ()
fdGetBuf :: FileDescriptor -> Ptr a -> Int -> IO ()
fdGetBuf fd buf bufLen = linux_read fd buf bufLen >>= \rc -> case rc of
1 -> throwErrno "fdGetBuf"
otherwise -> return ()