module System.LibFuse3.Utils
(
testBitSet
,
unErrno, ioErrorToErrno, throwErrnoOf, tryErrno, tryErrno_, tryErrno', tryErrno_'
,
pread, pwrite, c_pread, c_pwrite
,
pokeCStringLen0
,
timeSpecToPOSIXTime
)
where
import Control.Exception (SomeException, try, tryJust)
import Data.Bits ((.&.), Bits)
import Data.ByteString (ByteString)
import Data.Ratio ((%))
import Data.Time.Clock.POSIX (POSIXTime)
import Foreign (Ptr, allocaBytes, copyArray, pokeElemOff)
import Foreign.C (CInt(CInt), CSize(CSize), CStringLen, Errno(Errno), eIO, eOK, errnoToIOError, getErrno, throwErrno, throwErrnoIfMinus1, withCStringLen)
import GHC.IO.Exception (IOException(IOError, ioe_errno))
import System.Clock (TimeSpec)
import System.Posix.Types (ByteCount, COff(COff), CSsize(CSsize), Fd(Fd), FileOffset)
import qualified Data.ByteString as B
import qualified Data.ByteString.Unsafe as BU
import qualified System.Clock as TimeSpec
try_ :: IO a -> IO (Either SomeException a)
try_ :: IO a -> IO (Either SomeException a)
try_ = IO a -> IO (Either SomeException a)
forall e a. Exception e => IO a -> IO (Either e a)
try
unErrno :: Errno -> CInt
unErrno :: Errno -> CInt
unErrno (Errno CInt
errno) = CInt
errno
ioErrorToErrno :: IOError -> Maybe Errno
ioErrorToErrno :: IOError -> Maybe Errno
ioErrorToErrno IOError{ioe_errno :: IOError -> Maybe CInt
ioe_errno=Just CInt
e} = Errno -> Maybe Errno
forall a. a -> Maybe a
Just (Errno -> Maybe Errno) -> Errno -> Maybe Errno
forall a b. (a -> b) -> a -> b
$ CInt -> Errno
Errno CInt
e
ioErrorToErrno IOError
_ = Maybe Errno
forall a. Maybe a
Nothing
throwErrnoOf
:: String
-> Errno
-> IO a
throwErrnoOf :: String -> Errno -> IO a
throwErrnoOf String
loc Errno
errno = IOError -> IO a
forall a. IOError -> IO a
ioError (String -> Errno -> Maybe Handle -> Maybe String -> IOError
errnoToIOError String
loc Errno
errno Maybe Handle
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing)
where
_dummyToSuppressWarnings :: t
_dummyToSuppressWarnings = String -> IO Errno -> (String -> IO Any) -> t
forall a. HasCallStack => String -> a
error String
"dummy" IO Errno
getErrno String -> IO Any
forall a. String -> IO a
throwErrno
tryErrno :: IO a -> IO (Either Errno a)
tryErrno :: IO a -> IO (Either Errno a)
tryErrno = (IOError -> Maybe Errno) -> IO a -> IO (Either Errno a)
forall e b a.
Exception e =>
(e -> Maybe b) -> IO a -> IO (Either b a)
tryJust IOError -> Maybe Errno
ioErrorToErrno
tryErrno_ :: IO a -> IO Errno
tryErrno_ :: IO a -> IO Errno
tryErrno_ = (Either Errno a -> Errno) -> IO (Either Errno a) -> IO Errno
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Errno -> Errno) -> (a -> Errno) -> Either Errno a -> Errno
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Errno -> Errno
forall a. a -> a
id (Errno -> a -> Errno
forall a b. a -> b -> a
const Errno
eOK)) (IO (Either Errno a) -> IO Errno)
-> (IO a -> IO (Either Errno a)) -> IO a -> IO Errno
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IO (Either Errno a)
forall a. IO a -> IO (Either Errno a)
tryErrno
tryErrno' :: IO a -> IO (Either Errno a)
tryErrno' :: IO a -> IO (Either Errno a)
tryErrno' = (Either SomeException (Either Errno a) -> Either Errno a)
-> IO (Either SomeException (Either Errno a))
-> IO (Either Errno a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((SomeException -> Either Errno a)
-> (Either Errno a -> Either Errno a)
-> Either SomeException (Either Errno a)
-> Either Errno a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Either Errno a -> SomeException -> Either Errno a
forall a b. a -> b -> a
const (Either Errno a -> SomeException -> Either Errno a)
-> Either Errno a -> SomeException -> Either Errno a
forall a b. (a -> b) -> a -> b
$ Errno -> Either Errno a
forall a b. a -> Either a b
Left Errno
eIO) Either Errno a -> Either Errno a
forall a. a -> a
id) (IO (Either SomeException (Either Errno a)) -> IO (Either Errno a))
-> (IO a -> IO (Either SomeException (Either Errno a)))
-> IO a
-> IO (Either Errno a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO (Either Errno a) -> IO (Either SomeException (Either Errno a))
forall a. IO a -> IO (Either SomeException a)
try_ (IO (Either Errno a) -> IO (Either SomeException (Either Errno a)))
-> (IO a -> IO (Either Errno a))
-> IO a
-> IO (Either SomeException (Either Errno a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IO (Either Errno a)
forall a. IO a -> IO (Either Errno a)
tryErrno
tryErrno_' :: IO a -> IO Errno
tryErrno_' :: IO a -> IO Errno
tryErrno_' = (Either SomeException Errno -> Errno)
-> IO (Either SomeException Errno) -> IO Errno
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((SomeException -> Errno)
-> (Errno -> Errno) -> Either SomeException Errno -> Errno
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Errno -> SomeException -> Errno
forall a b. a -> b -> a
const Errno
eIO) Errno -> Errno
forall a. a -> a
id) (IO (Either SomeException Errno) -> IO Errno)
-> (IO a -> IO (Either SomeException Errno)) -> IO a -> IO Errno
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO Errno -> IO (Either SomeException Errno)
forall a. IO a -> IO (Either SomeException a)
try_ (IO Errno -> IO (Either SomeException Errno))
-> (IO a -> IO Errno) -> IO a -> IO (Either SomeException Errno)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> IO Errno
forall a. IO a -> IO Errno
tryErrno_
timeSpecToPOSIXTime :: TimeSpec -> POSIXTime
timeSpecToPOSIXTime :: TimeSpec -> POSIXTime
timeSpecToPOSIXTime TimeSpec
ts = Rational -> POSIXTime
forall a. Fractional a => Rational -> a
fromRational (Rational -> POSIXTime) -> Rational -> POSIXTime
forall a b. (a -> b) -> a -> b
$ TimeSpec -> Integer
TimeSpec.toNanoSecs TimeSpec
ts Integer -> Integer -> Rational
forall a. Integral a => a -> a -> Ratio a
% Integer
10Integer -> Int -> Integer
forall a b. (Num a, Integral b) => a -> b -> a
^(Int
9::Int)
pokeCStringLen0 :: CStringLen -> String -> IO ()
pokeCStringLen0 :: CStringLen -> String -> IO ()
pokeCStringLen0 (Ptr CChar
pBuf, Int
bufSize) String
src =
String -> (CStringLen -> IO ()) -> IO ()
forall a. String -> (CStringLen -> IO a) -> IO a
withCStringLen String
src ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
pSrc, Int
srcSize) -> do
let bufSize0 :: Int
bufSize0 = Int
bufSize Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1
Ptr CChar -> Ptr CChar -> Int -> IO ()
forall a. Storable a => Ptr a -> Ptr a -> Int -> IO ()
copyArray Ptr CChar
pBuf Ptr CChar
pSrc (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
bufSize0 Int
srcSize)
Ptr CChar -> Int -> CChar -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff Ptr CChar
pBuf (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
bufSize0 Int
srcSize) CChar
0
testBitSet :: Bits a => a -> a -> Bool
testBitSet :: a -> a -> Bool
testBitSet a
bits a
mask = a
bits a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
mask a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
mask
pread :: Fd -> ByteCount -> FileOffset -> IO ByteString
pread :: Fd -> ByteCount -> FileOffset -> IO ByteString
pread (Fd CInt
fd) ByteCount
size FileOffset
off =
Int -> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (ByteCount -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ByteCount
size) ((Ptr CChar -> IO ByteString) -> IO ByteString)
-> (Ptr CChar -> IO ByteString) -> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
buf -> do
CSsize
readBytes <- String -> IO CSsize -> IO CSsize
forall a. (Eq a, Num a) => String -> IO a -> IO a
throwErrnoIfMinus1 String
"pread" (IO CSsize -> IO CSsize) -> IO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ CInt -> Ptr CChar -> ByteCount -> FileOffset -> IO CSsize
forall a. CInt -> Ptr a -> ByteCount -> FileOffset -> IO CSsize
c_pread CInt
fd Ptr CChar
buf ByteCount
size FileOffset
off
CStringLen -> IO ByteString
B.packCStringLen (Ptr CChar
buf, CSsize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSsize
readBytes)
pwrite :: Fd -> ByteString -> FileOffset -> IO CSsize
pwrite :: Fd -> ByteString -> FileOffset -> IO CSsize
pwrite (Fd CInt
fd) ByteString
bs FileOffset
off =
ByteString -> (CStringLen -> IO CSsize) -> IO CSsize
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BU.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO CSsize) -> IO CSsize)
-> (CStringLen -> IO CSsize) -> IO CSsize
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
buf, Int
size) ->
String -> IO CSsize -> IO CSsize
forall a. (Eq a, Num a) => String -> IO a -> IO a
throwErrnoIfMinus1 String
"pwrite" (IO CSsize -> IO CSsize) -> IO CSsize -> IO CSsize
forall a b. (a -> b) -> a -> b
$ CInt -> Ptr CChar -> ByteCount -> FileOffset -> IO CSsize
forall a. CInt -> Ptr a -> ByteCount -> FileOffset -> IO CSsize
c_pwrite CInt
fd Ptr CChar
buf (Int -> ByteCount
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
size) FileOffset
off
foreign import ccall "pread"
c_pread :: CInt -> Ptr a -> CSize -> COff -> IO CSsize
foreign import ccall "pwrite"
c_pwrite :: CInt -> Ptr a -> CSize -> COff -> IO CSsize