module Z.IO.FileSystem.Base
(
File, initFile, readFileP, writeFileP, getFileFD, seek
, readFile, readTextFile, writeFile, writeTextFile
, readJSONFile, writeJSONFile
, FilePtr, newFilePtr, getFilePtrOffset, setFilePtrOffset
, mkdir, mkdirp
, unlink
, mkdtemp, mkstemp , initTempFile, initTempDir
, rmdir, rmrf
, DirEntType(..)
, scandir
, scandirRecursively
, FStat(..), UVTimeSpec(..)
, doesPathExist, doesFileExist, doesDirExist
, isLink, isDir, isFile
, isLinkSt, isDirSt, isFileSt
, stat, lstat, fstat
, stat', lstat'
, rename
, fsync, fdatasync
, ftruncate
, copyfile
, AccessResult(..)
, access
, chmod, fchmod
, utime, futime, lutime
, link, symlink
, readlink, realpath
, chown, fchown, lchown
, AccessMode
, pattern F_OK
, pattern R_OK
, pattern W_OK
, pattern X_OK
, FileMode
, pattern DEFAULT_FILE_MODE
, pattern DEFAULT_DIR_MODE
, pattern S_IRWXU
, pattern S_IRUSR
, pattern S_IWUSR
, pattern S_IXUSR
, pattern S_IRWXG
, pattern S_IRGRP
, pattern S_IWGRP
, pattern S_IXGRP
, pattern S_IRWXO
, pattern S_IROTH
, pattern S_IFMT
, pattern S_IFLNK
, pattern S_IFDIR
, pattern S_IFREG
, FileFlag
, pattern O_APPEND
, pattern O_CREAT
, pattern O_DIRECT
, pattern O_DSYNC
, pattern O_EXCL
, pattern O_EXLOCK
, pattern O_NOATIME
, pattern O_NOFOLLOW
, pattern O_RDONLY
, pattern O_RDWR
, pattern O_SYMLINK
, pattern O_SYNC
, pattern O_TRUNC
, pattern O_WRONLY
, pattern O_RANDOM
, pattern O_SHORT_LIVED
, pattern O_SEQUENTIAL
, pattern O_TEMPORARY
, CopyFileFlag
, pattern COPYFILE_DEFAULT
, pattern COPYFILE_EXCL
, pattern COPYFILE_FICLONE
, pattern COPYFILE_FICLONE_FORCE
, SymlinkFlag
, pattern SYMLINK_DEFAULT
, pattern SYMLINK_DIR
, pattern SYMLINK_JUNCTION
, Whence
, pattern SEEK_SET
, pattern SEEK_CUR
, pattern SEEK_END
) where
import Control.Monad
import Data.Bits
import Data.IORef
import Data.Int
import Data.Word
import Foreign.Marshal.Alloc (allocaBytes)
import Foreign.Ptr
import Foreign.Storable (peekElemOff)
import Prelude hiding (readFile, writeFile)
import qualified Z.Data.Builder as B
import Z.Data.CBytes as CBytes
import qualified Z.Data.JSON as JSON
import Z.Data.PrimRef
import qualified Z.Data.Text as T
import qualified Z.Data.Text.Print as T
import qualified Z.Data.Vector as V
import Z.Foreign
import Z.IO.Buffered
import qualified Z.IO.Environment as Env
import Z.IO.Exception
import qualified Z.IO.FileSystem.FilePath as P
import Z.IO.Resource
import Z.IO.UV.FFI
#include "fs_shared.hs"
data File = File {-# UNPACK #-} !FD
{-# UNPACK #-} !(IORef Bool)
instance Show File where show :: File -> String
show = forall a. Print a => a -> String
T.toString
instance T.Print File where
toUTF8BuilderP :: Int -> File -> Builder ()
toUTF8BuilderP Int
_ (File FileMode
fd IORef Bool
_) = Builder ()
"File " forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. (Integral a, Bounded a) => a -> Builder ()
T.int FileMode
fd
getFileFD :: File -> IO FD
{-# INLINABLE getFileFD #-}
getFileFD :: File -> IO FileMode
getFileFD (File FileMode
fd IORef Bool
closedRef) = do
Bool
closed <- forall a. IORef a -> IO a
readIORef IORef Bool
closedRef
if Bool
closed then forall a. HasCallStack => IO a
throwECLOSED else forall (m :: * -> *) a. Monad m => a -> m a
return FileMode
fd
checkFileClosed :: HasCallStack => File -> (FD -> IO a) -> IO a
{-# INLINABLE checkFileClosed #-}
checkFileClosed :: forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed (File FileMode
fd IORef Bool
closedRef) FileMode -> IO a
f = do
Bool
closed <- forall a. IORef a -> IO a
readIORef IORef Bool
closedRef
if Bool
closed then forall a. HasCallStack => IO a
throwECLOSED else FileMode -> IO a
f FileMode
fd
seek :: HasCallStack => File -> Int64 -> Whence -> IO Int64
{-# INLINABLE seek #-}
seek :: HasCallStack => File -> Int64 -> FileMode -> IO Int64
seek File
uvf Int64
off FileMode
w = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus forall a b. (a -> b) -> a -> b
$ FileMode -> Int64 -> FileMode -> IO Int64
hs_seek FileMode
fd Int64
off FileMode
w
instance Input File where
{-# INLINABLE readInput #-}
readInput :: File -> Ptr Word8 -> Int -> IO Int
readInput File
f Ptr Word8
buf Int
bufSiz = HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO Int
readFileP File
f Ptr Word8
buf Int
bufSiz (-Int64
1)
readFileP :: HasCallStack
=> File
-> Ptr Word8
-> Int
-> Int64
-> IO Int
{-# INLINABLE readFileP #-}
readFileP :: HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO Int
readFileP File
uvf Ptr Word8
buf Int
bufSiz Int64
off =
forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus forall a b. (a -> b) -> a -> b
$ FileMode -> Ptr Word8 -> Int -> Int64 -> IO Int
hs_uv_fs_read FileMode
fd Ptr Word8
buf Int
bufSiz Int64
off
instance Output File where
{-# INLINABLE writeOutput #-}
writeOutput :: File -> Ptr Word8 -> Int -> IO ()
writeOutput File
f Ptr Word8
buf Int
bufSiz = HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO ()
writeFileP File
f Ptr Word8
buf Int
bufSiz (-Int64
1)
writeFileP :: HasCallStack
=> File
-> Ptr Word8
-> Int
-> Int64
-> IO ()
{-# INLINABLE writeFileP #-}
writeFileP :: HasCallStack => File -> Ptr Word8 -> Int -> Int64 -> IO ()
writeFileP File
uvf Ptr Word8
buf0 Int
bufSiz0 Int64
off0 =
forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \FileMode
fd -> if Int64
off0 forall a. Eq a => a -> a -> Bool
== -Int64
1 then FileMode -> Ptr Word8 -> Int -> IO ()
go FileMode
fd Ptr Word8
buf0 Int
bufSiz0
else FileMode -> Ptr Word8 -> Int -> Int64 -> IO ()
go' FileMode
fd Ptr Word8
buf0 Int
bufSiz0 Int64
off0
where
go :: FileMode -> Ptr Word8 -> Int -> IO ()
go FileMode
fd !Ptr Word8
buf !Int
bufSiz = do
Int
written <- forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (FileMode -> Ptr Word8 -> Int -> Int64 -> IO Int
hs_uv_fs_write FileMode
fd Ptr Word8
buf Int
bufSiz (-Int64
1))
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
written forall a. Ord a => a -> a -> Bool
< Int
bufSiz)
(FileMode -> Ptr Word8 -> Int -> IO ()
go FileMode
fd (Ptr Word8
buf forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
written) (Int
bufSizforall a. Num a => a -> a -> a
-Int
written))
go' :: FileMode -> Ptr Word8 -> Int -> Int64 -> IO ()
go' FileMode
fd !Ptr Word8
buf !Int
bufSiz !Int64
off = do
Int
written <- forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (FileMode -> Ptr Word8 -> Int -> Int64 -> IO Int
hs_uv_fs_write FileMode
fd Ptr Word8
buf Int
bufSiz Int64
off)
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Int
written forall a. Ord a => a -> a -> Bool
< Int
bufSiz) forall a b. (a -> b) -> a -> b
$
FileMode -> Ptr Word8 -> Int -> Int64 -> IO ()
go' FileMode
fd (Ptr Word8
buf forall a b. Ptr a -> Int -> Ptr b
`plusPtr` Int
written)
(Int
bufSizforall a. Num a => a -> a -> a
-Int
written)
(Int64
offforall a. Num a => a -> a -> a
+forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
written)
initFile :: HasCallStack
=> CBytes
-> FileFlag
-> FileMode
-> Resource File
{-# INLINABLE initFile #-}
initFile :: HasCallStack => CBytes -> FileMode -> FileMode -> Resource File
initFile CBytes
path FileMode
flags FileMode
mode =
forall a. IO a -> (a -> IO ()) -> Resource a
initResource
(do !FileMode
fd <- forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus forall a b. (a -> b) -> a -> b
$ BA# Word8 -> FileMode -> FileMode -> IO FileMode
hs_uv_fs_open BA# Word8
p FileMode
flags FileMode
mode
FileMode -> IORef Bool -> File
File FileMode
fd forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. a -> IO (IORef a)
newIORef Bool
False)
(\ (File FileMode
fd IORef Bool
closedRef) -> do
Bool
closed <- forall a. IORef a -> IO a
readIORef IORef Bool
closedRef
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
closed forall a b. (a -> b) -> a -> b
$ do
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (FileMode -> IO Int
hs_uv_fs_close FileMode
fd)
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
closedRef Bool
True)
mkdir :: HasCallStack => CBytes -> FileMode -> IO ()
{-# INLINABLE mkdir #-}
mkdir :: HasCallStack => CBytes -> FileMode -> IO ()
mkdir CBytes
path FileMode
mode = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
BA# Word8 -> FileMode -> IO Int
hs_uv_fs_mkdir BA# Word8
p FileMode
mode
mkdirp :: HasCallStack => CBytes -> FileMode -> IO ()
{-# INLINABLE mkdirp #-}
mkdirp :: HasCallStack => CBytes -> FileMode -> IO ()
mkdirp CBytes
path FileMode
mode = do
Int
r <- forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> FileMode -> IO Int
hs_uv_fs_mkdir BA# Word8
p FileMode
mode
case forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
r of
FileMode
UV_ENOENT -> do
(CBytes
root, [CBytes]
segs) <- CBytes -> IO (CBytes, [CBytes])
P.splitSegments CBytes
path
case [CBytes]
segs of
CBytes
seg:[CBytes]
segs' -> [CBytes] -> CBytes -> IO ()
loop [CBytes]
segs' forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CBytes -> CBytes -> IO CBytes
P.join CBytes
root CBytes
seg
[CBytes]
_ -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV Int
r
FileMode
UV_EEXIST -> do
Bool
canIgnore <- HasCallStack => CBytes -> IO Bool
isDir CBytes
path
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
canIgnore forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV Int
r
FileMode
_ -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV Int
r
where
loop :: [CBytes] -> CBytes -> IO ()
loop [CBytes]
segs CBytes
p = do
AccessResult
a <- HasCallStack => CBytes -> FileMode -> IO AccessResult
access CBytes
p FileMode
F_OK
case AccessResult
a of
AccessResult
AccessOK -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
AccessResult
NoExistence -> HasCallStack => CBytes -> FileMode -> IO ()
mkdir CBytes
p FileMode
mode
AccessResult
NoPermission -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV FileMode
UV_EACCES
case [CBytes]
segs of
(CBytes
nextp:[CBytes]
ps) -> CBytes -> CBytes -> IO CBytes
P.join CBytes
p CBytes
nextp forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= [CBytes] -> CBytes -> IO ()
loop [CBytes]
ps
[CBytes]
_ -> forall (m :: * -> *) a. Monad m => a -> m a
return ()
unlink :: HasCallStack => CBytes -> IO ()
{-# INLINABLE unlink #-}
unlink :: HasCallStack => CBytes -> IO ()
unlink CBytes
path = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path BA# Word8 -> IO Int
hs_uv_fs_unlink)
mkdtemp :: HasCallStack => CBytes -> IO CBytes
{-# INLINABLE mkdtemp #-}
mkdtemp :: HasCallStack => CBytes -> IO CBytes
mkdtemp CBytes
path = do
let size :: Int
size = CBytes -> Int
CBytes.length CBytes
path
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> do
(CBytes
p',()
_) <- forall a.
HasCallStack =>
Int -> (MBA# Word8 -> IO a) -> IO (CBytes, a)
CBytes.allocCBytesUnsafe (Int
sizeforall a. Num a => a -> a -> a
+Int
7) forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
p' -> do
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (BA# Word8 -> Int -> MBA# Word8 -> IO Int
hs_uv_fs_mkdtemp BA# Word8
p Int
size MBA# Word8
p')
forall (m :: * -> *) a. Monad m => a -> m a
return CBytes
p'
mkstemp :: HasCallStack
=> CBytes
-> CBytes
-> Bool
-> Resource (CBytes, File)
{-# INLINABLE mkstemp #-}
mkstemp :: HasCallStack => CBytes -> CBytes -> Bool -> Resource (CBytes, File)
mkstemp CBytes
dir CBytes
template Bool
keep = do
forall a. IO a -> (a -> IO ()) -> Resource a
initResource
(do CBytes
template' <- CBytes
dir CBytes -> CBytes -> IO CBytes
`P.join` CBytes
template
let !size :: Int
size = CBytes -> Int
CBytes.length CBytes
template'
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
CBytes.withCBytesUnsafe CBytes
template' forall a b. (a -> b) -> a -> b
$ \BA# Word8
p -> do
(CBytes
p', Int
r) <- forall a.
HasCallStack =>
Int -> (MBA# Word8 -> IO a) -> IO (CBytes, a)
CBytes.allocCBytesUnsafe (Int
size forall a. Num a => a -> a -> a
+ Int
7) forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
p' -> do
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (BA# Word8 -> Int -> MBA# Word8 -> IO Int
hs_uv_fs_mkstemp BA# Word8
p Int
size MBA# Word8
p')
IORef Bool
closed <- forall a. a -> IO (IORef a)
newIORef Bool
False
forall (m :: * -> *) a. Monad m => a -> m a
return (CBytes
p', FileMode -> IORef Bool -> File
File (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
r) IORef Bool
closed))
(\ (CBytes
p, File FileMode
r IORef Bool
closed) -> do
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
keep (HasCallStack => CBytes -> IO ()
unlink CBytes
p)
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (FileMode -> IO Int
hs_uv_fs_close FileMode
r)
forall a. IORef a -> a -> IO ()
writeIORef IORef Bool
closed Bool
True)
rmdir :: HasCallStack => CBytes -> IO ()
{-# INLINABLE rmdir #-}
rmdir :: HasCallStack => CBytes -> IO ()
rmdir CBytes
path = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path BA# Word8 -> IO Int
hs_uv_fs_rmdir)
rmrf :: HasCallStack => CBytes -> IO ()
{-# INLINABLE rmrf #-}
rmrf :: HasCallStack => CBytes -> IO ()
rmrf CBytes
path =
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \BA# Word8
path' ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \Ptr FStat
s -> do
FileMode
r <- forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BA# Word8 -> Ptr FStat -> IO Int
hs_uv_fs_stat BA# Word8
path' Ptr FStat
s
if | FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
UV_ENOENT -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
| FileMode
r forall a. Ord a => a -> a -> Bool
< FileMode
0 -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV FileMode
r
| Bool
otherwise -> do
FStat
st <- Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
case FStat -> FileMode
stMode FStat
st forall a. Bits a => a -> a -> a
.&. FileMode
S_IFMT of
FileMode
S_IFREG -> HasCallStack => CBytes -> IO ()
unlink CBytes
path
FileMode
S_IFLNK -> HasCallStack => CBytes -> IO ()
unlink CBytes
path
FileMode
S_IFDIR -> do
[(CBytes, DirEntType)]
ds <- HasCallStack => CBytes -> IO [(CBytes, DirEntType)]
scandir CBytes
path
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [(CBytes, DirEntType)]
ds forall a b. (a -> b) -> a -> b
$ \ (CBytes
d, DirEntType
t) ->
if DirEntType
t forall a. Eq a => a -> a -> Bool
/= DirEntType
DirEntDir
then HasCallStack => CBytes -> IO ()
unlink CBytes
d
else HasCallStack => CBytes -> IO ()
rmrf forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< CBytes
path CBytes -> CBytes -> IO CBytes
`P.join` CBytes
d
HasCallStack => CBytes -> IO ()
rmdir CBytes
path
FileMode
mode -> do
let desc :: Text
desc = forall a. HasCallStack => Builder a -> Text
B.buildText forall a b. (a -> b) -> a -> b
$ Builder ()
"Unsupported file mode: " forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. (FiniteBits a, Integral a) => a -> Builder ()
B.hex FileMode
mode
forall e a. Exception e => e -> IO a
throwIO forall a b. (a -> b) -> a -> b
$ IOEInfo -> UnsupportedOperation
UnsupportedOperation (Text -> Text -> CallStack -> IOEInfo
IOEInfo Text
"" Text
desc HasCallStack => CallStack
callStack)
scandir :: HasCallStack => CBytes -> IO [(CBytes, DirEntType)]
{-# INLINABLE scandir #-}
scandir :: HasCallStack => CBytes -> IO [(CBytes, DirEntType)]
scandir CBytes
path = do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Prim a => (MBA# Word8 -> IO b) -> IO (a, b)
allocPrimUnsafe forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
dents ->
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (BA# Word8 -> MBA# Word8 -> IO Int
hs_uv_fs_scandir BA# Word8
p MBA# Word8
dents))
(\ (Ptr (Ptr DirEntType)
dents, Int
n) -> Ptr (Ptr DirEntType) -> Int -> IO ()
hs_uv_fs_scandir_cleanup Ptr (Ptr DirEntType)
dents Int
n)
(\ (Ptr (Ptr DirEntType)
dents, Int
n) -> forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [Int
0..Int
nforall a. Num a => a -> a -> a
-Int
1] forall a b. (a -> b) -> a -> b
$ \ Int
i -> do
Ptr DirEntType
dent <- forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr (Ptr DirEntType)
dents Int
i
(CString
p, UVDirEntType
typ) <- Ptr DirEntType -> IO (CString, UVDirEntType)
peekUVDirEnt Ptr DirEntType
dent
let !typ' :: DirEntType
typ' = UVDirEntType -> DirEntType
fromUVDirEntType UVDirEntType
typ
!CBytes
p' <- CString -> IO CBytes
fromCString CString
p
forall (m :: * -> *) a. Monad m => a -> m a
return (CBytes
p', DirEntType
typ'))
stat :: HasCallStack => CBytes -> IO FStat
{-# INLINABLE stat #-}
stat :: HasCallStack => CBytes -> IO FStat
stat CBytes
path = forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \ Ptr FStat
s -> do
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (BA# Word8 -> Ptr FStat -> IO Int
hs_uv_fs_stat BA# Word8
p Ptr FStat
s)
Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
lstat :: HasCallStack => CBytes -> IO FStat
{-# INLINABLE lstat #-}
lstat :: HasCallStack => CBytes -> IO FStat
lstat CBytes
path = forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \ Ptr FStat
s -> do
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (BA# Word8 -> Ptr FStat -> IO Int
hs_uv_fs_lstat BA# Word8
p Ptr FStat
s)
Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
stat' :: HasCallStack => CBytes -> IO (Maybe FStat)
{-# INLINABLE stat' #-}
stat' :: HasCallStack => CBytes -> IO (Maybe FStat)
stat' CBytes
path = forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \ Ptr FStat
s -> do
FileMode
r <- forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BA# Word8 -> Ptr FStat -> IO Int
hs_uv_fs_stat BA# Word8
p Ptr FStat
s
if | FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
UV_ENOENT -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| FileMode
r forall a. Ord a => a -> a -> Bool
< FileMode
0 -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV FileMode
r
| Bool
otherwise -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
lstat' :: HasCallStack => CBytes -> IO (Maybe FStat)
{-# INLINABLE lstat' #-}
lstat' :: HasCallStack => CBytes -> IO (Maybe FStat)
lstat' CBytes
path = forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \ Ptr FStat
s -> do
FileMode
r <- forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BA# Word8 -> Ptr FStat -> IO Int
hs_uv_fs_lstat BA# Word8
p Ptr FStat
s
if | FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
UV_ENOENT -> forall (m :: * -> *) a. Monad m => a -> m a
return forall a. Maybe a
Nothing
| FileMode
r forall a. Ord a => a -> a -> Bool
< FileMode
0 -> forall a b. (Integral a, HasCallStack) => a -> IO b
throwUV FileMode
r
| Bool
otherwise -> forall a. a -> Maybe a
Just forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
fstat :: HasCallStack => File -> IO FStat
{-# INLINABLE fstat #-}
fstat :: HasCallStack => File -> IO FStat
fstat File
uvf = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd ->
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes Int
uvStatSize forall a b. (a -> b) -> a -> b
$ \ Ptr FStat
s -> do
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (FileMode -> Ptr FStat -> IO Int
hs_uv_fs_fstat FileMode
fd Ptr FStat
s)
Ptr FStat -> IO FStat
peekUVStat Ptr FStat
s
rename :: HasCallStack => CBytes -> CBytes -> IO ()
{-# INLINABLE rename #-}
rename :: HasCallStack => CBytes -> CBytes -> IO ()
rename CBytes
path CBytes
path' = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path' (BA# Word8 -> BA# Word8 -> IO Int
hs_uv_fs_rename BA# Word8
p)
fsync :: HasCallStack => File -> IO ()
{-# INLINABLE fsync #-}
fsync :: HasCallStack => File -> IO ()
fsync File
uvf = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall a b. (a -> b) -> a -> b
$ FileMode -> IO Int
hs_uv_fs_fsync FileMode
fd
fdatasync :: HasCallStack => File -> IO ()
{-# INLINABLE fdatasync #-}
fdatasync :: HasCallStack => File -> IO ()
fdatasync File
uvf = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall a b. (a -> b) -> a -> b
$ FileMode -> IO Int
hs_uv_fs_fdatasync FileMode
fd
ftruncate :: HasCallStack => File -> Int64 -> IO ()
{-# INLINABLE ftruncate #-}
ftruncate :: HasCallStack => File -> Int64 -> IO ()
ftruncate File
uvf Int64
off = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall a b. (a -> b) -> a -> b
$ FileMode -> Int64 -> IO Int
hs_uv_fs_ftruncate FileMode
fd Int64
off
copyfile :: HasCallStack => CBytes -> CBytes -> CopyFileFlag -> IO ()
{-# INLINABLE copyfile #-}
copyfile :: HasCallStack => CBytes -> CBytes -> FileMode -> IO ()
copyfile CBytes
path CBytes
path' FileMode
flag = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path' forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p' -> BA# Word8 -> BA# Word8 -> FileMode -> IO Int
hs_uv_fs_copyfile BA# Word8
p BA# Word8
p' FileMode
flag
access :: HasCallStack => CBytes -> AccessMode -> IO AccessResult
{-# INLINABLE access #-}
access :: HasCallStack => CBytes -> FileMode -> IO AccessResult
access CBytes
path FileMode
mode = do
FileMode
r <- forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> forall a b. (Integral a, Num b) => a -> b
fromIntegral forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> BA# Word8 -> FileMode -> IO Int
hs_uv_fs_access BA# Word8
p FileMode
mode
if | FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
0 -> forall (m :: * -> *) a. Monad m => a -> m a
return AccessResult
AccessOK
| FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
UV_ENOENT -> forall (m :: * -> *) a. Monad m => a -> m a
return AccessResult
NoExistence
| FileMode
r forall a. Eq a => a -> a -> Bool
== FileMode
UV_EACCES -> forall (m :: * -> *) a. Monad m => a -> m a
return AccessResult
NoPermission
| Bool
otherwise -> do
Text
name <- FileMode -> IO Text
uvErrName FileMode
r
Text
desc <- FileMode -> IO Text
uvStdError FileMode
r
forall a. FileMode -> IOEInfo -> IO a
throwUVError FileMode
r (Text -> Text -> CallStack -> IOEInfo
IOEInfo Text
name Text
desc HasCallStack => CallStack
callStack)
chmod :: HasCallStack => CBytes -> FileMode -> IO ()
{-# INLINABLE chmod #-}
chmod :: HasCallStack => CBytes -> FileMode -> IO ()
chmod CBytes
path FileMode
mode = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> FileMode -> IO Int
hs_uv_fs_chmod BA# Word8
p FileMode
mode
fchmod :: HasCallStack => File -> FileMode -> IO ()
{-# INLINABLE fchmod #-}
fchmod :: HasCallStack => File -> FileMode -> IO ()
fchmod File
uvf FileMode
mode = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall a b. (a -> b) -> a -> b
$ FileMode -> FileMode -> IO Int
hs_uv_fs_fchmod FileMode
fd FileMode
mode
utime :: HasCallStack
=> CBytes
-> Double
-> Double
-> IO ()
{-# INLINABLE utime #-}
utime :: HasCallStack => CBytes -> Double -> Double -> IO ()
utime CBytes
path Double
atime Double
mtime = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> Double -> Double -> IO Int
hs_uv_fs_utime BA# Word8
p Double
atime Double
mtime
futime :: HasCallStack => File -> Double -> Double -> IO ()
{-# INLINABLE futime #-}
futime :: HasCallStack => File -> Double -> Double -> IO ()
futime File
uvf Double
atime Double
mtime = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd ->
forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ (FileMode -> Double -> Double -> IO Int
hs_uv_fs_futime FileMode
fd Double
atime Double
mtime)
lutime :: HasCallStack
=> CBytes
-> Double
-> Double
-> IO ()
{-# INLINABLE lutime #-}
lutime :: HasCallStack => CBytes -> Double -> Double -> IO ()
lutime CBytes
path Double
atime Double
mtime = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> Double -> Double -> IO Int
hs_uv_fs_lutime BA# Word8
p Double
atime Double
mtime
link :: HasCallStack => CBytes -> CBytes -> IO ()
{-# INLINABLE link #-}
link :: HasCallStack => CBytes -> CBytes -> IO ()
link CBytes
path CBytes
path' = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path' forall a b. (a -> b) -> a -> b
$ BA# Word8 -> BA# Word8 -> IO Int
hs_uv_fs_link BA# Word8
p
symlink :: HasCallStack => CBytes -> CBytes -> SymlinkFlag -> IO ()
{-# INLINABLE symlink #-}
symlink :: HasCallStack => CBytes -> CBytes -> FileMode -> IO ()
symlink CBytes
path CBytes
path' FileMode
flag = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path' forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p' -> BA# Word8 -> BA# Word8 -> FileMode -> IO Int
hs_uv_fs_symlink BA# Word8
p BA# Word8
p' FileMode
flag
readlink :: HasCallStack => CBytes -> IO CBytes
{-# INLINABLE readlink #-}
readlink :: HasCallStack => CBytes -> IO CBytes
readlink CBytes
path = do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Prim a => (MBA# Word8 -> IO b) -> IO (a, b)
allocPrimUnsafe forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
p' ->
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (BA# Word8 -> MBA# Word8 -> IO Int
hs_uv_fs_readlink BA# Word8
p MBA# Word8
p'))
(CString -> IO ()
hs_uv_fs_readlink_cleanup forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst)
(CString -> IO CBytes
fromCString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst)
realpath :: HasCallStack => CBytes -> IO CBytes
{-# INLINABLE realpath #-}
realpath :: HasCallStack => CBytes -> IO CBytes
realpath CBytes
path = do
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
(forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p ->
forall a b. Prim a => (MBA# Word8 -> IO b) -> IO (a, b)
allocPrimUnsafe forall a b. (a -> b) -> a -> b
$ \ MBA# Word8
p' ->
forall a. (HasCallStack, Integral a) => IO a -> IO a
throwUVIfMinus (BA# Word8 -> MBA# Word8 -> IO Int
hs_uv_fs_realpath BA# Word8
p MBA# Word8
p'))
(CString -> IO ()
hs_uv_fs_readlink_cleanup forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst)
(CString -> IO CBytes
fromCString forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst)
chown :: HasCallStack => CBytes -> UID -> GID -> IO ()
{-# INLINABLE chown #-}
chown :: HasCallStack => CBytes -> UID -> GID -> IO ()
chown CBytes
path UID
uid GID
gid = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> UID -> GID -> IO Int
hs_uv_fs_chown BA# Word8
p UID
uid GID
gid
fchown :: HasCallStack => File -> UID -> GID -> IO ()
{-# INLINABLE fchown #-}
fchown :: HasCallStack => File -> UID -> GID -> IO ()
fchown File
uvf UID
uid GID
gid = forall a. HasCallStack => File -> (FileMode -> IO a) -> IO a
checkFileClosed File
uvf forall a b. (a -> b) -> a -> b
$ \ FileMode
fd -> forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall a b. (a -> b) -> a -> b
$ FileMode -> UID -> GID -> IO Int
hs_uv_fs_fchown FileMode
fd UID
uid GID
gid
lchown :: HasCallStack => CBytes -> UID -> GID -> IO ()
{-# INLINABLE lchown #-}
lchown :: HasCallStack => CBytes -> UID -> GID -> IO ()
lchown CBytes
path UID
uid GID
gid = forall a. (HasCallStack, Integral a) => IO a -> IO ()
throwUVIfMinus_ forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. CBytes -> (BA# Word8 -> IO a) -> IO a
withCBytesUnsafe CBytes
path forall a b. (a -> b) -> a -> b
$ \ BA# Word8
p -> BA# Word8 -> UID -> GID -> IO Int
hs_uv_fs_lchown BA# Word8
p UID
uid GID
gid