{-# OPTIONS_GHC -Wno-missing-signatures #-}
module Unix
    ( fsync, fsyncExn
    , fdatasync, fdatasyncExn
    , ftruncate, ftruncateExn
    , mkdir, mkdirExn
    , preadBuf, preadBufExn
    , pread, preadExn
    , pwriteBuf, pwriteBufExn
    , pwrite, pwriteExn
    , pwriteFull, pwriteFullExn
    , readBuf, readBufExn
    , writeBuf, writeBufExn
    , read, readExn
    , remove, removeExn
    , rmdir, rmdirExn
    , write, writeExn
    , writeFull, writeFullExn

    , OpenFlag(..)
    , open, openExn
    , openat, openatExn
    , o_APPEND
    , o_CLOEXEC
    , o_CREAT
    , o_DIRECTORY
    , o_EXCL
    , o_NOFOLLOW
    , o_NONBLOCK
    , o_NDELAY
    , o_TRUNC
    , o_RDONLY
    , o_WRONLY
    , o_RDWR

    , close, closeExn

    -- * Re-exported for convenience
    , CString
    ) where

import CString
import Foreign.C.Error
import Foreign.ForeignPtr
import Unix.C
import Unix.C.Errors
import Unix.Errors
import Zhp

import qualified Data.ByteString          as BS
import qualified Data.ByteString.Internal as BS

type EIO a = IO (Either Errno a)

fsync :: Fd -> EIO ()
fsync :: Fd -> EIO ()
fsync Fd
fd = EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> IO CInt
c_fsync Fd
fd

fsyncExn :: Fd -> IO ()
fsyncExn :: Fd -> IO ()
fsyncExn Fd
fd = EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> EIO ()
fsync Fd
fd

fdatasync :: Fd -> EIO ()
fdatasync :: Fd -> EIO ()
fdatasync Fd
fd = EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> IO CInt
c_fdatasync Fd
fd

fdatasyncExn :: Fd -> IO ()
fdatasyncExn :: Fd -> IO ()
fdatasyncExn Fd
fd = EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> EIO ()
fdatasync Fd
fd

ftruncate :: Fd -> COff -> EIO ()
ftruncate :: Fd -> COff -> EIO ()
ftruncate Fd
fd COff
off = EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO Int -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO Int -> IO ()) -> IO Int -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> COff -> IO Int
c_ftruncate Fd
fd COff
off

ftruncateExn :: Fd -> COff -> IO ()
ftruncateExn :: Fd -> COff -> IO ()
ftruncateExn Fd
fd COff
off =
    EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> COff -> EIO ()
ftruncate Fd
fd COff
off

preadBuf :: Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
preadBuf :: Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
preadBuf Fd
fd Ptr Word8
ptr CSize
sz COff
off =
    EIO CSsize -> EIO CSsize
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO CSsize -> EIO CSsize) -> EIO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ IO CSsize -> EIO CSsize
forall a. IO a -> IO (Either Errno a)
orErrno (IO CSsize -> EIO CSsize) -> IO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
c_pread Fd
fd Ptr Word8
ptr CSize
sz COff
off

preadBufExn :: Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
preadBufExn :: Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
preadBufExn Fd
fd Ptr Word8
ptr CSize
sz COff
off =
    EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
preadBuf Fd
fd Ptr Word8
ptr CSize
sz COff
off

pread :: Fd -> CSize -> COff -> EIO BS.ByteString
pread :: Fd -> CSize -> COff -> EIO ByteString
pread Fd
fd CSize
sz COff
off = do
    ForeignPtr Word8
fptr <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
sz)
    Either Errno CSsize
r <- ForeignPtr Word8 -> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fptr ((Ptr Word8 -> EIO CSsize) -> EIO CSsize)
-> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
preadBuf Fd
fd Ptr Word8
ptr CSize
sz COff
off
    Either Errno ByteString -> EIO ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno ByteString -> EIO ByteString)
-> Either Errno ByteString -> EIO ByteString
forall a b. (a -> b) -> a -> b
$! case Either Errno CSsize
r of
        Left Errno
e  -> Errno -> Either Errno ByteString
forall a b. a -> Either a b
Left Errno
e
        Right CSsize
v -> ByteString -> Either Errno ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
BS.fromForeignPtr ForeignPtr Word8
fptr Int
0 (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v))

preadExn :: Fd -> CSize -> COff -> IO BS.ByteString
preadExn :: Fd -> CSize -> COff -> IO ByteString
preadExn Fd
fd CSize
sz COff
off = EIO ByteString -> IO ByteString
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO ByteString -> IO ByteString)
-> EIO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Fd -> CSize -> COff -> EIO ByteString
pread Fd
fd CSize
sz COff
off

pwriteBuf :: Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
pwriteBuf :: Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
pwriteBuf Fd
fd Ptr Word8
ptr CSize
sz COff
off =
    EIO CSsize -> EIO CSsize
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO CSsize -> EIO CSsize) -> EIO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ IO CSsize -> EIO CSsize
forall a. IO a -> IO (Either Errno a)
orErrno (IO CSsize -> EIO CSsize) -> IO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
c_pwrite Fd
fd Ptr Word8
ptr CSize
sz COff
off

pwriteBufExn :: Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
pwriteBufExn :: Fd -> Ptr Word8 -> CSize -> COff -> IO CSsize
pwriteBufExn Fd
fd Ptr Word8
ptr CSize
sz COff
off =
    EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
pwriteBuf Fd
fd Ptr Word8
ptr CSize
sz COff
off

pwrite :: Fd -> BS.ByteString -> COff -> EIO CSsize
pwrite :: Fd -> ByteString -> COff -> EIO CSsize
pwrite Fd
fd ByteString
bs COff
off =
    let (ForeignPtr Word8
fptr, Int
foff, Int
len) = ByteString -> (ForeignPtr Word8, Int, Int)
BS.toForeignPtr ByteString
bs in
    ForeignPtr Word8 -> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fptr ((Ptr Word8 -> EIO CSsize) -> EIO CSsize)
-> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr ->
        Fd -> Ptr Word8 -> CSize -> COff -> EIO CSsize
pwriteBuf Fd
fd (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
foff) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) COff
off

pwriteExn :: Fd -> BS.ByteString -> COff -> IO CSsize
pwriteExn :: Fd -> ByteString -> COff -> IO CSsize
pwriteExn Fd
fd ByteString
bs COff
off = EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> ByteString -> COff -> EIO CSsize
pwrite Fd
fd ByteString
bs COff
off

pwriteFull :: Fd -> BS.ByteString -> COff -> EIO ()
pwriteFull :: Fd -> ByteString -> COff -> EIO ()
pwriteFull Fd
fd ByteString
bs COff
off = do
    Either Errno CSsize
ret <- Fd -> ByteString -> COff -> EIO CSsize
pwrite Fd
fd ByteString
bs COff
off
    case Either Errno CSsize
ret of
        Left Errno
e -> Either Errno () -> EIO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno () -> EIO ()) -> Either Errno () -> EIO ()
forall a b. (a -> b) -> a -> b
$ Errno -> Either Errno ()
forall a b. a -> Either a b
Left Errno
e
        Right CSsize
v
            | CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString -> Int
BS.length ByteString
bs ->
                Either Errno () -> EIO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno () -> EIO ()) -> Either Errno () -> EIO ()
forall a b. (a -> b) -> a -> b
$ () -> Either Errno ()
forall a b. b -> Either a b
Right ()
            | Bool
otherwise ->
                Fd -> ByteString -> COff -> EIO ()
pwriteFull Fd
fd
                    (Int -> ByteString -> ByteString
BS.drop (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v) ByteString
bs)
                    (COff
off COff -> COff -> COff
forall a. Num a => a -> a -> a
+ CSsize -> COff
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v)

pwriteFullExn :: Fd -> BS.ByteString -> COff -> IO ()
pwriteFullExn :: Fd -> ByteString -> COff -> IO ()
pwriteFullExn Fd
fd ByteString
bs COff
off = EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> ByteString -> COff -> EIO ()
pwriteFull Fd
fd ByteString
bs COff
off

readBuf :: Fd -> Ptr Word8 -> CSize -> EIO CSsize
readBuf :: Fd -> Ptr Word8 -> CSize -> EIO CSsize
readBuf Fd
fd Ptr Word8
ptr CSize
sz =
    EIO CSsize -> EIO CSsize
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO CSsize -> EIO CSsize) -> EIO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ IO CSsize -> EIO CSsize
forall a. IO a -> IO (Either Errno a)
orErrno (IO CSsize -> EIO CSsize) -> IO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> IO CSsize
c_read Fd
fd Ptr Word8
ptr CSize
sz

readBufExn :: Fd -> Ptr Word8 -> CSize -> IO CSsize
readBufExn :: Fd -> Ptr Word8 -> CSize -> IO CSsize
readBufExn Fd
fd Ptr Word8
ptr CSize
sz =
    EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> EIO CSsize
readBuf Fd
fd Ptr Word8
ptr CSize
sz

read :: Fd -> Int -> EIO BS.ByteString
read :: Fd -> Int -> EIO ByteString
read Fd
fd Int
sz = do
    ForeignPtr Word8
fptr <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
mallocForeignPtrBytes Int
sz
    Either Errno CSsize
r <- ForeignPtr Word8 -> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fptr ((Ptr Word8 -> EIO CSsize) -> EIO CSsize)
-> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr -> Fd -> Ptr Word8 -> CSize -> EIO CSsize
readBuf Fd
fd Ptr Word8
ptr (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
sz)
    -- TODO(perf): should we trim the buffer to the size actually
    -- read? Maybe if it's below a certain size,
    -- possibly relative to the size of the buffer?
    Either Errno ByteString -> EIO ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno ByteString -> EIO ByteString)
-> Either Errno ByteString -> EIO ByteString
forall a b. (a -> b) -> a -> b
$! case Either Errno CSsize
r of
        Left Errno
e  -> Errno -> Either Errno ByteString
forall a b. a -> Either a b
Left Errno
e
        Right CSsize
v -> ByteString -> Either Errno ByteString
forall a b. b -> Either a b
Right (ForeignPtr Word8 -> Int -> Int -> ByteString
BS.fromForeignPtr ForeignPtr Word8
fptr Int
0 (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v))

readExn :: Fd -> Int -> IO BS.ByteString
readExn :: Fd -> Int -> IO ByteString
readExn Fd
fd Int
sz =
    EIO ByteString -> IO ByteString
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO ByteString -> IO ByteString)
-> EIO ByteString -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Fd -> Int -> EIO ByteString
read Fd
fd Int
sz

writeBuf :: Fd -> Ptr Word8 -> CSize -> EIO CSsize
writeBuf :: Fd -> Ptr Word8 -> CSize -> EIO CSsize
writeBuf Fd
fd Ptr Word8
ptr CSize
sz =
    EIO CSsize -> EIO CSsize
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO CSsize -> EIO CSsize) -> EIO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ IO CSsize -> EIO CSsize
forall a. IO a -> IO (Either Errno a)
orErrno (IO CSsize -> EIO CSsize) -> IO CSsize -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> IO CSsize
c_write Fd
fd Ptr Word8
ptr CSize
sz

writeBufExn :: Fd -> Ptr Word8 -> CSize -> IO CSsize
writeBufExn :: Fd -> Ptr Word8 -> CSize -> IO CSsize
writeBufExn Fd
fd Ptr Word8
ptr CSize
sz =
    EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> Ptr Word8 -> CSize -> EIO CSsize
writeBuf Fd
fd Ptr Word8
ptr CSize
sz

write :: Fd -> BS.ByteString -> EIO CSsize
write :: Fd -> ByteString -> EIO CSsize
write Fd
fd ByteString
bs =
    let (ForeignPtr Word8
fptr, Int
off, Int
len) = ByteString -> (ForeignPtr Word8, Int, Int)
BS.toForeignPtr ByteString
bs in
    ForeignPtr Word8 -> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fptr ((Ptr Word8 -> EIO CSsize) -> EIO CSsize)
-> (Ptr Word8 -> EIO CSsize) -> EIO CSsize
forall a b. (a -> b) -> a -> b
$ \Ptr Word8
ptr ->
        Fd -> Ptr Word8 -> CSize -> EIO CSsize
writeBuf Fd
fd (Ptr Word8 -> Int -> Ptr Word8
forall a b. Ptr a -> Int -> Ptr b
plusPtr Ptr Word8
ptr Int
off) (Int -> CSize
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)

writeExn :: Fd -> BS.ByteString -> IO CSsize
writeExn :: Fd -> ByteString -> IO CSsize
writeExn Fd
fd ByteString
bs =
    EIO CSsize -> IO CSsize
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO CSsize -> IO CSsize) -> EIO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ Fd -> ByteString -> EIO CSsize
write Fd
fd ByteString
bs

-- | Wrapper around write that makes sure the full bytestring is written,
-- handling short writes from the underlying system call.
writeFull :: Fd -> BS.ByteString -> EIO ()
writeFull :: Fd -> ByteString -> EIO ()
writeFull Fd
fd ByteString
bs = do
    Either Errno CSsize
ret <- Fd -> ByteString -> EIO CSsize
write Fd
fd ByteString
bs
    case Either Errno CSsize
ret of
        Left Errno
e -> Either Errno () -> EIO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno () -> EIO ()) -> Either Errno () -> EIO ()
forall a b. (a -> b) -> a -> b
$ Errno -> Either Errno ()
forall a b. a -> Either a b
Left Errno
e
        Right CSsize
v
            | (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v) Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString -> Int
BS.length ByteString
bs -> Either Errno () -> EIO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either Errno () -> EIO ()) -> Either Errno () -> EIO ()
forall a b. (a -> b) -> a -> b
$ () -> Either Errno ()
forall a b. b -> Either a b
Right ()
            | Bool
otherwise -> Fd -> ByteString -> EIO ()
writeFull Fd
fd (Int -> ByteString -> ByteString
BS.drop (CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
v) ByteString
bs)

writeFullExn :: Fd -> BS.ByteString -> IO ()
writeFullExn :: Fd -> ByteString -> IO ()
writeFullExn Fd
fd ByteString
bs =
    EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> ByteString -> EIO ()
writeFull Fd
fd ByteString
bs

remove :: CString -> EIO ()
remove :: CString -> EIO ()
remove CString
fpath =
    CString -> (CStr -> EIO ()) -> EIO ()
forall a. CString -> (CStr -> IO a) -> IO a
useCStr CString
fpath ((CStr -> EIO ()) -> EIO ()) -> (CStr -> EIO ()) -> EIO ()
forall a b. (a -> b) -> a -> b
$ \CStr
path ->
        EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ () () -> IO CInt -> IO ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ CStr -> IO CInt
c_remove CStr
path

removeExn :: CString -> IO ()
removeExn :: CString -> IO ()
removeExn CString
fpath =
    EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ CString -> EIO ()
remove CString
fpath

rmdir :: CString -> EIO ()
rmdir :: CString -> EIO ()
rmdir CString
fpath =
    CString -> (CStr -> EIO ()) -> EIO ()
forall a. CString -> (CStr -> IO a) -> IO a
useCStr CString
fpath ((CStr -> EIO ()) -> EIO ()) -> (CStr -> EIO ()) -> EIO ()
forall a b. (a -> b) -> a -> b
$ \CStr
path ->
        EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ () () -> IO CInt -> IO ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ CStr -> IO CInt
c_rmdir CStr
path

rmdirExn :: CString -> IO ()
rmdirExn :: CString -> IO ()
rmdirExn CString
fpath =
    EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ CString -> EIO ()
rmdir CString
fpath

mkdir :: CString -> CMode -> EIO ()
mkdir :: CString -> CMode -> EIO ()
mkdir CString
fpath CMode
mode =
    CString -> (CStr -> EIO ()) -> EIO ()
forall a. CString -> (CStr -> IO a) -> IO a
useCStr CString
fpath ((CStr -> EIO ()) -> EIO ()) -> (CStr -> EIO ()) -> EIO ()
forall a b. (a -> b) -> a -> b
$ \CStr
path ->
        EIO () -> EIO ()
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO () -> EIO ()) -> EIO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ () () -> IO CInt -> IO ()
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ CStr -> CMode -> IO CInt
c_mkdir CStr
path CMode
mode

mkdirExn :: CString -> CMode -> IO ()
mkdirExn :: CString -> CMode -> IO ()
mkdirExn CString
fpath CMode
mode =
    EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ CString -> CMode -> EIO ()
mkdir CString
fpath CMode
mode

newtype OpenFlag = OpenFlag CInt
instance Semigroup OpenFlag where
    (OpenFlag CInt
x) <> :: OpenFlag -> OpenFlag -> OpenFlag
<> (OpenFlag CInt
y) = CInt -> OpenFlag
OpenFlag (CInt
x CInt -> CInt -> CInt
forall a. Bits a => a -> a -> a
.|. CInt
y)

open :: CString -> OpenFlag -> CMode -> EIO Fd
open :: CString -> OpenFlag -> CMode -> EIO Fd
open CString
fpath (OpenFlag CInt
flag) CMode
mode =
    CString -> (CStr -> EIO Fd) -> EIO Fd
forall a. CString -> (CStr -> IO a) -> IO a
useCStr CString
fpath ((CStr -> EIO Fd) -> EIO Fd) -> (CStr -> EIO Fd) -> EIO Fd
forall a b. (a -> b) -> a -> b
$ \CStr
path ->
        EIO Fd -> EIO Fd
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO Fd -> EIO Fd) -> EIO Fd -> EIO Fd
forall a b. (a -> b) -> a -> b
$ IO Fd -> EIO Fd
forall a. IO a -> IO (Either Errno a)
orErrno (IO Fd -> EIO Fd) -> IO Fd -> EIO Fd
forall a b. (a -> b) -> a -> b
$ CStr -> CInt -> CMode -> IO Fd
c_open CStr
path CInt
flag CMode
mode

openExn :: CString -> OpenFlag -> CMode -> IO Fd
openExn :: CString -> OpenFlag -> CMode -> IO Fd
openExn CString
path OpenFlag
flag CMode
mode =
    EIO Fd -> IO Fd
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO Fd -> IO Fd) -> EIO Fd -> IO Fd
forall a b. (a -> b) -> a -> b
$ CString -> OpenFlag -> CMode -> EIO Fd
open CString
path OpenFlag
flag CMode
mode

openat :: Fd -> CString -> OpenFlag -> CMode -> EIO Fd
openat :: Fd -> CString -> OpenFlag -> CMode -> EIO Fd
openat Fd
fd CString
fpath (OpenFlag CInt
flag) CMode
mode =
    CString -> (CStr -> EIO Fd) -> EIO Fd
forall a. CString -> (CStr -> IO a) -> IO a
useCStr CString
fpath ((CStr -> EIO Fd) -> EIO Fd) -> (CStr -> EIO Fd) -> EIO Fd
forall a b. (a -> b) -> a -> b
$ \CStr
path ->
        EIO Fd -> EIO Fd
forall a. IO (Either Errno a) -> IO (Either Errno a)
retryEINTR (EIO Fd -> EIO Fd) -> EIO Fd -> EIO Fd
forall a b. (a -> b) -> a -> b
$ IO Fd -> EIO Fd
forall a. IO a -> IO (Either Errno a)
orErrno (IO Fd -> EIO Fd) -> IO Fd -> EIO Fd
forall a b. (a -> b) -> a -> b
$ Fd -> CStr -> CInt -> CMode -> IO Fd
c_openat Fd
fd CStr
path CInt
flag CMode
mode

openatExn :: Fd -> CString -> OpenFlag -> CMode -> IO Fd
openatExn :: Fd -> CString -> OpenFlag -> CMode -> IO Fd
openatExn Fd
fd CString
path OpenFlag
flag CMode
mode =
    EIO Fd -> IO Fd
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO Fd -> IO Fd) -> EIO Fd -> IO Fd
forall a b. (a -> b) -> a -> b
$ Fd -> CString -> OpenFlag -> CMode -> EIO Fd
openat Fd
fd CString
path OpenFlag
flag CMode
mode

o_APPEND :: OpenFlag
o_APPEND    = CInt -> OpenFlag
OpenFlag CInt
c_O_APPEND
o_CLOEXEC :: OpenFlag
o_CLOEXEC   = CInt -> OpenFlag
OpenFlag CInt
c_O_CLOEXEC
o_CREAT :: OpenFlag
o_CREAT     = CInt -> OpenFlag
OpenFlag CInt
c_O_CREAT
o_DIRECTORY :: OpenFlag
o_DIRECTORY = CInt -> OpenFlag
OpenFlag CInt
c_O_DIRECTORY
o_EXCL :: OpenFlag
o_EXCL      = CInt -> OpenFlag
OpenFlag CInt
c_O_EXCL
o_NOFOLLOW :: OpenFlag
o_NOFOLLOW  = CInt -> OpenFlag
OpenFlag CInt
c_O_NOFOLLOW
o_NONBLOCK :: OpenFlag
o_NONBLOCK  = CInt -> OpenFlag
OpenFlag CInt
c_O_NONBLOCK
o_NDELAY :: OpenFlag
o_NDELAY    = CInt -> OpenFlag
OpenFlag CInt
c_O_NDELAY
o_TRUNC :: OpenFlag
o_TRUNC     = CInt -> OpenFlag
OpenFlag CInt
c_O_TRUNC
o_RDONLY :: OpenFlag
o_RDONLY    = CInt -> OpenFlag
OpenFlag CInt
c_O_RDONLY
o_WRONLY :: OpenFlag
o_WRONLY    = CInt -> OpenFlag
OpenFlag CInt
c_O_WRONLY
o_RDWR :: OpenFlag
o_RDWR      = CInt -> OpenFlag
OpenFlag CInt
c_O_RDWR

close :: Fd -> EIO ()
close :: Fd -> EIO ()
close Fd
fd =
    IO () -> EIO ()
forall a. IO a -> IO (Either Errno a)
orErrno (IO () -> EIO ()) -> IO () -> EIO ()
forall a b. (a -> b) -> a -> b
$ IO CInt -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO CInt -> IO ()) -> IO CInt -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> IO CInt
c_close Fd
fd
    -- We intentionally do not retryEINTR; posix is silent on whether
    -- the file descriptor will be closed after an EINTR return, but on
    -- at least Linux the answer is always yes, so we must not retry
    -- in case the file descriptor has been re-allocated by another thread.

closeExn :: Fd -> IO ()
closeExn :: Fd -> IO ()
closeExn Fd
fd = EIO () -> IO ()
forall a. IO (Either Errno a) -> IO a
throwIfErrno (EIO () -> IO ()) -> EIO () -> IO ()
forall a b. (a -> b) -> a -> b
$ Fd -> EIO ()
close Fd
fd