Move file check functions to HPath.IO

This commit is contained in:
Julian Ospald 2020-01-13 23:12:55 +01:00
parent 931851c8c1
commit 6a1f80bc17
No known key found for this signature in database
GPG Key ID: 511B62C09D50CD28
4 changed files with 94 additions and 43 deletions

View File

@ -73,7 +73,6 @@ test-suite spec
HPath.IO.GetFileTypeSpec HPath.IO.GetFileTypeSpec
HPath.IO.MoveFileOverwriteSpec HPath.IO.MoveFileOverwriteSpec
HPath.IO.MoveFileSpec HPath.IO.MoveFileSpec
HPath.IO.ReadFileEOFSpec
HPath.IO.ReadFileSpec HPath.IO.ReadFileSpec
HPath.IO.RecreateSymlinkOverwriteSpec HPath.IO.RecreateSymlinkOverwriteSpec
HPath.IO.RecreateSymlinkSpec HPath.IO.RecreateSymlinkSpec

View File

@ -73,6 +73,12 @@ module HPath.IO
-- * File permissions -- * File permissions
, newFilePerms , newFilePerms
, newDirPerms , newDirPerms
-- * File checks
, doesExist
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
-- * Directory reading -- * Directory reading
, getDirsFiles , getDirsFiles
-- * Filetype operations -- * Filetype operations
@ -191,7 +197,9 @@ import System.Posix.ByteString
import System.Posix.Directory.ByteString import System.Posix.Directory.ByteString
( (
createDirectory createDirectory
, closeDirStream
, getWorkingDirectory , getWorkingDirectory
, openDirStream
, removeDirectory , removeDirectory
) )
import System.Posix.Directory.Traversals import System.Posix.Directory.Traversals
@ -201,6 +209,7 @@ import System.Posix.Directory.Traversals
import System.Posix.Files.ByteString import System.Posix.Files.ByteString
( (
createSymbolicLink createSymbolicLink
, fileAccess
, fileMode , fileMode
, getFdStatus , getFdStatus
, groupExecuteMode , groupExecuteMode
@ -446,7 +455,9 @@ recreateSymlink symsource@(MkPath symsourceBS) newsym@(MkPath newsymBS) cm
case cm of case cm of
Strict -> return () Strict -> return ()
Overwrite -> do Overwrite -> do
writable <- toAbs newsym >>= isWritable writable <- toAbs newsym >>= (\p -> do
e <- doesExist p
if e then isWritable p else pure False)
isfile <- doesFileExist newsym isfile <- doesFileExist newsym
isdir <- doesDirectoryExist newsym isdir <- doesDirectoryExist newsym
when (writable && isfile) (deleteFile newsym) when (writable && isfile) (deleteFile newsym)
@ -830,7 +841,10 @@ moveFile from to cm = do
easyDelete from easyDelete from
Overwrite -> do Overwrite -> do
ft <- getFileType from ft <- getFileType from
writable <- toAbs to >>= isWritable writable <- toAbs to >>= (\p -> do
e <- doesFileExist p
if e then isWritable p else pure False)
case ft of case ft of
RegularFile -> do RegularFile -> do
exists <- doesFileExist to exists <- doesFileExist to
@ -980,6 +994,72 @@ newDirPerms
-------------------
--[ File checks ]--
-------------------
-- |Checks if the given file exists.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesExist :: Path b -> IO Bool
doesExist (MkPath bs) =
catchErrno [eNOENT] (do
_ <- PF.getSymbolicLinkStatus bs
return $ True)
$ return False
-- |Checks if the given file exists and is not a directory.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesFileExist :: Path b -> IO Bool
doesFileExist (MkPath bs) =
catchErrno [eNOENT] (do
fs <- PF.getSymbolicLinkStatus bs
return $ not . PF.isDirectory $ fs)
$ return False
-- |Checks if the given file exists and is a directory.
-- Does not follow symlinks.
--
-- Only eNOENT is catched (and returns False).
doesDirectoryExist :: Path b -> IO Bool
doesDirectoryExist (MkPath bs) =
catchErrno [eNOENT] (do
fs <- PF.getSymbolicLinkStatus bs
return $ PF.isDirectory fs)
$ return False
-- |Checks whether a file or folder is writable.
--
-- Only eACCES, eROFS, eTXTBSY, ePERM are catched (and return False).
--
-- Throws:
--
-- - `NoSuchThing` if the file does not exist
isWritable :: Path b -> IO Bool
isWritable (MkPath bs) = fileAccess bs False True False
-- |Checks whether the directory at the given path exists and can be
-- opened. This invokes `openDirStream` which follows symlinks.
canOpenDirectory :: Path b -> IO Bool
canOpenDirectory (MkPath bs) =
handleIOError (\_ -> return False) $ do
bracket (openDirStream bs)
closeDirStream
(\_ -> return ())
return True
------------------------- -------------------------
--[ Directory reading ]-- --[ Directory reading ]--
------------------------- -------------------------

View File

@ -6,3 +6,11 @@ import HPath
canonicalizePath :: Path b -> IO (Path Abs) canonicalizePath :: Path b -> IO (Path Abs)
toAbs :: Path b -> IO (Path Abs) toAbs :: Path b -> IO (Path Abs)
doesFileExist :: Path b -> IO Bool
doesDirectoryExist :: Path b -> IO Bool
isWritable :: Path b -> IO Bool
canOpenDirectory :: Path b -> IO Bool

View File

@ -33,10 +33,6 @@ module HPath.IO.Errors
, throwSameFile , throwSameFile
, sameFile , sameFile
, throwDestinationInSource , throwDestinationInSource
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
-- * Error handling functions -- * Error handling functions
, catchErrno , catchErrno
@ -92,6 +88,10 @@ import {-# SOURCE #-} HPath.IO
( (
canonicalizePath canonicalizePath
, toAbs , toAbs
, doesFileExist
, doesDirectoryExist
, isWritable
, canOpenDirectory
) )
import System.IO.Error import System.IO.Error
( (
@ -242,42 +242,6 @@ throwDestinationInSource (MkPath sbs) dest@(MkPath dbs) = do
(throwIO $ DestinationInSource dbs sbs) (throwIO $ DestinationInSource dbs sbs)
-- |Checks if the given file exists and is not a directory.
-- Does not follow symlinks.
doesFileExist :: Path b -> IO Bool
doesFileExist (MkPath bs) =
handleIOError (\_ -> return False) $ do
fs <- PF.getSymbolicLinkStatus bs
return $ not . PF.isDirectory $ fs
-- |Checks if the given file exists and is a directory.
-- Does not follow symlinks.
doesDirectoryExist :: Path b -> IO Bool
doesDirectoryExist (MkPath bs) =
handleIOError (\_ -> return False) $ do
fs <- PF.getSymbolicLinkStatus bs
return $ PF.isDirectory fs
-- |Checks whether a file or folder is writable.
isWritable :: Path b -> IO Bool
isWritable (MkPath bs) =
handleIOError (\_ -> return False) $
fileAccess bs False True False
-- |Checks whether the directory at the given path exists and can be
-- opened. This invokes `openDirStream` which follows symlinks.
canOpenDirectory :: Path b -> IO Bool
canOpenDirectory (MkPath bs) =
handleIOError (\_ -> return False) $ do
bracket (PFD.openDirStream bs)
PFD.closeDirStream
(\_ -> return ())
return True
-------------------------------- --------------------------------