module Foreign.C.Error.Safe
(
eitherErrnoIf
, eitherErrnoIfRetry
, eitherErrnoIfRetryMayBlock
, eitherErrnoIfMinus1
, eitherErrnoIfMinus1Retry
, eitherErrnoIfMinus1RetryMayBlock
, eitherErrnoIfNull
, eitherErrnoIfNullRetry
, eitherErrnoIfNullRetryMayBlock
) where
import qualified Foreign.C.Error as C
import qualified Foreign.Ptr as FFI
eitherErrnoIf
:: (a -> Bool)
-> IO a
-> IO (Either C.Errno a)
eitherErrnoIf p io = do
a <- io
if p a
then do
errno <- C.getErrno
return (Left errno)
else return (Right a)
eitherErrnoIfRetry
:: (a -> Bool)
-> IO a
-> IO (Either C.Errno a)
eitherErrnoIfRetry p io = loop
where
loop = do
a <- io
if p a
then do
errno <- C.getErrno
if errno == C.eINTR
then loop
else return (Left errno)
else return (Right a)
eitherErrnoIfRetryMayBlock
:: (a -> Bool)
-> IO a
-> IO b
-> IO (Either C.Errno a)
eitherErrnoIfRetryMayBlock p f on_block = loop
where
loop = do
a <- f
if p a
then do
errno <- C.getErrno
if errno == C.eINTR
then loop
else if errno == C.eWOULDBLOCK || errno == C.eAGAIN
then on_block >> loop
else return (Left errno)
else return (Right a)
eitherErrnoIfMinus1 :: (Num a) => IO a -> IO (Either C.Errno a)
eitherErrnoIfMinus1 = eitherErrnoIf (1 ==)
eitherErrnoIfMinus1Retry :: (Num a) => IO a -> IO (Either C.Errno a)
eitherErrnoIfMinus1Retry = eitherErrnoIfRetry (1 ==)
eitherErrnoIfMinus1RetryMayBlock
:: (Num a) => IO a -> IO b -> IO (Either C.Errno a)
eitherErrnoIfMinus1RetryMayBlock =
eitherErrnoIfRetryMayBlock (1 ==)
eitherErrnoIfNull :: IO (FFI.Ptr a) -> IO (Either C.Errno (FFI.Ptr a))
eitherErrnoIfNull = eitherErrnoIf (== FFI.nullPtr)
eitherErrnoIfNullRetry :: IO (FFI.Ptr a) -> IO (Either C.Errno (FFI.Ptr a))
eitherErrnoIfNullRetry = eitherErrnoIfRetry (== FFI.nullPtr)
eitherErrnoIfNullRetryMayBlock
:: IO (FFI.Ptr a) -> IO b -> IO (Either C.Errno (FFI.Ptr a))
eitherErrnoIfNullRetryMayBlock =
eitherErrnoIfRetryMayBlock (== FFI.nullPtr)