propellor-5.7.0: property-based host configuration management in haskell

Safe HaskellNone
LanguageHaskell98

Propellor.Utilities

Description

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

Documentation

read :: Read a => String -> a Source #

head :: [a] -> a Source #

tail :: [a] -> [a] Source #

init :: [a] -> [a] Source #

last :: [a] -> a Source #

headMaybe :: [a] -> Maybe a Source #

lastMaybe :: [a] -> Maybe a Source #

beginning :: [a] -> [a] Source #

end :: [a] -> [a] Source #

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 Just e is returned where e 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 #

Arguments

:: CreateProcess 
-> String

standard input

-> IO (ExitCode, String, String)

exitcode, stdout, stderr

readCreateProcessWithExitCode works exactly like readProcessWithExitCode except that it lets you pass CreateProcess giving better flexibility.

Note that Handles provided for std_in, std_out, or std_err via the CreateProcess record will be ignored.

Since: process-1.2.3.0

readCreateProcess #

Arguments

:: 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 Handles 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 handles.

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 Handles 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.

type Pid = CPid #

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

interruptProcessGroupOf #

Arguments

:: 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

createProcess_ #

Arguments

:: 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:

  • Handles provided via UseHandle 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

data CmdSpec #

Constructors

ShellCommand String

A command line to execute using the shell

RawCommand FilePath [String]

The name of an executable with a list of arguments

The FilePath argument names the executable, and is interpreted according to the platform's standard policy for searching for executables. Specifically:

  • on Unix systems the execvp(3) semantics is used, where if the executable filename does not contain a slash (/) then the PATH environment variable is searched for the executable.
  • on Windows systems the Win32 CreateProcess semantics is used. Briefly: if the filename does not contain a path, then the directory containing the parent executable is searched, followed by the current directory, then some standard locations, and finally the current PATH. An .exe extension is added if the filename does not already have an extension. For full details see the documentation for the Windows SearchPath API.
Instances
Eq CmdSpec 
Instance details

Defined in System.Process.Common

Methods

(==) :: CmdSpec -> CmdSpec -> Bool #

(/=) :: CmdSpec -> CmdSpec -> Bool #

Show CmdSpec 
Instance details

Defined in System.Process.Common

IsString CmdSpec

construct a ShellCommand from a string literal

Since: process-1.2.1.0

Instance details

Defined in System.Process.Common

Methods

fromString :: String -> CmdSpec #

data StdStream #

Constructors

Inherit

Inherit Handle from parent

UseHandle Handle

Use the supplied Handle

CreatePipe

Create a new pipe. The returned Handle will use the default encoding and newline translation mode (just like Handles created by openFile).

NoStream

No stream handle will be passed

Instances
Eq StdStream 
Instance details

Defined in System.Process.Common

Show StdStream 
Instance details

Defined in System.Process.Common

data CreateProcess #

Constructors

CreateProcess 

Fields

  • cmdspec :: CmdSpec

    Executable & arguments, or shell command. If cwd is Nothing, relative paths are resolved with respect to the current working directory. If cwd is provided, it is implementation-dependent whether relative paths are resolved with respect to cwd or the current working directory, so absolute paths should be used to ensure portability.

  • cwd :: Maybe FilePath

    Optional path to the working directory for the new process

  • env :: Maybe [(String, String)]

    Optional environment (otherwise inherit from the current process)

  • std_in :: StdStream

    How to determine stdin

  • std_out :: StdStream

    How to determine stdout

  • std_err :: StdStream

    How to determine stderr

  • close_fds :: Bool

    Close all file descriptors except stdin, stdout and stderr in the new process (on Windows, only works if std_in, std_out, and std_err are all Inherit)

  • create_group :: Bool

    Create a new process group

  • delegate_ctlc :: Bool

    Delegate control-C handling. Use this for interactive console processes to let them handle control-C themselves (see below for details).

    On Windows this has no effect.

    Since: process-1.2.0.0

  • detach_console :: Bool

    Use the windows DETACHED_PROCESS flag when creating the process; does nothing on other platforms.

    Since: process-1.3.0.0

  • create_new_console :: Bool

    Use the windows CREATE_NEW_CONSOLE flag when creating the process; does nothing on other platforms.

    Default: False

    Since: process-1.3.0.0

  • new_session :: Bool

    Use posix setsid to start the new process in a new session; does nothing on other platforms.

    Since: process-1.3.0.0

  • child_group :: Maybe GroupID

    Use posix setgid to set child process's group id; does nothing on other platforms.

    Default: Nothing

    Since: process-1.4.0.0

  • child_user :: Maybe UserID

    Use posix setuid to set child process's user id; does nothing on other platforms.

    Default: Nothing

    Since: process-1.4.0.0

  • use_process_jobs :: Bool

    On Windows systems this flag indicates that we should wait for the entire process tree to finish before unblocking. On POSIX systems this flag is ignored.

    Default: False

    Since: process-1.5.0.0

data StdHandle Source #

Instances
Eq StdHandle Source # 
Instance details

Defined in Utility.Process

readProcess :: FilePath -> [String] -> IO String Source #

Normally, when reading from a process, it does not need to be fed any standard input.

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.

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.

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 #

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.

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

Minimal complete definition

Nothing

Methods

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
Exception AsyncCancelled 
Instance details

Defined in Control.Concurrent.Async

Exception ExceptionInLinkedThread 
Instance details

Defined in Control.Concurrent.Async

Exception Void

Since: base-4.8.0.0

Instance details

Defined in Data.Void

Exception PatternMatchFail

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception RecSelError

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception RecConError

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception RecUpdError

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception NoMethodError

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception TypeError

Since: base-4.9.0.0

Instance details

Defined in Control.Exception.Base

Exception NonTermination

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception NestedAtomically

Since: base-4.0

Instance details

Defined in Control.Exception.Base

Exception Dynamic

Since: base-4.0.0.0

Instance details

Defined in Data.Dynamic

Exception BlockedIndefinitelyOnMVar

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception BlockedIndefinitelyOnSTM

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception Deadlock

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception AllocationLimitExceeded

Since: base-4.8.0.0

Instance details

Defined in GHC.IO.Exception

Exception CompactionFailed

Since: base-4.10.0.0

Instance details

Defined in GHC.IO.Exception

Exception AssertionFailed

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception SomeAsyncException

Since: base-4.7.0.0

Instance details

Defined in GHC.IO.Exception

Exception AsyncException

Since: base-4.7.0.0

Instance details

Defined in GHC.IO.Exception

Exception ArrayException

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception FixIOException

Since: base-4.11.0.0

Instance details

Defined in GHC.IO.Exception

Exception ExitCode

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception IOException

Since: base-4.1.0.0

Instance details

Defined in GHC.IO.Exception

Exception ErrorCall

Since: base-4.0.0.0

Instance details

Defined in GHC.Exception

Exception ArithException

Since: base-4.0.0.0

Instance details

Defined in GHC.Exception.Type

Exception SomeException

Since: base-3.0

Instance details

Defined in GHC.Exception.Type

Exception StopPropellorException Source # 
Instance details

Defined in Propellor.Types.Exception

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.

Constructors

SomeException :: forall e. Exception e => e -> SomeException 

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 #

handleIf :: (MonadCatch m, Exception e) => (e -> Bool) -> (e -> m a) -> m a -> m a #

Flipped catchIf

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 #

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 IOErrors 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.

mask_ :: MonadMask m => m a -> m a #

Like mask, 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.

Methods

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
MonadThrow [] 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> [a] #

MonadThrow Maybe 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> Maybe a #

MonadThrow IO 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> IO a #

MonadThrow Q 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> Q a #

MonadThrow STM 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> STM a #

MonadThrow Propellor Source # 
Instance details

Defined in Propellor.Types.Core

Methods

throwM :: Exception e => e -> Propellor a #

e ~ SomeException => MonadThrow (Either e) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e0 => e0 -> Either e a #

MonadThrow m => MonadThrow (MaybeT m)

Throws exceptions into the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> MaybeT m a #

MonadThrow m => MonadThrow (ListT m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> ListT m a #

MonadThrow m => MonadThrow (ExceptT e m)

Throws exceptions into the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e0 => e0 -> ExceptT e m a #

MonadThrow m => MonadThrow (IdentityT m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> IdentityT m a #

(Error e, MonadThrow m) => MonadThrow (ErrorT e m)

Throws exceptions into the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e0 => e0 -> ErrorT e m a #

MonadThrow m => MonadThrow (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> StateT s m a #

MonadThrow m => MonadThrow (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> StateT s m a #

(MonadThrow m, Monoid w) => MonadThrow (WriterT w m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> WriterT w m a #

(MonadThrow m, Monoid w) => MonadThrow (WriterT w m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> WriterT w m a #

MonadThrow m => MonadThrow (ContT r m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> ContT r m a #

MonadThrow m => MonadThrow (ReaderT r m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> ReaderT r m a #

(MonadThrow m, Monoid w) => MonadThrow (RWST r w s m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> RWST r w s m a #

(MonadThrow m, Monoid w) => MonadThrow (RWST r w s m) 
Instance details

Defined in Control.Monad.Catch

Methods

throwM :: Exception e => e -> RWST r w s m a #

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.

Methods

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 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => IO a -> (e -> IO a) -> IO a #

MonadCatch STM 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => STM a -> (e -> STM a) -> STM a #

MonadCatch Propellor Source # 
Instance details

Defined in Propellor.Types.Core

Methods

catch :: Exception e => Propellor a -> (e -> Propellor a) -> Propellor a #

e ~ SomeException => MonadCatch (Either e)

Since: exceptions-0.8.3

Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e0 => Either e a -> (e0 -> Either e a) -> Either e a #

MonadCatch m => MonadCatch (MaybeT m)

Catches exceptions from the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => MaybeT m a -> (e -> MaybeT m a) -> MaybeT m a #

MonadCatch m => MonadCatch (ListT m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => ListT m a -> (e -> ListT m a) -> ListT m a #

MonadCatch m => MonadCatch (ExceptT e m)

Catches exceptions from the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e0 => ExceptT e m a -> (e0 -> ExceptT e m a) -> ExceptT e m a #

MonadCatch m => MonadCatch (IdentityT m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => IdentityT m a -> (e -> IdentityT m a) -> IdentityT m a #

(Error e, MonadCatch m) => MonadCatch (ErrorT e m)

Catches exceptions from the base monad.

Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e0 => ErrorT e m a -> (e0 -> ErrorT e m a) -> ErrorT e m a #

MonadCatch m => MonadCatch (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => StateT s m a -> (e -> StateT s m a) -> StateT s m a #

MonadCatch m => MonadCatch (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => StateT s m a -> (e -> StateT s m a) -> StateT s m a #

(MonadCatch m, Monoid w) => MonadCatch (WriterT w m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a #

(MonadCatch m, Monoid w) => MonadCatch (WriterT w m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => WriterT w m a -> (e -> WriterT w m a) -> WriterT w m a #

MonadCatch m => MonadCatch (ReaderT r m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => ReaderT r m a -> (e -> ReaderT r m a) -> ReaderT r m a #

(MonadCatch m, Monoid w) => MonadCatch (RWST r w s m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a #

(MonadCatch m, Monoid w) => MonadCatch (RWST r w s m) 
Instance details

Defined in Control.Monad.Catch

Methods

catch :: Exception e => RWST r w s m a -> (e -> RWST r w s m a) -> RWST r w s m a #

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.

Methods

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.

generalBracket #

Arguments

:: 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 overrides use's state
      -- changes and the state reverts to s1.
      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 two Either effects determines
    -- which error will win if they are both Lefts. We want the error from
    -- release to win.
    c <- ec
    b <- eb
    return (b, c)

Since: exceptions-0.9.0

Instances
MonadMask IO 
Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. IO a -> IO a) -> IO b) -> IO b #

uninterruptibleMask :: ((forall a. IO a -> IO a) -> IO b) -> IO b #

generalBracket :: IO a -> (a -> ExitCase b -> IO c) -> (a -> IO b) -> IO (b, c) #

MonadMask Propellor Source # 
Instance details

Defined in Propellor.Types.Core

Methods

mask :: ((forall a. Propellor a -> Propellor a) -> Propellor b) -> Propellor b #

uninterruptibleMask :: ((forall a. Propellor a -> Propellor a) -> Propellor b) -> Propellor b #

generalBracket :: Propellor a -> (a -> ExitCase b -> Propellor c) -> (a -> Propellor b) -> Propellor (b, c) #

e ~ SomeException => MonadMask (Either e)

Since: exceptions-0.8.3

Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. Either e a -> Either e a) -> Either e b) -> Either e b #

uninterruptibleMask :: ((forall a. Either e a -> Either e a) -> Either e b) -> Either e b #

generalBracket :: Either e a -> (a -> ExitCase b -> Either e c) -> (a -> Either e b) -> Either e (b, c) #

MonadMask m => MonadMask (MaybeT m)

Since: exceptions-0.10.0

Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. MaybeT m a -> MaybeT m a) -> MaybeT m b) -> MaybeT m b #

uninterruptibleMask :: ((forall a. MaybeT m a -> MaybeT m a) -> MaybeT m b) -> MaybeT m b #

generalBracket :: MaybeT m a -> (a -> ExitCase b -> MaybeT m c) -> (a -> MaybeT m b) -> MaybeT m (b, c) #

MonadMask m => MonadMask (ExceptT e m)

Since: exceptions-0.9.0

Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. ErrorT e m a -> ErrorT e m a) -> ErrorT e m b) -> ErrorT e m b #

uninterruptibleMask :: ((forall a. ErrorT e m a -> ErrorT e m a) -> ErrorT e m b) -> ErrorT e m b #

generalBracket :: ErrorT e m a -> (a -> ExitCase b -> ErrorT e m c) -> (a -> ErrorT e m b) -> ErrorT e m (b, c) #

MonadMask m => MonadMask (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. StateT s m a -> StateT s m a) -> StateT s m b) -> StateT s m b #

uninterruptibleMask :: ((forall a. StateT s m a -> StateT s m a) -> StateT s m b) -> StateT s m b #

generalBracket :: StateT s m a -> (a -> ExitCase b -> StateT s m c) -> (a -> StateT s m b) -> StateT s m (b, c) #

MonadMask m => MonadMask (StateT s m) 
Instance details

Defined in Control.Monad.Catch

Methods

mask :: ((forall a. StateT s m a -> StateT s m a) -> StateT s m b) -> StateT s m b #

uninterruptibleMask :: ((forall a. StateT s m a -> StateT s m a) -> StateT s m b) -> StateT s m b #

generalBracket :: StateT s m a -> (a -> ExitCase b -> StateT s m c) -> (a -> StateT s m b) -> StateT s m (b, c) #

(MonadMask m, Monoid w) => MonadMask (WriterT w m) 
Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

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) 
Instance details

Defined in Control.Monad.Catch

Methods

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) #

data ExitCase a #

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).

Instances
Show a => Show (ExitCase a) 
Instance details

Defined in Control.Monad.Catch

Methods

showsPrec :: Int -> ExitCase a -> ShowS #

show :: ExitCase a -> String #

showList :: [ExitCase a] -> ShowS #

giveup :: [Char] -> a 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 #

bracketIO :: (MonadMask m, MonadIO m) => IO v -> (v -> IO b) -> (v -> m a) -> m a Source #

catchNonAsync :: MonadCatch m => m a -> (SomeException -> m a) -> m a Source #

tryWhenExists :: MonadCatch m => m a -> m (Maybe a) Source #

catchIOErrorType :: MonadCatch m => IOErrorType -> (IOException -> m a) -> m a -> m a Source #

catchPermissionDenied :: MonadCatch m => (IOException -> m a) -> m a -> m a Source #

addEntry :: Eq k => k -> v -> [(k, v)] -> [(k, v)] Source #

addEntries :: Eq k => [(k, v)] -> [(k, v)] -> [(k, v)] Source #

delEntry :: Eq k => k -> [(k, v)] -> [(k, v)] Source #

setEnv :: String -> String -> Bool -> IO () 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:

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:

getAppUserDataDirectory #

Arguments

:: FilePath

a relative path that is appended to the path

-> IO FilePath 

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:

getXdgDirectoryList #

Arguments

:: XdgDirectoryList

which special directory list

-> IO [FilePath] 

getXdgDirectory #

Arguments

:: 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:

setModificationTime :: FilePath -> UTCTime -> IO () #

Change the time at which the file or directory was last modified.

The operation may fail with:

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 where utimensat is supported, the modification time is set atomically with nanosecond precision.
  • If compiled against a version of unix prior to 2.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:

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 where utimensat is supported, the access time is set atomically with nanosecond precision.
  • If compiled against a version of unix prior to 2.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:

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:

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

createDirectoryLink #

Arguments

:: FilePath

path to the target directory

-> FilePath

path of the link to be created

-> IO () 

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

createFileLink #

Arguments

:: FilePath

path to the target file

-> FilePath

path of the link to be created

-> IO () 

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

withCurrentDirectory #

Arguments

:: FilePath

Directory to execute in

-> IO a

Action to be executed

-> IO a 

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 or NoSuchThing The directory does not exist. [ENOENT, ENOTDIR]
  • isPermissionError or PermissionDenied 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 or NoSuchThing There is no path referring to the working directory. [EPERM, ENOENT, ESTALE...]
  • isPermissionError or PermissionDenied 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] #

listDirectory dir returns a list of all entries in dir without the special entries (. 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 </> name exists and satisfies the predicate. If so, dir </> name 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.

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 findExecutable name corresponds to the program that would be executed by createProcess 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 normalised. If the path is already absolute, the path is simply normalised. 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.

copyFileWithMetadata #

Arguments

:: FilePath

Source file

-> FilePath

Destination file

-> IO () 

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

copyFile #

Arguments

:: FilePath

Source filename

-> FilePath

Destination filename

-> IO () 

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.

renamePath #

Arguments

:: FilePath

Old path

-> FilePath

New path

-> IO () 

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 () #

renameFile old new 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.

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 () #

renameDirectory old new 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 removeDirectory. 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 () #

removeDirectoryRecursive dir removes an existing directory dir together with its contents and subdirectories. Within this directory, symbolic links are removed without affecting their targets.

On Windows, the operation fails if dir is a directory symbolic link.

removeDirectory :: FilePath -> IO () #

removeDirectory dir 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).

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]

createDirectoryIfMissing #

Arguments

:: Bool

Create its parents too?

-> FilePath

The path to the directory you want to make

-> IO () 

createDirectoryIfMissing parents dir creates a new directory dir 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 () #

createDirectory dir creates a new directory dir 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:

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:

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

Constructors

XdgData

For data files (e.g. images). Defaults to ~/.local/share and can be overridden by the XDG_DATA_HOME environment variable. On Windows, it is %APPDATA% (e.g. C:/Users/<user>/AppData/Roaming). Can be considered as the user-specific equivalent of /usr/share.

XdgConfig

For configuration files. Defaults to ~/.config and can be overridden by the XDG_CONFIG_HOME environment variable. On Windows, it is %APPDATA% (e.g. C:/Users/<user>/AppData/Roaming). Can be considered as the user-specific equivalent of /etc.

XdgCache

For non-essential files (e.g. cache). Defaults to ~/.cache and can be overridden by the XDG_CACHE_HOME environment variable. On Windows, it is %LOCALAPPDATA% (e.g. C:/Users/<user>/AppData/Local). Can be considered as the user-specific equivalent of /var/cache.

Instances
Bounded XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

Enum XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

Eq XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

Ord XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

Read XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

Show XdgDirectory 
Instance details

Defined in System.Directory.Internal.Common

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

Constructors

XdgDataDirs

For data files (e.g. images). Defaults to usrlocalshare and usrshare/ and can be overridden by the XDG_DATA_DIRS environment variable. On Windows, it is %PROGRAMDATA% or %ALLUSERSPROFILE% (e.g. C:/ProgramData).

XdgConfigDirs

For configuration files. Defaults to etcxdg and can be overridden by the XDG_CONFIG_DIRS environment variable. On Windows, it is %PROGRAMDATA% or %ALLUSERSPROFILE% (e.g. C:/ProgramData).

Instances
Bounded XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

Enum XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

Eq XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

Ord XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

Read XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

Show XdgDirectoryList 
Instance details

Defined in System.Directory.Internal.Common

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.

viaTmp :: (MonadMask m, MonadIO m) => (FilePath -> v -> m ()) -> FilePath -> v -> m () Source #

withTmpFile :: (MonadIO m, MonadMask m) => Template -> (FilePath -> Handle -> m a) -> m a Source #

withTmpFileIn :: (MonadIO m, MonadMask m) => FilePath -> Template -> (FilePath -> Handle -> m a) -> m a Source #

withTmpDir :: (MonadMask m, MonadIO m) => Template -> (FilePath -> m a) -> m a Source #

withTmpDirIn :: (MonadMask m, MonadIO m) => FilePath -> Template -> (FilePath -> m a) -> m a Source #

firstM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a) Source #

getM :: Monad m => (a -> m (Maybe b)) -> [a] -> m (Maybe b) Source #

anyM :: Monad m => (a -> m Bool) -> [a] -> m Bool Source #

allM :: Monad m => (a -> m Bool) -> [a] -> m Bool Source #

untilTrue :: Monad m => [a] -> (a -> m Bool) -> m Bool Source #

ifM :: Monad m => m Bool -> (m a, m a) -> m a Source #

(<||>) :: Monad m => m Bool -> m Bool -> m Bool infixr 2 Source #

(<&&>) :: Monad m => m Bool -> m Bool -> m Bool infixr 3 Source #

observe :: Monad m => (a -> m b) -> m a -> m a Source #

after :: Monad m => m b -> m a -> m a Source #

noop :: Monad m => m () Source #

separate :: (a -> Bool) -> [a] -> ([a], [a]) Source #

segment :: (a -> Bool) -> [a] -> [[a]] Source #

segmentDelim :: (a -> Bool) -> [a] -> [[a]] Source #

noUmask :: (MonadIO m, MonadMask m) => FileMode -> m a -> m a Source #

withUmask :: (MonadIO m, MonadMask m) => FileMode -> m a -> m a Source #