Safe Haskell | None |
---|---|
Language | Haskell98 |
Re-exports some of propellor's internal utility modules.
These are used in the implementation of propellor, including some of its properties. However, there is no API stability; any of these can change or be removed without a major version number increase.
Use outside propellor at your own risk.
Synopsis
- read :: Read a => String -> a
- head :: [a] -> a
- tail :: [a] -> [a]
- init :: [a] -> [a]
- last :: [a] -> a
- readish :: Read a => String -> Maybe a
- headMaybe :: [a] -> Maybe a
- lastMaybe :: [a] -> Maybe a
- beginning :: [a] -> [a]
- end :: [a] -> [a]
- runCommand :: String -> IO ProcessHandle
- terminateProcess :: ProcessHandle -> IO ()
- getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode)
- getPid :: ProcessHandle -> IO (Maybe Pid)
- showCommandForUser :: FilePath -> [String] -> String
- readCreateProcessWithExitCode :: CreateProcess -> String -> IO (ExitCode, String, String)
- readCreateProcess :: CreateProcess -> String -> IO String
- callCommand :: String -> IO ()
- callProcess :: FilePath -> [String] -> IO ()
- spawnCommand :: String -> IO ProcessHandle
- spawnProcess :: FilePath -> [String] -> IO ProcessHandle
- cleanupProcess :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO ()
- withCreateProcess :: CreateProcess -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a) -> IO a
- shell :: String -> CreateProcess
- proc :: FilePath -> [String] -> CreateProcess
- type Pid = CPid
- interruptProcessGroupOf :: ProcessHandle -> IO ()
- createPipeFd :: IO (FD, FD)
- createPipe :: IO (Handle, Handle)
- createProcess_ :: String -> CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
- data CmdSpec
- data StdStream
- data ProcessHandle
- data CreateProcess = CreateProcess {
- cmdspec :: CmdSpec
- cwd :: Maybe FilePath
- env :: Maybe [(String, String)]
- std_in :: StdStream
- std_out :: StdStream
- std_err :: StdStream
- close_fds :: Bool
- create_group :: Bool
- delegate_ctlc :: Bool
- detach_console :: Bool
- create_new_console :: Bool
- new_session :: Bool
- child_group :: Maybe GroupID
- child_user :: Maybe UserID
- use_process_jobs :: Bool
- data StdHandle
- readProcess :: FilePath -> [String] -> IO String
- readProcess' :: CreateProcess -> IO String
- readProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> IO String
- writeReadProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> Maybe (Handle -> IO ()) -> Maybe (Handle -> IO ()) -> IO String
- forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO ()
- forceSuccessProcess' :: CreateProcess -> ExitCode -> IO ()
- checkSuccessProcess :: ProcessHandle -> IO Bool
- ignoreFailureProcess :: ProcessHandle -> IO Bool
- createProcessSuccess :: CreateProcessRunner
- createProcessChecked :: (ProcessHandle -> IO b) -> CreateProcessRunner
- createBackgroundProcess :: CreateProcessRunner
- withHandle :: StdHandle -> CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a
- withIOHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a
- withOEHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a
- withNullHandle :: (Handle -> IO a) -> IO a
- withQuietOutput :: CreateProcessRunner -> CreateProcess -> IO ()
- feedWithQuietOutput :: CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a
- createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)
- waitForProcess :: ProcessHandle -> IO ExitCode
- startInteractiveProcess :: FilePath -> [String] -> Maybe [(String, String)] -> IO (ProcessHandle, Handle, Handle)
- stdinHandle :: HandleExtractor
- stdoutHandle :: HandleExtractor
- stderrHandle :: HandleExtractor
- ioHandles :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> (Handle, Handle)
- processHandle :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> ProcessHandle
- devNull :: FilePath
- processTranscript :: String -> [String] -> Maybe String -> IO (String, Bool)
- processTranscript' :: CreateProcess -> Maybe String -> IO (String, Bool)
- processTranscript'' :: CreateProcess -> Maybe String -> IO (String, ExitCode)
- class (Typeable e, Show e) => Exception e where
- toException :: e -> SomeException
- fromException :: SomeException -> Maybe e
- displayException :: e -> String
- data SomeException where
- SomeException :: forall e. Exception e => e -> SomeException
- bracketOnError :: MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
- finally :: MonadMask m => m a -> m b -> m a
- bracket_ :: MonadMask m => m a -> m c -> m b -> m b
- bracket :: MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b
- onError :: MonadMask m => m a -> m b -> m a
- onException :: MonadCatch m => m a -> m b -> m a
- catches :: (Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a
- tryJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a)
- try :: (MonadCatch m, Exception e) => m a -> m (Either e a)
- handleJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a
- handleIf :: (MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a
- handleAll :: MonadCatch m => (SomeException -> m a) -> m a -> m a
- handleIOError :: MonadCatch m => (IOError -> m a) -> m a -> m a
- handle :: (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a
- catchJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a
- catchIf :: (MonadCatch m, Exception e) => (e -> Bool) -> m a -> (e -> m a) -> m a
- catchIOError :: MonadCatch m => m a -> (IOError -> m a) -> m a
- catchAll :: MonadCatch m => m a -> (SomeException -> m a) -> m a
- uninterruptibleMask_ :: MonadMask m => m a -> m a
- mask_ :: MonadMask m => m a -> m a
- class Monad m => MonadThrow (m :: Type -> Type) where
- class MonadThrow m => MonadCatch (m :: Type -> Type) where
- class MonadCatch m => MonadMask (m :: Type -> Type) where
- mask :: ((forall a. m a -> m a) -> m b) -> m b
- uninterruptibleMask :: ((forall a. m a -> m a) -> m b) -> m b
- generalBracket :: m a -> (a -> ExitCase b -> m c) -> (a -> m b) -> m (b, c)
- data ExitCase a
- giveup :: [Char] -> a
- catchBoolIO :: MonadCatch m => m Bool -> m Bool
- catchMaybeIO :: MonadCatch m => m a -> m (Maybe a)
- catchDefaultIO :: MonadCatch m => a -> m a -> m a
- catchMsgIO :: MonadCatch m => m a -> m (Either String a)
- catchIO :: MonadCatch m => m a -> (IOException -> m a) -> m a
- tryIO :: MonadCatch m => m a -> m (Either IOException a)
- bracketIO :: (MonadMask m, MonadIO m) => IO v -> (v -> IO b) -> (v -> m a) -> m a
- catchNonAsync :: MonadCatch m => m a -> (SomeException -> m a) -> m a
- tryNonAsync :: MonadCatch m => m a -> m (Either SomeException a)
- tryWhenExists :: MonadCatch m => m a -> m (Maybe a)
- catchIOErrorType :: MonadCatch m => IOErrorType -> (IOException -> m a) -> m a -> m a
- data IOErrorType
- catchPermissionDenied :: MonadCatch m => (IOException -> m a) -> m a -> m a
- getEnv :: String -> IO (Maybe String)
- getEnvDefault :: String -> String -> IO String
- getEnvironment :: IO [(String, String)]
- addEntry :: Eq k => k -> v -> [(k, v)] -> [(k, v)]
- addEntries :: Eq k => [(k, v)] -> [(k, v)] -> [(k, v)]
- delEntry :: Eq k => k -> [(k, v)] -> [(k, v)]
- setEnv :: String -> String -> Bool -> IO ()
- unsetEnv :: String -> IO ()
- dirCruft :: FilePath -> Bool
- dirContents :: FilePath -> IO [FilePath]
- dirContentsRecursive :: FilePath -> IO [FilePath]
- dirContentsRecursiveSkipping :: (FilePath -> Bool) -> Bool -> FilePath -> IO [FilePath]
- dirTreeRecursiveSkipping :: (FilePath -> Bool) -> FilePath -> IO [FilePath]
- moveFile :: FilePath -> FilePath -> IO ()
- nukeFile :: FilePath -> IO ()
- getTemporaryDirectory :: IO FilePath
- getUserDocumentsDirectory :: IO FilePath
- getAppUserDataDirectory :: FilePath -> IO FilePath
- getXdgDirectoryList :: XdgDirectoryList -> IO [FilePath]
- getXdgDirectory :: XdgDirectory -> FilePath -> IO FilePath
- getHomeDirectory :: IO FilePath
- setModificationTime :: FilePath -> UTCTime -> IO ()
- setAccessTime :: FilePath -> UTCTime -> IO ()
- getModificationTime :: FilePath -> IO UTCTime
- getAccessTime :: FilePath -> IO UTCTime
- getSymbolicLinkTarget :: FilePath -> IO FilePath
- pathIsSymbolicLink :: FilePath -> IO Bool
- removeDirectoryLink :: FilePath -> IO ()
- createDirectoryLink :: FilePath -> FilePath -> IO ()
- createFileLink :: FilePath -> FilePath -> IO ()
- doesFileExist :: FilePath -> IO Bool
- doesDirectoryExist :: FilePath -> IO Bool
- doesPathExist :: FilePath -> IO Bool
- withCurrentDirectory :: FilePath -> IO a -> IO a
- setCurrentDirectory :: FilePath -> IO ()
- getCurrentDirectory :: IO FilePath
- listDirectory :: FilePath -> IO [FilePath]
- getDirectoryContents :: FilePath -> IO [FilePath]
- exeExtension :: String
- findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath]
- findFileWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO (Maybe FilePath)
- findFiles :: [FilePath] -> String -> IO [FilePath]
- findFile :: [FilePath] -> String -> IO (Maybe FilePath)
- findExecutablesInDirectories :: [FilePath] -> String -> IO [FilePath]
- findExecutables :: String -> IO [FilePath]
- findExecutable :: String -> IO (Maybe FilePath)
- makeRelativeToCurrentDirectory :: FilePath -> IO FilePath
- makeAbsolute :: FilePath -> IO FilePath
- canonicalizePath :: FilePath -> IO FilePath
- copyFileWithMetadata :: FilePath -> FilePath -> IO ()
- copyFile :: FilePath -> FilePath -> IO ()
- renamePath :: FilePath -> FilePath -> IO ()
- renameFile :: FilePath -> FilePath -> IO ()
- renameDirectory :: FilePath -> FilePath -> IO ()
- removeFile :: FilePath -> IO ()
- removePathForcibly :: FilePath -> IO ()
- removeDirectoryRecursive :: FilePath -> IO ()
- removeDirectory :: FilePath -> IO ()
- createDirectoryIfMissing :: Bool -> FilePath -> IO ()
- createDirectory :: FilePath -> IO ()
- copyPermissions :: FilePath -> FilePath -> IO ()
- setPermissions :: FilePath -> Permissions -> IO ()
- getPermissions :: FilePath -> IO Permissions
- setOwnerSearchable :: Bool -> Permissions -> Permissions
- setOwnerExecutable :: Bool -> Permissions -> Permissions
- setOwnerWritable :: Bool -> Permissions -> Permissions
- setOwnerReadable :: Bool -> Permissions -> Permissions
- emptyPermissions :: Permissions
- data Permissions
- data XdgDirectory
- data XdgDirectoryList
- isDirectoryEmpty :: FilePath -> IO Bool
- isUnpopulated :: FilePath -> IO Bool
- fsCruft :: FilePath -> Bool
- testDirectory :: FilePath -> (FilePath -> Bool) -> IO Bool
- type Template = String
- viaTmp :: (MonadMask m, MonadIO m) => (FilePath -> v -> m ()) -> FilePath -> v -> m ()
- withTmpFile :: (MonadIO m, MonadMask m) => Template -> (FilePath -> Handle -> m a) -> m a
- withTmpFileIn :: (MonadIO m, MonadMask m) => FilePath -> Template -> (FilePath -> Handle -> m a) -> m a
- relatedTemplate :: FilePath -> FilePath
- withTmpDir :: (MonadMask m, MonadIO m) => Template -> (FilePath -> m a) -> m a
- withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a
- removeTmpDir :: MonadIO m => FilePath -> m ()
- firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
- getM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b)
- anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool
- allM :: Monad m => (a -> m Bool) -> [a] -> m Bool
- untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool
- ifM :: Monad m => m Bool -> (m a, m a) -> m a
- (<||>) :: Monad m => m Bool -> m Bool -> m Bool
- (<&&>) :: Monad m => m Bool -> m Bool -> m Bool
- observe :: Monad m => (a -> m b) -> m a -> m a
- after :: Monad m => m b -> m a -> m a
- noop :: Monad m => m ()
- hGetContentsStrict :: Handle -> IO String
- readFileStrict :: FilePath -> IO String
- separate :: (a -> Bool) -> [a] -> ([a], [a])
- firstLine :: String -> String
- segment :: (a -> Bool) -> [a] -> [[a]]
- prop_segment_regressionTest :: Bool
- segmentDelim :: (a -> Bool) -> [a] -> [[a]]
- massReplace :: [(String, String)] -> String -> String
- hGetSomeString :: Handle -> Int -> IO String
- exitBool :: Bool -> IO a
- modifyFileMode :: FilePath -> (FileMode -> FileMode) -> IO ()
- modifyFileMode' :: FilePath -> (FileMode -> FileMode) -> IO FileMode
- withModifiedFileMode :: FilePath -> (FileMode -> FileMode) -> IO a -> IO a
- addModes :: [FileMode] -> FileMode -> FileMode
- removeModes :: [FileMode] -> FileMode -> FileMode
- writeModes :: [FileMode]
- readModes :: [FileMode]
- executeModes :: [FileMode]
- otherGroupModes :: [FileMode]
- preventWrite :: FilePath -> IO ()
- allowWrite :: FilePath -> IO ()
- allowRead :: FilePath -> IO ()
- groupSharedModes :: [FileMode]
- groupWriteRead :: FilePath -> IO ()
- checkMode :: FileMode -> FileMode -> Bool
- isSymLink :: FileMode -> Bool
- isExecutable :: FileMode -> Bool
- noUmask :: (MonadIO m, MonadMask m) => FileMode -> m a -> m a
- withUmask :: (MonadIO m, MonadMask m) => FileMode -> m a -> m a
- getUmask :: IO FileMode
- defaultFileMode :: IO FileMode
- combineModes :: [FileMode] -> FileMode
- isSticky :: FileMode -> Bool
- stickyMode :: FileMode
- setSticky :: FilePath -> IO ()
- writeFileProtected :: FilePath -> String -> IO ()
- writeFileProtected' :: FilePath -> (Handle -> IO ()) -> IO ()
- protectedOutput :: IO a -> IO a
- type FileMode = CMode
Documentation
runCommand :: String -> IO ProcessHandle #
Runs a command using the shell.
terminateProcess :: ProcessHandle -> IO () #
Attempts to terminate the specified process. This function should
not be used under normal circumstances - no guarantees are given regarding
how cleanly the process is terminated. To check whether the process
has indeed terminated, use getProcessExitCode
.
On Unix systems, terminateProcess
sends the process the SIGTERM signal.
On Windows systems, if use_process_jobs
is True
then the Win32 TerminateJobObject
function is called to kill all processes associated with the job and passing the
exit code of 1 to each of them. Otherwise if use_process_jobs
is False
then the
Win32 TerminateProcess
function is called, passing an exit code of 1.
Note: on Windows, if the process was a shell command created by
createProcess
with shell
, or created by runCommand
or
runInteractiveCommand
, then terminateProcess
will only
terminate the shell, not the command itself. On Unix systems, both
processes are in a process group and will be terminated together.
getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode) #
This is a non-blocking version of waitForProcess
. If the process is
still running, Nothing
is returned. If the process has exited, then
is returned where Just
ee
is the exit code of the process.
On Unix systems, see waitForProcess
for the meaning of exit codes
when the process died as the result of a signal.
getPid :: ProcessHandle -> IO (Maybe Pid) #
Returns the PID (process ID) of a subprocess.
Nothing
is returned if the handle was already closed. Otherwise a
PID is returned that remains valid as long as the handle is open.
The operating system may reuse the PID as soon as the last handle to
the process is closed.
Since: process-1.6.3.0
showCommandForUser :: FilePath -> [String] -> String #
Given a program p
and arguments args
,
showCommandForUser p args
returns a string suitable for pasting
into /bin/sh
(on Unix systems) or CMD.EXE
(on Windows).
readCreateProcessWithExitCode #
readCreateProcessWithExitCode
works exactly like readProcessWithExitCode
except that it
lets you pass CreateProcess
giving better flexibility.
Note that Handle
s provided for std_in
, std_out
, or std_err
via the CreateProcess
record will be ignored.
Since: process-1.2.3.0
:: CreateProcess | |
-> String | standard input |
-> IO String | stdout |
readCreateProcess
works exactly like readProcess
except that it
lets you pass CreateProcess
giving better flexibility.
> readCreateProcess (shell "pwd" { cwd = "/etc/" }) "" "/etc\n"
Note that Handle
s provided for std_in
or std_out
via the CreateProcess
record will be ignored.
Since: process-1.2.3.0
callCommand :: String -> IO () #
Creates a new process to run the specified shell command. If the command returns a non-zero exit code, an exception is raised.
If an asynchronous exception is thrown to the thread executing
callCommand
, the forked process will be terminated and
callCommand
will wait (block) until the process has been
terminated.
Since: process-1.2.0.0
callProcess :: FilePath -> [String] -> IO () #
Creates a new process to run the specified command with the given arguments, and wait for it to finish. If the command returns a non-zero exit code, an exception is raised.
If an asynchronous exception is thrown to the thread executing
callProcess
, the forked process will be terminated and
callProcess
will wait (block) until the process has been
terminated.
Since: process-1.2.0.0
spawnCommand :: String -> IO ProcessHandle #
Creates a new process to run the specified shell command.
It does not wait for the program to finish, but returns the ProcessHandle
.
Since: process-1.2.0.0
spawnProcess :: FilePath -> [String] -> IO ProcessHandle #
Creates a new process to run the specified raw command with the given
arguments. It does not wait for the program to finish, but returns the
ProcessHandle
.
Since: process-1.2.0.0
cleanupProcess :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> IO () #
Cleans up the process.
This function is meant to be invoked from any application level cleanup
handler. It terminates the process, and closes any CreatePipe
handle
s.
Since: process-1.6.4.0
withCreateProcess :: CreateProcess -> (Maybe Handle -> Maybe Handle -> Maybe Handle -> ProcessHandle -> IO a) -> IO a #
A bracket
-style resource handler for createProcess
.
Does automatic cleanup when the action finishes. If there is an exception
in the body then it ensures that the process gets terminated and any
CreatePipe
Handle
s are closed. In particular this means that if the
Haskell thread is killed (e.g. killThread
), that the external process is
also terminated.
e.g.
withCreateProcess (proc cmd args) { ... } $ \stdin stdout stderr ph -> do ...
Since: process-1.4.3.0
shell :: String -> CreateProcess #
Construct a CreateProcess
record for passing to createProcess
,
representing a command to be passed to the shell.
proc :: FilePath -> [String] -> CreateProcess #
Construct a CreateProcess
record for passing to createProcess
,
representing a raw command with arguments.
See RawCommand
for precise semantics of the specified FilePath
.
The platform specific type for a process identifier.
This is always an integral type. Width and signedness are platform specific.
Since: process-1.6.3.0
:: ProcessHandle | A process in the process group |
-> IO () |
Sends an interrupt signal to the process group of the given process.
On Unix systems, it sends the group the SIGINT signal.
On Windows systems, it generates a CTRL_BREAK_EVENT and will only work for
processes created using createProcess
and setting the create_group
flag
createPipeFd :: IO (FD, FD) #
Create a pipe for interprocess communication and return a
(readEnd, writeEnd)
FD
pair.
Since: process-1.4.2.0
createPipe :: IO (Handle, Handle) #
Create a pipe for interprocess communication and return a
(readEnd, writeEnd)
Handle
pair.
Since: process-1.2.1.0
:: String | function name (for error messages) |
-> CreateProcess | |
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) |
This function is almost identical to
createProcess
. The only differences are:
Handle
s provided viaUseHandle
are not closed automatically.- This function takes an extra
String
argument to be used in creating error messages. use_process_jobs
can be set in CreateProcess since 1.5.0.0 in order to create an I/O completion port to monitor a process tree's progress on Windows.
The function also returns two new handles: * an I/O Completion Port handle on which events will be signaled. * a Job handle which can be used to kill all running processes.
On POSIX platforms these two new handles will always be Nothing
This function has been available from the System.Process.Internals module for some time, and is part of the System.Process module since version 1.2.1.0.
Since: process-1.2.1.0
ShellCommand String | A command line to execute using the shell |
RawCommand FilePath [String] | The name of an executable with a list of arguments The
|
Instances
Eq CmdSpec | |
Show CmdSpec | |
IsString CmdSpec | construct a Since: process-1.2.1.0 |
Defined in System.Process.Common fromString :: String -> CmdSpec # |
Inherit | Inherit Handle from parent |
UseHandle Handle | Use the supplied Handle |
CreatePipe | Create a new pipe. The returned
|
NoStream | No stream handle will be passed |
data ProcessHandle #
data CreateProcess #
CreateProcess | |
|
Instances
Eq CreateProcess | |
Defined in System.Process.Common (==) :: CreateProcess -> CreateProcess -> Bool # (/=) :: CreateProcess -> CreateProcess -> Bool # | |
Show CreateProcess | |
Defined in System.Process.Common showsPrec :: Int -> CreateProcess -> ShowS # show :: CreateProcess -> String # showList :: [CreateProcess] -> ShowS # |
readProcess :: FilePath -> [String] -> IO String Source #
Normally, when reading from a process, it does not need to be fed any standard input.
readProcess' :: CreateProcess -> IO String Source #
writeReadProcessEnv :: FilePath -> [String] -> Maybe [(String, String)] -> Maybe (Handle -> IO ()) -> Maybe (Handle -> IO ()) -> IO String Source #
Runs an action to write to a process on its stdin, returns its output, and also allows specifying the environment.
forceSuccessProcess :: CreateProcess -> ProcessHandle -> IO () Source #
Waits for a ProcessHandle, and throws an IOError if the process did not exit successfully.
forceSuccessProcess' :: CreateProcess -> ExitCode -> IO () Source #
checkSuccessProcess :: ProcessHandle -> IO Bool Source #
Waits for a ProcessHandle and returns True if it exited successfully. Note that using this with createProcessChecked will throw away the Bool, and is only useful to ignore the exit code of a process, while still waiting for it. -}
createProcessSuccess :: CreateProcessRunner Source #
Runs createProcess, then an action on its handles, and then forceSuccessProcess.
createProcessChecked :: (ProcessHandle -> IO b) -> CreateProcessRunner Source #
Runs createProcess, then an action on its handles, and then a checker action on its exit code, which must wait for the process.
createBackgroundProcess :: CreateProcessRunner Source #
Leaves the process running, suitable for lazy streaming. Note: Zombies will result, and must be waited on.
withHandle :: StdHandle -> CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a Source #
Runs a CreateProcessRunner, on a CreateProcess structure, that is adjusted to pipe only from/to a single StdHandle, and passes the resulting Handle to an action.
withIOHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a Source #
Like withHandle, but passes (stdin, stdout) handles to the action.
withOEHandles :: CreateProcessRunner -> CreateProcess -> ((Handle, Handle) -> IO a) -> IO a Source #
Like withHandle, but passes (stdout, stderr) handles to the action.
withQuietOutput :: CreateProcessRunner -> CreateProcess -> IO () Source #
Forces the CreateProcessRunner to run quietly; both stdout and stderr are discarded.
feedWithQuietOutput :: CreateProcessRunner -> CreateProcess -> (Handle -> IO a) -> IO a Source #
Stdout and stderr are discarded, while the process is fed stdin from the handle.
createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) Source #
Wrapper around createProcess
that does debug logging.
waitForProcess :: ProcessHandle -> IO ExitCode Source #
Wrapper around waitForProcess
that does debug logging.
startInteractiveProcess :: FilePath -> [String] -> Maybe [(String, String)] -> IO (ProcessHandle, Handle, Handle) Source #
Starts an interactive process. Unlike runInteractiveProcess in System.Process, stderr is inherited.
stdinHandle :: HandleExtractor Source #
stdoutHandle :: HandleExtractor Source #
stderrHandle :: HandleExtractor Source #
processHandle :: (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) -> ProcessHandle Source #
processTranscript :: String -> [String] -> Maybe String -> IO (String, Bool) Source #
Runs a process and returns a transcript combining its stdout and stderr, and whether it succeeded or failed.
processTranscript' :: CreateProcess -> Maybe String -> IO (String, Bool) Source #
Also feeds the process some input.
processTranscript'' :: CreateProcess -> Maybe String -> IO (String, ExitCode) Source #
class (Typeable e, Show e) => Exception e where #
Any type that you wish to throw or catch as an exception must be an
instance of the Exception
class. The simplest case is a new exception
type directly below the root:
data MyException = ThisException | ThatException deriving Show instance Exception MyException
The default method definitions in the Exception
class do what we need
in this case. You can now throw and catch ThisException
and
ThatException
as exceptions:
*Main> throw ThisException `catch` \e -> putStrLn ("Caught " ++ show (e :: MyException)) Caught ThisException
In more complicated examples, you may wish to define a whole hierarchy of exceptions:
--------------------------------------------------------------------- -- Make the root exception type for all the exceptions in a compiler data SomeCompilerException = forall e . Exception e => SomeCompilerException e instance Show SomeCompilerException where show (SomeCompilerException e) = show e instance Exception SomeCompilerException compilerExceptionToException :: Exception e => e -> SomeException compilerExceptionToException = toException . SomeCompilerException compilerExceptionFromException :: Exception e => SomeException -> Maybe e compilerExceptionFromException x = do SomeCompilerException a <- fromException x cast a --------------------------------------------------------------------- -- Make a subhierarchy for exceptions in the frontend of the compiler data SomeFrontendException = forall e . Exception e => SomeFrontendException e instance Show SomeFrontendException where show (SomeFrontendException e) = show e instance Exception SomeFrontendException where toException = compilerExceptionToException fromException = compilerExceptionFromException frontendExceptionToException :: Exception e => e -> SomeException frontendExceptionToException = toException . SomeFrontendException frontendExceptionFromException :: Exception e => SomeException -> Maybe e frontendExceptionFromException x = do SomeFrontendException a <- fromException x cast a --------------------------------------------------------------------- -- Make an exception type for a particular frontend compiler exception data MismatchedParentheses = MismatchedParentheses deriving Show instance Exception MismatchedParentheses where toException = frontendExceptionToException fromException = frontendExceptionFromException
We can now catch a MismatchedParentheses
exception as
MismatchedParentheses
, SomeFrontendException
or
SomeCompilerException
, but not other types, e.g. IOException
:
*Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: MismatchedParentheses)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeFrontendException)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: SomeCompilerException)) Caught MismatchedParentheses *Main> throw MismatchedParentheses `catch` \e -> putStrLn ("Caught " ++ show (e :: IOException)) *** Exception: MismatchedParentheses
Nothing
toException :: e -> SomeException #
fromException :: SomeException -> Maybe e #
displayException :: e -> String #
Render this exception value in a human-friendly manner.
Default implementation:
.show
Since: base-4.8.0.0
Instances
data SomeException where #
The SomeException
type is the root of the exception type hierarchy.
When an exception of type e
is thrown, behind the scenes it is
encapsulated in a SomeException
.
SomeException :: forall e. Exception e => e -> SomeException |
Instances
Show SomeException | Since: base-3.0 |
Defined in GHC.Exception.Type showsPrec :: Int -> SomeException -> ShowS # show :: SomeException -> String # showList :: [SomeException] -> ShowS # | |
Exception SomeException | Since: base-3.0 |
Defined in GHC.Exception.Type |
bracketOnError :: MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b #
Like bracket
, but only performs the final action if an error is
thrown by the in-between computation.
finally :: MonadMask m => m a -> m b -> m a #
Perform an action with a finalizer action that is run, even if an error occurs.
bracket_ :: MonadMask m => m a -> m c -> m b -> m b #
Version of bracket
without any value being passed to the second and
third actions.
bracket :: MonadMask m => m a -> (a -> m c) -> (a -> m b) -> m b #
Generalized abstracted pattern of safe resource acquisition and release
in the face of errors. The first action "acquires" some value, which
is "released" by the second action at the end. The third action "uses"
the value and its result is the result of the bracket
.
If an error is thrown during the use, the release still happens before the error is rethrown.
Note that this is essentially a type-specialized version of
generalBracket
. This function has a more common signature (matching the
signature from Control.Exception), and is often more convenient to use. By
contrast, generalBracket
is more expressive, allowing us to implement
other functions like bracketOnError
.
onError :: MonadMask m => m a -> m b -> m a #
Run an action only if an error is thrown in the main action. Unlike
onException
, this works with every kind of error, not just exceptions. For
example, if f
is an ExceptT
computation which aborts with a Left
, the
computation onError f g
will execute g
, while onException f g
will not.
This distinction is only meaningful for monads which have multiple exit
points, such as Except
and MaybeT
. For monads that only have a single
exit point, there is no difference between onException
and onError
,
except that onError
has a more constrained type.
Since: exceptions-0.10.0
onException :: MonadCatch m => m a -> m b -> m a #
Run an action only if an exception is thrown in the main action. The exception is not caught, simply rethrown.
NOTE The action is only run if an exception is thrown. If the monad
supports other ways of aborting the computation, the action won't run if
those other kinds of errors are thrown. See onError
.
catches :: (Foldable f, MonadCatch m) => m a -> f (Handler m a) -> m a #
Catches different sorts of exceptions. See Control.Exception's catches
tryJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> m (Either b a) #
A variant of try
that takes an exception predicate to select
which exceptions are caught. See Control.Exception's tryJust
try :: (MonadCatch m, Exception e) => m a -> m (Either e a) #
Similar to catch
, but returns an Either
result. See Control.Exception's
try
.
handleJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> (b -> m a) -> m a -> m a #
Flipped catchJust
. See Control.Exception's handleJust
.
handleAll :: MonadCatch m => (SomeException -> m a) -> m a -> m a #
Flipped catchAll
handleIOError :: MonadCatch m => (IOError -> m a) -> m a -> m a #
Flipped catchIOError
handle :: (MonadCatch m, Exception e) => (e -> m a) -> m a -> m a #
Flipped catch
. See Control.Exception's handle
.
catchJust :: (MonadCatch m, Exception e) => (e -> Maybe b) -> m a -> (b -> m a) -> m a #
A more generalized way of determining which exceptions to catch at run time.
catchIf :: (MonadCatch m, Exception e) => (e -> Bool) -> m a -> (e -> m a) -> m a #
Catch exceptions only if they pass some predicate. Often useful with the
predicates for testing IOError
values in System.IO.Error.
catchIOError :: MonadCatch m => m a -> (IOError -> m a) -> m a #
Catch all IOError
(eqv. IOException
) exceptions. Still somewhat too
general, but better than using catchAll
. See catchIf
for an easy way
of catching specific IOError
s based on the predicates in System.IO.Error.
catchAll :: MonadCatch m => m a -> (SomeException -> m a) -> m a #
Catches all exceptions, and somewhat defeats the purpose of the extensible exception system. Use sparingly.
NOTE This catches all exceptions, but if the monad supports other ways of aborting the computation, those other kinds of errors will not be caught.
uninterruptibleMask_ :: MonadMask m => m a -> m a #
Like uninterruptibleMask
, but does not pass a restore
action to the
argument.
class Monad m => MonadThrow (m :: Type -> Type) where #
A class for monads in which exceptions may be thrown.
Instances should obey the following law:
throwM e >> x = throwM e
In other words, throwing an exception short-circuits the rest of the monadic computation.
throwM :: Exception e => e -> m a #
Throw an exception. Note that this throws when this action is run in
the monad m
, not when it is applied. It is a generalization of
Control.Exception's throwIO
.
Should satisfy the law:
throwM e >> f = throwM e
Instances
class MonadThrow m => MonadCatch (m :: Type -> Type) where #
A class for monads which allow exceptions to be caught, in particular
exceptions which were thrown by throwM
.
Instances should obey the following law:
catch (throwM e) f = f e
Note that the ability to catch an exception does not guarantee that we can
deal with all possible exit points from a computation. Some monads, such as
continuation-based stacks, allow for more than just a success/failure
strategy, and therefore catch
cannot be used by those monads to properly
implement a function such as finally
. For more information, see
MonadMask
.
catch :: Exception e => m a -> (e -> m a) -> m a #
Provide a handler for exceptions thrown during execution of the first
action. Note that type of the type of the argument to the handler will
constrain which exceptions are caught. See Control.Exception's
catch
.
Instances
MonadCatch IO | |
MonadCatch STM | |
MonadCatch Propellor Source # | |
e ~ SomeException => MonadCatch (Either e) | Since: exceptions-0.8.3 |
MonadCatch m => MonadCatch (MaybeT m) | Catches exceptions from the base monad. |
MonadCatch m => MonadCatch (ListT m) | |
MonadCatch m => MonadCatch (ExceptT e m) | Catches exceptions from the base monad. |
MonadCatch m => MonadCatch (IdentityT m) | |
(Error e, MonadCatch m) => MonadCatch (ErrorT e m) | Catches exceptions from the base monad. |
MonadCatch m => MonadCatch (StateT s m) | |
MonadCatch m => MonadCatch (StateT s m) | |
(MonadCatch m, Monoid w) => MonadCatch (WriterT w m) | |
(MonadCatch m, Monoid w) => MonadCatch (WriterT w m) | |
MonadCatch m => MonadCatch (ReaderT r m) | |
(MonadCatch m, Monoid w) => MonadCatch (RWST r w s m) | |
(MonadCatch m, Monoid w) => MonadCatch (RWST r w s m) | |
class MonadCatch m => MonadMask (m :: Type -> Type) where #
A class for monads which provide for the ability to account for all possible exit points from a computation, and to mask asynchronous exceptions. Continuation-based monads are invalid instances of this class.
Instances should ensure that, in the following code:
fg = f `finally` g
The action g
is called regardless of what occurs within f
, including
async exceptions. Some monads allow f
to abort the computation via other
effects than throwing an exception. For simplicity, we will consider aborting
and throwing an exception to be two forms of "throwing an error".
If f
and g
both throw an error, the error thrown by fg
depends on which
errors we're talking about. In a monad transformer stack, the deeper layers
override the effects of the inner layers; for example, ExceptT e1 (Except
e2) a
represents a value of type Either e2 (Either e1 a)
, so throwing both
an e1
and an e2
will result in Left e2
. If f
and g
both throw an
error from the same layer, instances should ensure that the error from g
wins.
Effects other than throwing an error are also overriden by the deeper layers.
For example, StateT s Maybe a
represents a value of type s -> Maybe (a,
s)
, so if an error thrown from f
causes this function to return Nothing
,
any changes to the state which f
also performed will be erased. As a
result, g
will see the state as it was before f
. Once g
completes,
f
's error will be rethrown, so g
' state changes will be erased as well.
This is the normal interaction between effects in a monad transformer stack.
By contrast, lifted-base's
version of finally
always discards all of g
's non-IO effects, and g
never sees any of f
's non-IO effects, regardless of the layer ordering and
regardless of whether f
throws an error. This is not the result of
interacting effects, but a consequence of MonadBaseControl
's approach.
mask :: ((forall a. m a -> m a) -> m b) -> m b #
Runs an action with asynchronous exceptions disabled. The action is
provided a method for restoring the async. environment to what it was
at the mask
call. See Control.Exception's mask
.
uninterruptibleMask :: ((forall a. m a -> m a) -> m b) -> m b #
Like mask
, but the masked computation is not interruptible (see
Control.Exception's uninterruptibleMask
. WARNING:
Only use if you need to mask exceptions around an interruptible operation
AND you can guarantee the interruptible operation will only block for a
short period of time. Otherwise you render the program/thread unresponsive
and/or unkillable.
:: m a | acquire some resource |
-> (a -> ExitCase b -> m c) | release the resource, observing the outcome of the inner action |
-> (a -> m b) | inner action to perform with the resource |
-> m (b, c) |
A generalized version of bracket
which uses ExitCase
to distinguish
the different exit cases, and returns the values of both the use
and
release
actions. In practice, this extra information is rarely needed,
so it is often more convenient to use one of the simpler functions which
are defined in terms of this one, such as bracket
, finally
, onError
,
and bracketOnError
.
This function exists because in order to thread their effects through the
execution of bracket
, monad transformers need values to be threaded from
use
to release
and from release
to the output value.
NOTE This method was added in version 0.9.0 of this
library. Previously, implementation of functions like bracket
and finally
in this module were based on the mask
and
uninterruptibleMask
functions only, disallowing some classes of
tranformers from having MonadMask
instances (notably
multi-exit-point transformers like ExceptT
). If you are a
library author, you'll now need to provide an implementation for
this method. The StateT
implementation demonstrates most of the
subtleties:
generalBracket acquire release use = StateT $ s0 -> do ((b, _s2), (c, s3)) <- generalBracket (runStateT acquire s0) ((resource, s1) exitCase -> case exitCase of ExitCaseSuccess (b, s2) -> runStateT (release resource (ExitCaseSuccess b)) s2 -- In the two other cases, the base monad overridesuse
's state -- changes and the state reverts tos1
. ExitCaseException e -> runStateT (release resource (ExitCaseException e)) s1 ExitCaseAbort -> runStateT (release resource ExitCaseAbort) s1 ) ((resource, s1) -> runStateT (use resource) s1) return ((b, c), s3)
The StateT s m
implementation of generalBracket
delegates to the m
implementation of generalBracket
. The acquire
, use
, and release
arguments given to StateT
's implementation produce actions of type
StateT s m a
, StateT s m b
, and StateT s m c
. In order to run those
actions in the base monad, we need to call runStateT
, from which we
obtain actions of type m (a, s)
, m (b, s)
, and m (c, s)
. Since each
action produces the next state, it is important to feed the state produced
by the previous action to the next action.
In the ExitCaseSuccess
case, the state starts at s0
, flows through
acquire
to become s1
, flows through use
to become s2
, and finally
flows through release
to become s3
. In the other two cases, release
does not receive the value s2
, so its action cannot see the state changes
performed by use
. This is fine, because in those two cases, an error was
thrown in the base monad, so as per the usual interaction between effects
in a monad transformer stack, those state changes get reverted. So we start
from s1
instead.
Finally, the m
implementation of generalBracket
returns the pairs
(b, s)
and (c, s)
. For monad transformers other than StateT
, this
will be some other type representing the effects and values performed and
returned by the use
and release
actions. The effect part of the use
result, in this case _s2
, usually needs to be discarded, since those
effects have already been incorporated in the release
action.
The only effect which is intentionally not incorporated in the release
action is the effect of throwing an error. In that case, the error must be
re-thrown. One subtlety which is easy to miss is that in the case in which
use
and release
both throw an error, the error from release
should
take priority. Here is an implementation for ExceptT
which demonstrates
how to do this.
generalBracket acquire release use = ExceptT $ do (eb, ec) <- generalBracket (runExceptT acquire) (eresource exitCase -> case eresource of Left e -> return (Left e) -- nothing to release, acquire didn't succeed Right resource -> case exitCase of ExitCaseSuccess (Right b) -> runExceptT (release resource (ExitCaseSuccess b)) ExitCaseException e -> runExceptT (release resource (ExitCaseException e)) _ -> runExceptT (release resource ExitCaseAbort)) (either (return . Left) (runExceptT . use)) return $ do -- The order in which we perform those twoEither
effects determines -- which error will win if they are bothLeft
s. We want the error from --release
to win. c <- ec b <- eb return (b, c)
Since: exceptions-0.9.0
Instances
MonadMask IO | |
MonadMask Propellor Source # | |
Defined in Propellor.Types.Core | |
e ~ SomeException => MonadMask (Either e) | Since: exceptions-0.8.3 |
Defined in Control.Monad.Catch | |
MonadMask m => MonadMask (MaybeT m) | Since: exceptions-0.10.0 |
Defined in Control.Monad.Catch | |
MonadMask m => MonadMask (ExceptT e m) | Since: exceptions-0.9.0 |
Defined in Control.Monad.Catch mask :: ((forall a. ExceptT e m a -> ExceptT e m a) -> ExceptT e m b) -> ExceptT e m b # uninterruptibleMask :: ((forall a. ExceptT e m a -> ExceptT e m a) -> ExceptT e m b) -> ExceptT e m b # generalBracket :: ExceptT e m a -> (a -> ExitCase b -> ExceptT e m c) -> (a -> ExceptT e m b) -> ExceptT e m (b, c) # | |
MonadMask m => MonadMask (IdentityT m) | |
Defined in Control.Monad.Catch mask :: ((forall a. IdentityT m a -> IdentityT m a) -> IdentityT m b) -> IdentityT m b # uninterruptibleMask :: ((forall a. IdentityT m a -> IdentityT m a) -> IdentityT m b) -> IdentityT m b # generalBracket :: IdentityT m a -> (a -> ExitCase b -> IdentityT m c) -> (a -> IdentityT m b) -> IdentityT m (b, c) # | |
(Error e, MonadMask m) => MonadMask (ErrorT e m) | |
Defined in Control.Monad.Catch | |
MonadMask m => MonadMask (StateT s m) | |
Defined in Control.Monad.Catch | |
MonadMask m => MonadMask (StateT s m) | |
Defined in Control.Monad.Catch | |
(MonadMask m, Monoid w) => MonadMask (WriterT w m) | |
Defined in Control.Monad.Catch mask :: ((forall a. WriterT w m a -> WriterT w m a) -> WriterT w m b) -> WriterT w m b # uninterruptibleMask :: ((forall a. WriterT w m a -> WriterT w m a) -> WriterT w m b) -> WriterT w m b # generalBracket :: WriterT w m a -> (a -> ExitCase b -> WriterT w m c) -> (a -> WriterT w m b) -> WriterT w m (b, c) # | |
(MonadMask m, Monoid w) => MonadMask (WriterT w m) | |
Defined in Control.Monad.Catch mask :: ((forall a. WriterT w m a -> WriterT w m a) -> WriterT w m b) -> WriterT w m b # uninterruptibleMask :: ((forall a. WriterT w m a -> WriterT w m a) -> WriterT w m b) -> WriterT w m b # generalBracket :: WriterT w m a -> (a -> ExitCase b -> WriterT w m c) -> (a -> WriterT w m b) -> WriterT w m (b, c) # | |
MonadMask m => MonadMask (ReaderT r m) | |
Defined in Control.Monad.Catch mask :: ((forall a. ReaderT r m a -> ReaderT r m a) -> ReaderT r m b) -> ReaderT r m b # uninterruptibleMask :: ((forall a. ReaderT r m a -> ReaderT r m a) -> ReaderT r m b) -> ReaderT r m b # generalBracket :: ReaderT r m a -> (a -> ExitCase b -> ReaderT r m c) -> (a -> ReaderT r m b) -> ReaderT r m (b, c) # | |
(MonadMask m, Monoid w) => MonadMask (RWST r w s m) | |
Defined in Control.Monad.Catch mask :: ((forall a. RWST r w s m a -> RWST r w s m a) -> RWST r w s m b) -> RWST r w s m b # uninterruptibleMask :: ((forall a. RWST r w s m a -> RWST r w s m a) -> RWST r w s m b) -> RWST r w s m b # generalBracket :: RWST r w s m a -> (a -> ExitCase b -> RWST r w s m c) -> (a -> RWST r w s m b) -> RWST r w s m (b, c) # | |
(MonadMask m, Monoid w) => MonadMask (RWST r w s m) | |
Defined in Control.Monad.Catch mask :: ((forall a. RWST r w s m a -> RWST r w s m a) -> RWST r w s m b) -> RWST r w s m b # uninterruptibleMask :: ((forall a. RWST r w s m a -> RWST r w s m a) -> RWST r w s m b) -> RWST r w s m b # generalBracket :: RWST r w s m a -> (a -> ExitCase b -> RWST r w s m c) -> (a -> RWST r w s m b) -> RWST r w s m (b, c) # |
A MonadMask
computation may either succeed with a value, abort with an
exception, or abort for some other reason. For example, in ExceptT e IO
you can use throwM
to abort with an exception (ExitCaseException
) or
throwE
to abort with a value of type e
(ExitCaseAbort
).
catchBoolIO :: MonadCatch m => m Bool -> m Bool Source #
catchMaybeIO :: MonadCatch m => m a -> m (Maybe a) Source #
catchDefaultIO :: MonadCatch m => a -> m a -> m a Source #
catchMsgIO :: MonadCatch m => m a -> m (Either String a) Source #
catchIO :: MonadCatch m => m a -> (IOException -> m a) -> m a Source #
tryIO :: MonadCatch m => m a -> m (Either IOException a) Source #
catchNonAsync :: MonadCatch m => m a -> (SomeException -> m a) -> m a Source #
tryNonAsync :: MonadCatch m => m a -> m (Either SomeException a) Source #
tryWhenExists :: MonadCatch m => m a -> m (Maybe a) Source #
catchIOErrorType :: MonadCatch m => IOErrorType -> (IOException -> m a) -> m a -> m a Source #
data IOErrorType #
An abstract type that contains a value for each variant of IOException
.
Instances
Eq IOErrorType | Since: base-4.1.0.0 |
Defined in GHC.IO.Exception (==) :: IOErrorType -> IOErrorType -> Bool # (/=) :: IOErrorType -> IOErrorType -> Bool # | |
Show IOErrorType | Since: base-4.1.0.0 |
Defined in GHC.IO.Exception showsPrec :: Int -> IOErrorType -> ShowS # show :: IOErrorType -> String # showList :: [IOErrorType] -> ShowS # |
catchPermissionDenied :: MonadCatch m => (IOException -> m a) -> m a -> m a Source #
addEntries :: Eq k => [(k, v)] -> [(k, v)] -> [(k, v)] Source #
getTemporaryDirectory :: IO FilePath #
Returns the current directory for temporary files.
On Unix, getTemporaryDirectory
returns the value of the TMPDIR
environment variable or "/tmp" if the variable isn't defined.
On Windows, the function checks for the existence of environment variables in
the following order and uses the first path found:
- TMP environment variable.
- TEMP environment variable.
- USERPROFILE environment variable.
- The Windows directory
The operation may fail with:
UnsupportedOperation
The operating system has no notion of temporary directory.
The function doesn't verify whether the path exists.
getUserDocumentsDirectory :: IO FilePath #
Returns the current user's document directory.
The directory returned is expected to be writable by the current user,
but note that it isn't generally considered good practice to store
application-specific data here; use getXdgDirectory
or
getAppUserDataDirectory
instead.
On Unix, getUserDocumentsDirectory
returns the value of the HOME
environment variable. On Windows, the system is queried for a
suitable path; a typical path might be C:/Users/<user>/Documents
.
The operation may fail with:
UnsupportedOperation
The operating system has no notion of document directory.isDoesNotExistError
The document directory for the current user does not exist, or cannot be found.
Obtain the path to a special directory for storing user-specific
application data (traditional Unix location). Newer applications may
prefer the the XDG-conformant location provided by getXdgDirectory
(migration guide).
The argument is usually the name of the application. Since it will be integrated into the path, it must consist of valid path characters.
- On Unix-like systems, the path is
~/.<app>
. - On Windows, the path is
%APPDATA%/<app>
(e.g.C:/Users/<user>/AppData/Roaming/<app>
)
Note: the directory may not actually exist, in which case you would need to create it. It is expected that the parent directory exists and is writable.
The operation may fail with:
UnsupportedOperation
The operating system has no notion of application-specific data directory.isDoesNotExistError
The home directory for the current user does not exist, or cannot be found.
:: XdgDirectoryList | which special directory list |
-> IO [FilePath] |
:: XdgDirectory | which special directory |
-> FilePath | a relative path that is appended to the path; if empty, the base path is returned |
-> IO FilePath |
Obtain the paths to special directories for storing user-specific
application data, configuration, and cache files, conforming to the
XDG Base Directory Specification.
Compared with getAppUserDataDirectory
, this function provides a more
fine-grained hierarchy as well as greater flexibility for the user.
It also works on Windows, although in that case XdgData
and XdgConfig
will map to the same directory.
The second argument is usually the name of the application. Since it will be integrated into the path, it must consist of valid path characters.
Note: The directory may not actually exist, in which case you would need
to create it with file mode 700
(i.e. only accessible by the owner).
Since: directory-1.2.3.0
getHomeDirectory :: IO FilePath #
Returns the current user's home directory.
The directory returned is expected to be writable by the current user,
but note that it isn't generally considered good practice to store
application-specific data here; use getXdgDirectory
or
getAppUserDataDirectory
instead.
On Unix, getHomeDirectory
returns the value of the HOME
environment variable. On Windows, the system is queried for a
suitable path; a typical path might be C:/Users/<user>
.
The operation may fail with:
UnsupportedOperation
The operating system has no notion of home directory.isDoesNotExistError
The home directory for the current user does not exist, or cannot be found.
setModificationTime :: FilePath -> UTCTime -> IO () #
Change the time at which the file or directory was last modified.
The operation may fail with:
isPermissionError
if the user is not permitted to alter the modification time; orisDoesNotExistError
if the file or directory does not exist.
Some caveats for POSIX systems:
- Not all systems support
utimensat
, in which case the function can only emulate the behavior by reading the access time and then setting both the access and modification times together. On systems whereutimensat
is supported, the modification time is set atomically with nanosecond precision. - If compiled against a version of
unix
prior to2.7.0.0
, the function would not be able to set timestamps with sub-second resolution. In this case, there would also be loss of precision in the access time.
Since: directory-1.2.3.0
setAccessTime :: FilePath -> UTCTime -> IO () #
Change the time at which the file or directory was last accessed.
The operation may fail with:
isPermissionError
if the user is not permitted to alter the access time; orisDoesNotExistError
if the file or directory does not exist.
Some caveats for POSIX systems:
- Not all systems support
utimensat
, in which case the function can only emulate the behavior by reading the modification time and then setting both the access and modification times together. On systems whereutimensat
is supported, the access time is set atomically with nanosecond precision. - If compiled against a version of
unix
prior to2.7.0.0
, the function would not be able to set timestamps with sub-second resolution. In this case, there would also be loss of precision in the modification time.
Since: directory-1.2.3.0
getModificationTime :: FilePath -> IO UTCTime #
Obtain the time at which the file or directory was last modified.
The operation may fail with:
isPermissionError
if the user is not permitted to read the modification time; orisDoesNotExistError
if the file or directory does not exist.
Caveat for POSIX systems: This function returns a timestamp with sub-second
resolution only if this package is compiled against unix-2.6.0.0
or later
and the underlying filesystem supports them.
getAccessTime :: FilePath -> IO UTCTime #
Obtain the time at which the file or directory was last accessed.
The operation may fail with:
isPermissionError
if the user is not permitted to read the access time; orisDoesNotExistError
if the file or directory does not exist.
Caveat for POSIX systems: This function returns a timestamp with sub-second
resolution only if this package is compiled against unix-2.6.0.0
or later
and the underlying filesystem supports them.
Since: directory-1.2.3.0
getSymbolicLinkTarget :: FilePath -> IO FilePath #
Retrieve the target path of either a file or directory symbolic link. The returned path may not be absolute, may not exist, and may not even be a valid path.
On Windows systems, this calls DeviceIoControl
with
FSCTL_GET_REPARSE_POINT
. In addition to symbolic links, the function
also works on junction points. On POSIX systems, this calls readlink
.
Windows-specific errors: This operation may fail with
illegalOperationErrorType
if the file system does not support symbolic
links.
Since: directory-1.3.1.0
pathIsSymbolicLink :: FilePath -> IO Bool #
Check whether the path refers to a symbolic link. An exception is thrown if the path does not exist or is inaccessible.
On Windows, this checks for FILE_ATTRIBUTE_REPARSE_POINT
. In addition to
symbolic links, the function also returns true on junction points. On
POSIX systems, this checks for S_IFLNK
.
Since: directory-1.3.0.0
removeDirectoryLink :: FilePath -> IO () #
Remove an existing directory symbolic link.
On Windows, this is an alias for removeDirectory
. On POSIX systems, this
is an alias for removeFile
.
See also: removeFile
, which can remove an existing file symbolic link.
Since: directory-1.3.1.0
Create a directory symbolic link. The target path can be either absolute or relative and need not refer to an existing directory. The order of arguments follows the POSIX convention.
To remove an existing directory symbolic link, use removeDirectoryLink
.
Although the distinction between file symbolic links and directory symbolic links does not exist on POSIX systems, on Windows this is an intrinsic property of every symbolic link and cannot be changed without recreating the link. A file symbolic link that actually points to a directory will fail to dereference and vice versa. Moreover, creating symbolic links on Windows may require privileges unavailable to users outside the Administrators group. Portable programs that use symbolic links should take both into consideration.
On Windows, the function is implemented using CreateSymbolicLink
with
SYMBOLIC_LINK_FLAG_DIRECTORY
. Since 1.3.3.0, the
SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
flag is also included if
supported by the operating system. On POSIX, this is an alias for
createFileLink
and is therefore atomic.
Windows-specific errors: This operation may fail with permissionErrorType
if the user lacks the privileges to create symbolic links. It may also
fail with illegalOperationErrorType
if the file system does not support
symbolic links.
Since: directory-1.3.1.0
Create a file symbolic link. The target path can be either absolute or relative and need not refer to an existing file. The order of arguments follows the POSIX convention.
To remove an existing file symbolic link, use removeFile
.
Although the distinction between file symbolic links and directory symbolic links does not exist on POSIX systems, on Windows this is an intrinsic property of every symbolic link and cannot be changed without recreating the link. A file symbolic link that actually points to a directory will fail to dereference and vice versa. Moreover, creating symbolic links on Windows may require privileges unavailable to users outside the Administrators group. Portable programs that use symbolic links should take both into consideration.
On Windows, the function is implemented using CreateSymbolicLink
. Since
1.3.3.0, the SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE
flag is included
if supported by the operating system. On POSIX, the function uses symlink
and is therefore atomic.
Windows-specific errors: This operation may fail with permissionErrorType
if the user lacks the privileges to create symbolic links. It may also
fail with illegalOperationErrorType
if the file system does not support
symbolic links.
Since: directory-1.3.1.0
doesFileExist :: FilePath -> IO Bool #
The operation doesFileExist
returns True
if the argument file exists and is not a directory, and False
otherwise.
doesDirectoryExist :: FilePath -> IO Bool #
The operation doesDirectoryExist
returns True
if the argument file
exists and is either a directory or a symbolic link to a directory,
and False
otherwise.
doesPathExist :: FilePath -> IO Bool #
Test whether the given path points to an existing filesystem object. If the user lacks necessary permissions to search the parent directories, this function may return false even if the file does actually exist.
Since: directory-1.2.7.0
Run an IO
action with the given working directory and restore the
original working directory afterwards, even if the given action fails due
to an exception.
The operation may fail with the same exceptions as getCurrentDirectory
and setCurrentDirectory
.
Since: directory-1.2.3.0
setCurrentDirectory :: FilePath -> IO () #
Change the working directory to the given path.
In a multithreaded program, the current working directory is a global state
shared among all threads of the process. Therefore, when performing
filesystem operations from multiple threads, it is highly recommended to
use absolute rather than relative paths (see: makeAbsolute
).
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
The operand is not a valid directory name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
orNoSuchThing
The directory does not exist.[ENOENT, ENOTDIR]
isPermissionError
orPermissionDenied
The process has insufficient privileges to perform the operation.[EACCES]
UnsupportedOperation
The operating system has no notion of current working directory, or the working directory cannot be dynamically changed.InappropriateType
The path refers to an existing non-directory object.[ENOTDIR]
getCurrentDirectory :: IO FilePath #
Obtain the current working directory as an absolute path.
In a multithreaded program, the current working directory is a global state
shared among all threads of the process. Therefore, when performing
filesystem operations from multiple threads, it is highly recommended to
use absolute rather than relative paths (see: makeAbsolute
).
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
isDoesNotExistError
orNoSuchThing
There is no path referring to the working directory.[EPERM, ENOENT, ESTALE...]
isPermissionError
orPermissionDenied
The process has insufficient privileges to perform the operation.[EACCES]
ResourceExhausted
Insufficient resources are available to perform the operation.UnsupportedOperation
The operating system has no notion of current working directory.
listDirectory :: FilePath -> IO [FilePath] #
returns a list of all entries in dir without
the special entries (listDirectory
dir.
and ..
).
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
The operand is not a valid directory name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The directory does not exist.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EACCES]
ResourceExhausted
Insufficient resources are available to perform the operation.[EMFILE, ENFILE]
InappropriateType
The path refers to an existing non-directory object.[ENOTDIR]
Since: directory-1.2.5.0
getDirectoryContents :: FilePath -> IO [FilePath] #
Similar to listDirectory
, but always includes the special entries (.
and ..
). (This applies to Windows as well.)
The operation may fail with the same exceptions as listDirectory
.
exeExtension :: String #
Filename extension for executable files (including the dot if any)
(usually ""
on POSIX systems and ".exe"
on Windows or OS/2).
Since: directory-1.2.4.0
findFilesWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO [FilePath] #
findFilesWith predicate dirs name
searches through the list of
directories (dirs
) for files that have the given name
and satisfy the
given predicate
ands return the paths of those files. The directories
are checked in a left-to-right order and the paths are returned in the same
order.
If the name
is a relative path, then for every search directory dir
,
the function checks whether dir
exists and satisfies the
predicate. If so, </>
namedir
is returned as one of the results. In
other words, the returned paths can be either relative or absolute
depending on the search directories were used. If there are no search
directories, no results are ever returned.</>
name
If the name
is an absolute path, then the function will return a single
result if the file exists and satisfies the predicate and no results
otherwise. This is irrespective of what search directories were given.
Since: directory-1.2.1.0
findFileWith :: (FilePath -> IO Bool) -> [FilePath] -> String -> IO (Maybe FilePath) #
Search through a given list of directories for a file that has the given name and satisfies the given predicate and return the path of the first occurrence. The directories are checked in a left-to-right order.
This is essentially a more performant version of findFilesWith
that
always returns the first result, if any. Details can be found in the
documentation of findFilesWith
.
Since: directory-1.2.6.0
findFiles :: [FilePath] -> String -> IO [FilePath] #
Search through the given list of directories for the given file and returns all paths where the given file exists.
The behavior is equivalent to findFilesWith
. Details can be found in the
documentation of findFilesWith
.
Since: directory-1.2.1.0
findFile :: [FilePath] -> String -> IO (Maybe FilePath) #
Search through the given list of directories for the given file.
The behavior is equivalent to findFileWith
, returning only the first
occurrence. Details can be found in the documentation of findFileWith
.
findExecutablesInDirectories :: [FilePath] -> String -> IO [FilePath] #
Given a name or path, findExecutable
appends the exeExtension
to the
query and searches for executable files in the list of given search
directories and returns all occurrences.
The behavior is equivalent to findFileWith
using the given search
directories and testing each file for executable permissions. Details can
be found in the documentation of findFileWith
.
Unlike other similarly named functions, findExecutablesInDirectories
does
not use SearchPath
from the Win32 API. The behavior of this function on
Windows is therefore equivalent to those on non-Windows platforms.
Since: directory-1.2.4.0
findExecutables :: String -> IO [FilePath] #
Search for executable files in a list of system-defined locations, which
generally includes PATH
and possibly more.
On Windows, this only returns the first ocurrence, if any. Its behavior
is therefore equivalent to findExecutable
.
On non-Windows platforms, the behavior is equivalent to
findExecutablesInDirectories
using the search directories from the PATH
environment variable. Details can be found in the documentation of
findExecutablesInDirectories
.
Since: directory-1.2.2.0
findExecutable :: String -> IO (Maybe FilePath) #
Given the name or path of an executable file, findExecutable
searches
for such a file in a list of system-defined locations, which generally
includes PATH
and possibly more. The full path to the executable is
returned if found. For example, (findExecutable "ghc")
would normally
give you the path to GHC.
The path returned by
corresponds to the program
that would be executed by findExecutable
namecreateProcess
when passed the
same string (as a RawCommand
, not a ShellCommand
), provided that name
is not a relative path with more than one segment.
On Windows, findExecutable
calls the Win32 function
SearchPath
,
which may search other places before checking the directories in the PATH
environment variable. Where it actually searches depends on registry
settings, but notably includes the directory containing the current
executable.
On non-Windows platforms, the behavior is equivalent to findFileWith
using the search directories from the PATH
environment variable and
testing each file for executable permissions. Details can be found in the
documentation of findFileWith
.
makeRelativeToCurrentDirectory :: FilePath -> IO FilePath #
Construct a path relative to the current directory, similar to
makeRelative
.
The operation may fail with the same exceptions as getCurrentDirectory
.
makeAbsolute :: FilePath -> IO FilePath #
Convert a path into an absolute path. If the given path is relative, the
current directory is prepended and then the combined result is
normalise
d. If the path is already absolute, the path is simply
normalise
d. The function preserves the presence or absence of the
trailing path separator unless the path refers to the root directory /
.
If the path is already absolute, the operation never fails. Otherwise, the
operation may fail with the same exceptions as getCurrentDirectory
.
Since: directory-1.2.2.0
canonicalizePath :: FilePath -> IO FilePath #
Make a path absolute, normalise
the path, and remove as many
indirections from it as possible. Any trailing path separators are
discarded via dropTrailingPathSeparator
. Additionally, on Windows the
letter case of the path is canonicalized.
Note: This function is a very big hammer. If you only need an absolute
path, makeAbsolute
is sufficient for removing dependence on the current
working directory.
Indirections include the two special directories .
and ..
, as well as
any symbolic links (and junction points on Windows). The input path need
not point to an existing file or directory. Canonicalization is performed
on the longest prefix of the path that points to an existing file or
directory. The remaining portion of the path that does not point to an
existing file or directory will still undergo normalise
, but case
canonicalization and indirection removal are skipped as they are impossible
to do on a nonexistent path.
Most programs should not worry about the canonicity of a path. In particular, despite the name, the function does not truly guarantee canonicity of the returned path due to the presence of hard links, mount points, etc.
If the path points to an existing file or directory, then the output path shall also point to the same file or directory, subject to the condition that the relevant parts of the file system do not change while the function is still running. In other words, the function is definitively not atomic. The results can be utterly wrong if the portions of the path change while this function is running.
Since some indirections (symbolic links on all systems, ..
on non-Windows
systems, and junction points on Windows) are dependent on the state of the
existing filesystem, the function can only make a conservative attempt by
removing such indirections from the longest prefix of the path that still
points to an existing file or directory.
Note that on Windows parent directories ..
are always fully expanded
before the symbolic links, as consistent with the rest of the Windows API
(such as GetFullPathName
). In contrast, on POSIX systems parent
directories ..
are expanded alongside symbolic links from left to right.
To put this more concretely: if L
is a symbolic link for R/P
, then on
Windows L\..
refers to .
, whereas on other operating systems L/..
refers to R
.
Similar to normalise
, passing an empty path is equivalent to passing the
current directory.
canonicalizePath
can resolve at least 64 indirections in a single path,
more than what is supported by most operating systems. Therefore, it may
return the fully resolved path even though the operating system itself
would have long given up.
On Windows XP or earlier systems, junction expansion is not performed due
to their lack of GetFinalPathNameByHandle
.
Changes since 1.2.3.0: The function has been altered to be more robust
and has the same exception behavior as makeAbsolute
.
Changes since 1.3.0.0: The function no longer preserves the trailing path separator. File symbolic links that appear in the middle of a path are properly dereferenced. Case canonicalization and symbolic link expansion are now performed on Windows.
Copy a file with its associated metadata. If the destination file already exists, it is overwritten. There is no guarantee of atomicity in the replacement of the destination file. Neither path may refer to an existing directory. If the source and/or destination are symbolic links, the copy is performed on the targets of the links.
On Windows, it behaves like the Win32 function CopyFile, which copies various kinds of metadata including file attributes and security resource properties.
On Unix-like systems, permissions, access time, and modification time are preserved. If possible, the owner and group are also preserved. Note that the very act of copying can change the access time of the source file, hence the access times of the two files may differ after the operation completes.
Since: directory-1.2.6.0
Copy a file with its permissions. If the destination file already exists, it is replaced atomically. Neither path may refer to an existing directory. No exceptions are thrown if the permissions could not be copied.
Rename a file or directory. If the destination path already exists, it is replaced atomically. The destination path must not point to an existing directory. A conformant implementation need not support renaming files in all situations (e.g. renaming across different physical devices), but the constraints must be documented.
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
Either operand is not a valid file name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The original file does not exist, or there is no path to the target.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES, EPERM]
ResourceExhausted
Insufficient resources are available to perform the operation.[EDQUOT, ENOSPC, ENOMEM, EMLINK]
UnsatisfiedConstraints
Implementation-dependent constraints are not satisfied.[EBUSY]
UnsupportedOperation
The implementation does not support renaming in this situation.[EXDEV]
InappropriateType
Either the destination path refers to an existing directory, or one of the parent segments in the destination path is not a directory.[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]
Since: directory-1.2.7.0
renameFile :: FilePath -> FilePath -> IO () #
changes the name of an existing file system
object from old to new. If the new object already
exists, it is atomically replaced by the old object. Neither
path may refer to an existing directory. A conformant implementation
need not support renaming files in all situations (e.g. renaming
across different physical devices), but the constraints must be
documented.renameFile
old new
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
Either operand is not a valid file name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The original file does not exist, or there is no path to the target.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES, EPERM]
ResourceExhausted
Insufficient resources are available to perform the operation.[EDQUOT, ENOSPC, ENOMEM, EMLINK]
UnsatisfiedConstraints
Implementation-dependent constraints are not satisfied.[EBUSY]
UnsupportedOperation
The implementation does not support renaming in this situation.[EXDEV]
InappropriateType
Either path refers to an existing directory.[ENOTDIR, EISDIR, EINVAL, EEXIST, ENOTEMPTY]
renameDirectory :: FilePath -> FilePath -> IO () #
changes the name of an existing
directory from old to new. If the new directory
already exists, it is atomically replaced by the old directory.
If the new directory is neither the old directory nor an
alias of the old directory, it is removed as if by
renameDirectory
old newremoveDirectory
. A conformant implementation need not support
renaming directories in all situations (e.g. renaming to an existing
directory, or across different physical devices), but the constraints
must be documented.
On Win32 platforms, renameDirectory
fails if the new directory already
exists.
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
Either operand is not a valid directory name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The original directory does not exist, or there is no path to the target.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES, EPERM]
ResourceExhausted
Insufficient resources are available to perform the operation.[EDQUOT, ENOSPC, ENOMEM, EMLINK]
UnsatisfiedConstraints
Implementation-dependent constraints are not satisfied.[EBUSY, ENOTEMPTY, EEXIST]
UnsupportedOperation
The implementation does not support renaming in this situation.[EINVAL, EXDEV]
InappropriateType
Either path refers to an existing non-directory object.[ENOTDIR, EISDIR]
removeFile :: FilePath -> IO () #
removeFile
file removes the directory entry for an existing file
file, where file is not itself a directory. The
implementation may specify additional constraints which must be
satisfied before a file can be removed (e.g. the file may not be in
use by other processes).
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
The operand is not a valid file name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The file does not exist.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES, EPERM]
UnsatisfiedConstraints
Implementation-dependent constraints are not satisfied.[EBUSY]
InappropriateType
The operand refers to an existing directory.[EPERM, EINVAL]
removePathForcibly :: FilePath -> IO () #
Removes a file or directory at path together with its contents and subdirectories. Symbolic links are removed without affecting their targets. If the path does not exist, nothing happens.
Unlike other removal functions, this function will also attempt to delete files marked as read-only or otherwise made unremovable due to permissions. As a result, if the removal is incomplete, the permissions or attributes on the remaining files may be altered. If there are hard links in the directory, then permissions on all related hard links may be altered.
If an entry within the directory vanishes while removePathForcibly
is
running, it is silently ignored.
If an exception occurs while removing an entry, removePathForcibly
will
still try to remove as many entries as it can before failing with an
exception. The first exception that it encountered is re-thrown.
Since: directory-1.2.7.0
removeDirectoryRecursive :: FilePath -> IO () #
removes an existing directory dir
together with its contents and subdirectories. Within this directory,
symbolic links are removed without affecting their targets.removeDirectoryRecursive
dir
On Windows, the operation fails if dir is a directory symbolic link.
removeDirectory :: FilePath -> IO () #
removes an existing directory dir. The
implementation may specify additional constraints which must be
satisfied before a directory can be removed (e.g. the directory has to
be empty, or may not be in use by other processes). It is not legal
for an implementation to partially remove a directory unless the
entire directory is removed. A conformant implementation need not
support directory removal in all situations (e.g. removal of the root
directory).removeDirectory
dir
The operation may fail with:
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
The operand is not a valid directory name.[ENAMETOOLONG, ELOOP]
isDoesNotExistError
/NoSuchThing
The directory does not exist.[ENOENT, ENOTDIR]
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES, EPERM]
UnsatisfiedConstraints
Implementation-dependent constraints are not satisfied.[EBUSY, ENOTEMPTY, EEXIST]
UnsupportedOperation
The implementation does not support removal in this situation.[EINVAL]
InappropriateType
The operand refers to an existing non-directory object.[ENOTDIR]
creates a new directory
createDirectoryIfMissing
parents dirdir
if it doesn't exist. If the first argument is True
the function will also create all parent directories if they are missing.
createDirectory :: FilePath -> IO () #
creates a new directory createDirectory
dirdir
which is
initially empty, or as near to empty as the operating system
allows.
The operation may fail with:
isPermissionError
/PermissionDenied
The process has insufficient privileges to perform the operation.[EROFS, EACCES]
isAlreadyExistsError
/AlreadyExists
The operand refers to a directory that already exists.[EEXIST]
HardwareFault
A physical I/O error has occurred.[EIO]
InvalidArgument
The operand is not a valid directory name.[ENAMETOOLONG, ELOOP]
NoSuchThing
There is no path to the directory.[ENOENT, ENOTDIR]
ResourceExhausted
Insufficient resources (virtual memory, process file descriptors, physical disk space, etc.) are available to perform the operation.[EDQUOT, ENOSPC, ENOMEM, EMLINK]
InappropriateType
The path refers to an existing non-directory object.[EEXIST]
copyPermissions :: FilePath -> FilePath -> IO () #
Copy the permissions of one file to another. This reproduces the
permissions more accurately than using getPermissions
followed by
setPermissions
.
On Windows, this copies only the read-only attribute.
On POSIX systems, this is equivalent to stat
followed by chmod
.
setPermissions :: FilePath -> Permissions -> IO () #
Set the permissions of a file or directory.
On Windows, this is only capable of changing the writable
permission,
which corresponds to the "read-only" attribute. Changing the other
permissions has no effect.
On POSIX systems, this sets the owner permissions.
The operation may fail with:
isPermissionError
if the user is not permitted to set the permissions, orisDoesNotExistError
if the file or directory does not exist.
getPermissions :: FilePath -> IO Permissions #
Get the permissions of a file or directory.
On Windows, the writable
permission corresponds to the "read-only"
attribute. The executable
permission is set if the file extension is of
an executable file type. The readable
permission is always set.
On POSIX systems, this returns the result of access
.
The operation may fail with:
isPermissionError
if the user is not permitted to access the permissions, orisDoesNotExistError
if the file or directory does not exist.
setOwnerSearchable :: Bool -> Permissions -> Permissions #
setOwnerExecutable :: Bool -> Permissions -> Permissions #
setOwnerWritable :: Bool -> Permissions -> Permissions #
setOwnerReadable :: Bool -> Permissions -> Permissions #
data Permissions #
Instances
Eq Permissions | |
Defined in System.Directory.Internal.Common (==) :: Permissions -> Permissions -> Bool # (/=) :: Permissions -> Permissions -> Bool # | |
Ord Permissions | |
Defined in System.Directory.Internal.Common compare :: Permissions -> Permissions -> Ordering # (<) :: Permissions -> Permissions -> Bool # (<=) :: Permissions -> Permissions -> Bool # (>) :: Permissions -> Permissions -> Bool # (>=) :: Permissions -> Permissions -> Bool # max :: Permissions -> Permissions -> Permissions # min :: Permissions -> Permissions -> Permissions # | |
Read Permissions | |
Defined in System.Directory.Internal.Common readsPrec :: Int -> ReadS Permissions # readList :: ReadS [Permissions] # readPrec :: ReadPrec Permissions # readListPrec :: ReadPrec [Permissions] # | |
Show Permissions | |
Defined in System.Directory.Internal.Common showsPrec :: Int -> Permissions -> ShowS # show :: Permissions -> String # showList :: [Permissions] -> ShowS # |
data XdgDirectory #
Special directories for storing user-specific application data, configuration, and cache files, as specified by the XDG Base Directory Specification.
Note: On Windows, XdgData
and XdgConfig
map to the same directory.
Since: directory-1.2.3.0
XdgData | For data files (e.g. images).
Defaults to |
XdgConfig | For configuration files.
Defaults to |
XdgCache | For non-essential files (e.g. cache).
Defaults to |
Instances
data XdgDirectoryList #
Search paths for various application data, as specified by the XDG Base Directory Specification.
Note: On Windows, XdgDataDirs
and XdgConfigDirs
yield the same result.
Since: directory-1.3.2.0
XdgDataDirs | For data files (e.g. images).
Defaults to |
XdgConfigDirs | For configuration files.
Defaults to |
Instances
isDirectoryEmpty :: FilePath -> IO Bool Source #
True only when directory exists and contains nothing. Throws exception if directory does not exist.
isUnpopulated :: FilePath -> IO Bool Source #
True if the directory does not exist or contains nothing. Ignores "lost+found" which can exist in an empty filesystem.
testDirectory :: FilePath -> (FilePath -> Bool) -> IO Bool Source #
Run test on entries found in directory, return False as soon as the test returns False, else return True. Throws exception if directory does not exist.
withTmpFileIn :: (MonadIO m, MonadMask m) => FilePath -> Template -> (FilePath -> Handle -> m a) -> m a Source #
relatedTemplate :: FilePath -> FilePath Source #
withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a Source #
removeTmpDir :: MonadIO m => FilePath -> m () Source #
segmentDelim :: (a -> Bool) -> [a] -> [[a]] Source #
writeModes :: [FileMode] Source #
executeModes :: [FileMode] Source #
otherGroupModes :: [FileMode] Source #
preventWrite :: FilePath -> IO () Source #
allowWrite :: FilePath -> IO () Source #
groupSharedModes :: [FileMode] Source #
groupWriteRead :: FilePath -> IO () Source #
isExecutable :: FileMode -> Bool Source #
combineModes :: [FileMode] -> FileMode Source #
protectedOutput :: IO a -> IO a Source #