-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Simple interface for shell scripting in Haskell. -- -- Monadic EDSL for writing cross-platform shell scripts in Haskell. Note -- that programs using shellmate should be built with the -threaded flag -- to avoid deadlocks. @package shellmate @version 0.3.4.3 -- | Simple interface for shell scripting-like tasks. module Control.Shell -- | A shell command: either an IO computation or a pipeline of at least -- one step. data Shell a -- | Why did the computation terminate? data ExitReason Success :: ExitReason Failure :: !String -> ExitReason -- | Run a shell computation. If part of the computation fails, the whole -- computation fails. The computation's environment is initially that of -- the whole process. shell :: Shell a -> IO (Either ExitReason a) -- | Run a shell computation and return its result. If the computation -- calls exit, the return value will be undefined. If the -- computation fails, an error will be thrown. shell_ :: Shell a -> IO a -- | Convert an ExitReason into a String. Successful -- termination yields the empty string, while abnormal termination yields -- the termination error message. If the program terminaged abnormally -- but without an error message - i.e. the error message is empty string -- - the error message will be shown as "abnormal termination". exitString :: ExitReason -> String -- | Connect the standard output of the first argument to the standard -- input of the second argument, and run the two computations in -- parallel. (|>) :: Shell () -> Shell () -> Shell () infixl 5 |> -- | Perform the given computation and return its standard output. capture :: Shell () -> Shell String -- | Perform the given computation and return its standard error. captureStdErr :: Shell () -> Shell String -- | Perform the given computation and return its standard output and -- error, in that order. capture2 :: Shell () -> Shell (String, String) -- | Perform the given computation and return its standard output and -- error, as well as its exit reason, in that order. capture3 :: Shell () -> Shell (String, String, ExitReason) -- | Lift a pure function to a computation over standard input/output. -- Similar to interact. stream :: (String -> String) -> Shell () -- | Lift a shell computation to a function over stdin and stdout. Similar -- to interact. lift :: (String -> Shell String) -> Shell () -- | Attempt to run a computation. If the inner computation fails, the -- outer computations returns its error message, otherwise its result is -- returned. try :: Shell a -> Shell (Either String a) -- | Attempt to run the first command. If the first command fails, run the -- second. Forces serialization of the first command. orElse :: Shell a -> Shell a -> Shell a -- | Terminate the program successfully. exit :: Shell a class Guard guard where { -- | The type of the guard's return value, if it succeeds. type family Result guard; } -- | Perform a Shell computation; if the computation succeeds but returns a -- false-ish value, the outer Shell computation fails with the given -- error message. assert :: Guard guard => String -> guard -> Shell (Result guard) -- | Perform a Shell computation; if the computation succeeds but returns a -- false-ish value, the outer Shell computation fails. Corresponds to -- guard. guard :: Guard g => g -> Shell (Result g) -- | Perform the given computation if the given guard passes, otherwise do -- nothing. The guard raising an error counts as failure as far as this -- function is concerned. Corresponds to when. when :: Guard g => g -> Shell () -> Shell () -- | Perform the given computation if the given guard fails, otherwise do -- nothing. The guard raising an error counts as failure as far as this -- function is concerned. Corresponds to unless. unless :: Guard g => g -> Shell () -> Shell () -- | Run a computation with the given environment variable set. withEnv :: String -> String -> Shell a -> Shell a -- | Run a computation with the given environment variable unset. withoutEnv :: String -> Shell a -> Shell a -- | Get the value of an environment variable. Returns Nothing if the -- variable doesn't exist. lookupEnv :: String -> Shell (Maybe String) -- | Get the value of an environment variable. Returns the empty string if -- the variable doesn't exist. getEnv :: String -> Shell String -- | The executable's command line arguments. cmdline :: [String] -- | Monads in which IO computations may be embedded. Any monad -- built by applying a sequence of monad transformers to the IO -- monad will be an instance of this class. -- -- Instances should satisfy the following laws, which state that -- liftIO is a transformer of monads: -- -- class Monad m => MonadIO (m :: Type -> Type) -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | A shell environment: consists of the current standard input, output -- and error handles used by the computation, as well as the current -- working directory and set of environment variables. data Env Env :: !Handle -> !Handle -> !Handle -> !FilePath -> ![(String, String)] -> Env [envStdIn] :: Env -> !Handle [envStdOut] :: Env -> !Handle [envStdErr] :: Env -> !Handle [envWorkDir] :: Env -> !FilePath [envEnvVars] :: Env -> ![(String, String)] -- | Execute an external command. No globbing, escaping or other external -- shell magic is performed on either the command or arguments. The -- program's stdout will be written to stdout. run :: FilePath -> [String] -> Shell () -- | Run a command with elevated privileges. sudo :: FilePath -> [String] -> Shell () -- | Lift an IO computation into a shell. The lifted computation is not -- thread-safe, and should thus absolutely not use environment variables, -- relative paths or standard input/output. unsafeLiftIO :: IO a -> Shell a -- | Create an absolute path from the environment and a potentially -- relative path. Has no effect if the path is already absolute. absPath :: Env -> FilePath -> FilePath -- | Get the current global shell environment, including standard input, -- output and error handles. Only safe to call within a computation -- lifted into Shell by liftIO. shellEnv :: IO Env -- | Get the complete environment for the current computation. getShellEnv :: Shell Env -- | Propagate an explicit ExitResult through the computation. joinResult :: Shell (Either ExitReason a) -> Shell a runSh :: Env -> Shell a -> IO (Either ExitReason a) -- | Recursively copy a directory. If the target is a directory that -- already exists, the source directory is copied into that directory -- using its current name. cpdir :: FilePath -> FilePath -> Shell () -- | Get the current working directory. pwd :: Shell FilePath -- | List the contents of a directory, sans . and ... ls :: FilePath -> Shell [FilePath] -- | Create a directory. Optionally create any required missing directories -- as well. mkdir :: Bool -> FilePath -> Shell () -- | Recursively remove a directory. Follows symlinks, so be careful. rmdir :: FilePath -> Shell () -- | Execute a command in the given working directory, then restore the -- previous working directory. inDirectory :: FilePath -> Shell a -> Shell a -- | Does the given path lead to a directory? isDirectory :: FilePath -> Shell Bool -- | Do something with the user's home directory. withHomeDirectory :: (FilePath -> Shell a) -> Shell a -- | Perform an action with the user's home directory as the working -- directory. inHomeDirectory :: Shell a -> Shell a -- | Do something with the given application's data directory. withAppDirectory :: String -> (FilePath -> Shell a) -> Shell a -- | Do something with the given application's data directory as the -- working directory. inAppDirectory :: FilePath -> Shell a -> Shell a -- | Perform an action on each file in the given directory. This function -- will traverse any subdirectories of the given as well. File paths are -- given relative to the given directory; the current working directory -- is not affected. forEachFile :: FilePath -> (FilePath -> Shell a) -> Shell [a] -- | Like forEachFile but only performs a side effect. forEachFile_ :: FilePath -> (FilePath -> Shell ()) -> Shell () -- | Recursively perform an action on each subdirectory of the given -- directory. The path passed to the callback is relative to the given -- directory. The action will *not* be performed on the given directory -- itself. forEachDirectory :: FilePath -> (FilePath -> Shell a) -> Shell [a] -- | Like forEachDirectory, but discards its result. forEachDirectory_ :: FilePath -> (FilePath -> Shell ()) -> Shell () -- | Does the given path lead to a file? isFile :: FilePath -> Shell Bool -- | Remove a file. rm :: FilePath -> Shell () -- | Rename a file or directory. If the target is a directory, then the -- source will be moved into that directory. mv :: FilePath -> FilePath -> Shell () -- | Copy a file. Fails if the source is a directory. If the target is a -- directory, the source file is copied into that directory using its -- current name. cp :: FilePath -> FilePath -> Shell () -- | Lazily read a file. input :: FilePath -> Shell String -- | Lazily write a file. output :: FilePath -> String -> Shell () -- | Perform a computation over a file. withFile :: FilePath -> IOMode -> (Handle -> Shell a) -> Shell a -- | Perform a computation over a binary file. withBinaryFile :: FilePath -> IOMode -> (Handle -> Shell a) -> Shell a -- | Open a file, returning a handle to it. openFile :: FilePath -> IOMode -> Shell Handle -- | Open a file in binary mode, returning a handle to it. openBinaryFile :: FilePath -> IOMode -> Shell Handle -- | Perform a file operation in binary or text mode? data FileMode BinaryMode :: FileMode TextMode :: FileMode -- | Create a temp file in the standard system temp directory, do something -- with it, then remove it. withTempFile :: FileMode -> (FilePath -> Handle -> Shell a) -> Shell a -- | Create a temp file in the standard system temp directory, do something -- with it, then remove it. withCustomTempFile :: FileMode -> FilePath -> (FilePath -> Handle -> Shell a) -> Shell a -- | Create a temp directory in the standard system temp directory, do -- something with it, then remove it. withTempDirectory :: (FilePath -> Shell a) -> Shell a -- | Create a temp directory in given directory, do something with it, then -- remove it. withCustomTempDirectory :: FilePath -> (FilePath -> Shell a) -> Shell a -- | Performs a command inside a temporary directory. The directory will be -- cleaned up after the command finishes. inTempDirectory :: Shell a -> Shell a -- | Performs a command inside a temporary directory. The directory will be -- cleaned up after the command finishes. inCustomTempDirectory :: FilePath -> Shell a -> Shell a -- | Haskell defines operations to read and write characters from and to -- files, represented by values of type Handle. Each value of -- this type is a handle: a record used by the Haskell run-time -- system to manage I/O with file system objects. A handle has at -- least the following properties: -- -- -- -- Most handles will also have a current I/O position indicating where -- the next input or output operation will occur. A handle is -- readable if it manages only input or both input and output; -- likewise, it is writable if it manages only output or both -- input and output. A handle is open when first allocated. Once -- it is closed it can no longer be used for either input or output, -- though an implementation cannot re-use its storage while references -- remain to it. Handles are in the Show and Eq classes. -- The string produced by showing a handle is system dependent; it should -- include enough information to identify the handle for debugging. A -- handle is equal according to == only to itself; no attempt is -- made to compare the internal state of different handles for equality. data Handle -- | See openFile data IOMode ReadMode :: IOMode WriteMode :: IOMode AppendMode :: IOMode ReadWriteMode :: IOMode -- | Three kinds of buffering are supported: line-buffering, -- block-buffering or no-buffering. These modes have the following -- effects. For output, items are written out, or flushed, from -- the internal buffer according to the buffer mode: -- -- -- -- An implementation is free to flush the buffer more frequently, but not -- less frequently, than specified above. The output buffer is emptied as -- soon as it has been written out. -- -- Similarly, input occurs according to the buffer mode for the handle: -- -- -- -- The default buffering mode when a handle is opened is -- implementation-dependent and may depend on the file system object -- which is attached to that handle. For most implementations, physical -- files will normally be block-buffered and terminals will normally be -- line-buffered. data BufferMode -- | buffering is disabled if possible. NoBuffering :: BufferMode -- | line-buffering should be enabled if possible. LineBuffering :: BufferMode -- | block-buffering should be enabled if possible. The size of the buffer -- is n items if the argument is Just n and is -- otherwise implementation-dependent. BlockBuffering :: Maybe Int -> BufferMode -- | Flush a handle. hFlush :: Handle -> Shell () -- | Close a handle. hClose :: Handle -> Shell () -- | Is the handle ready for reading? hReady :: Handle -> Shell Bool -- | Get the buffering mode of the given handle. hGetBuffering :: Handle -> Shell BufferMode -- | Set the buffering mode of the given handle. hSetBuffering :: Handle -> BufferMode -> Shell () -- | Get the standard input, output and error handle respectively. getStdIn :: Shell Handle -- | Get the standard input, output and error handle respectively. getStdOut :: Shell Handle -- | Get the standard input, output and error handle respectively. getStdErr :: Shell Handle -- | Write a string to a handle. hPutStr :: Handle -> String -> Shell () -- | Write a string to a handle, followed by a newline. hPutStrLn :: Handle -> String -> Shell () -- | Write a string to standard output, followed by a newline. echo :: String -> Shell () -- | Write a string to standard output, without appending a newline. echo_ :: String -> Shell () -- | Read a line of text from standard input. ask :: Shell String -- | Get the contents of the computation's standard input. stdin :: Shell String -- | Read a line of input from a handle. hGetLine :: Handle -> Shell String -- | Lazily read all remaining input from a handle. hGetContents :: Handle -> Shell String data Color Black :: Color Red :: Color Green :: Color Yellow :: Color Blue :: Color Purple :: Color Magenta :: Color White :: Color -- | Apply the given color to the given string. color :: Color -> String -> String -- | Apply the given background color to the given string. background :: Color -> String -> String -- | Apply the terminal's default highlighting to the given string. highlight :: String -> String -- | Output the given string in bold font. bold :: String -> String -- | Underline the given string. underline :: String -> String -- | Read n bytes from a handle. hGetBytes :: Handle -> Int -> Shell ByteString -- | Write a ByteString to a handle. Newline is not appended. hPutBytes :: Handle -> ByteString -> Shell () -- | Read a line of input from a handle and return it as a -- ByteString. hGetByteLine :: Handle -> Shell ByteString -- | Read all remaining input from a handle and return it as a -- ByteString. hGetByteContents :: Handle -> Shell ByteString -- | The join function is the conventional monad join operator. It -- is used to remove one level of monadic structure, projecting its bound -- argument into the outer level. -- --

Examples

-- -- A common use of join is to run an IO computation -- returned from an STM transaction, since STM transactions -- can't perform IO directly. Recall that -- --
--   atomically :: STM a -> IO a
--   
-- -- is used to run STM transactions atomically. So, by specializing -- the types of atomically and join to -- --
--   atomically :: STM (IO b) -> IO (IO b)
--   join       :: IO (IO b)  -> IO b
--   
-- -- we can compose them as -- --
--   join . atomically :: STM (IO b) -> IO b
--   
-- -- to run an STM transaction and the IO action it returns. join :: Monad m => m (m a) -> m a -- | The Monad class defines the basic operations over a -- monad, a concept from a branch of mathematics known as -- category theory. From the perspective of a Haskell programmer, -- however, it is best to think of a monad as an abstract datatype -- of actions. Haskell's do expressions provide a convenient -- syntax for writing monadic expressions. -- -- Instances of Monad should satisfy the following laws: -- -- -- -- Furthermore, the Monad and Applicative operations should -- relate as follows: -- -- -- -- The above laws imply: -- -- -- -- and that pure and (<*>) satisfy the applicative -- functor laws. -- -- The instances of Monad for lists, Maybe and IO -- defined in the Prelude satisfy these laws. class Applicative m => Monad (m :: Type -> Type) -- | Sequentially compose two actions, passing any value produced by the -- first as an argument to the second. (>>=) :: Monad m => m a -> (a -> m b) -> m b -- | Sequentially compose two actions, discarding any value produced by the -- first, like sequencing operators (such as the semicolon) in imperative -- languages. (>>) :: Monad m => m a -> m b -> m b -- | Inject a value into the monadic type. return :: Monad m => a -> m a -- | Fail with a message. This operation is not part of the mathematical -- definition of a monad, but is invoked on pattern-match failure in a -- do expression. -- -- As part of the MonadFail proposal (MFP), this function is moved to its -- own class MonadFail (see Control.Monad.Fail for more -- details). The definition here will be removed in a future release. fail :: Monad m => String -> m a infixl 1 >>= infixl 1 >> -- | The Functor class is used for types that can be mapped over. -- Instances of Functor should satisfy the following laws: -- --
--   fmap id  ==  id
--   fmap (f . g)  ==  fmap f . fmap g
--   
-- -- The instances of Functor for lists, Maybe and IO -- satisfy these laws. class Functor (f :: Type -> Type) fmap :: Functor f => (a -> b) -> f a -> f b -- | Map each element of a structure to a monadic action, evaluate these -- actions from left to right, and collect the results. For a version -- that ignores the results see mapM_. mapM :: (Traversable t, Monad m) => (a -> m b) -> t a -> m (t b) -- | Evaluate each monadic action in the structure from left to right, and -- collect the results. For a version that ignores the results see -- sequence_. sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) -- | Direct MonadPlus equivalent of filter. -- --

Examples

-- -- The filter function is just mfilter specialized to the -- list monad: -- --
--   filter = ( mfilter :: (a -> Bool) -> [a] -> [a] )
--   
-- -- An example using mfilter with the Maybe monad: -- --
--   >>> mfilter odd (Just 1)
--   Just 1
--   >>> mfilter odd (Just 2)
--   Nothing
--   
mfilter :: MonadPlus m => (a -> Bool) -> m a -> m a -- | Strict version of <$>. (<$!>) :: Monad m => (a -> b) -> m a -> m b infixl 4 <$!> -- | Like replicateM, but discards the result. replicateM_ :: Applicative m => Int -> m a -> m () -- | replicateM n act performs the action n times, -- gathering the results. replicateM :: Applicative m => Int -> m a -> m [a] -- | Like foldM, but discards the result. foldM_ :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m () -- | The foldM function is analogous to foldl, except that -- its result is encapsulated in a monad. Note that foldM works -- from left-to-right over the list arguments. This could be an issue -- where (>>) and the `folded function' are not -- commutative. -- --
--   foldM f a1 [x1, x2, ..., xm]
--   
--   ==
--   
--   do
--     a2 <- f a1 x1
--     a3 <- f a2 x2
--     ...
--     f am xm
--   
-- -- If right-to-left evaluation is required, the input list should be -- reversed. -- -- Note: foldM is the same as foldlM foldM :: (Foldable t, Monad m) => (b -> a -> m b) -> b -> t a -> m b -- | zipWithM_ is the extension of zipWithM which ignores the -- final result. zipWithM_ :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m () -- | The zipWithM function generalizes zipWith to arbitrary -- applicative functors. zipWithM :: Applicative m => (a -> b -> m c) -> [a] -> [b] -> m [c] -- | The mapAndUnzipM function maps its first argument over a list, -- returning the result as a pair of lists. This function is mainly used -- with complicated data structures or a state-transforming monad. mapAndUnzipM :: Applicative m => (a -> m (b, c)) -> [a] -> m ([b], [c]) -- | Repeat an action indefinitely. -- --

Examples

-- -- A common use of forever is to process input from network -- sockets, Handles, and channels (e.g. MVar and -- Chan). -- -- For example, here is how we might implement an echo server, -- using forever both to listen for client connections on a -- network socket and to echo client input on client connection handles: -- --
--   echoServer :: Socket -> IO ()
--   echoServer socket = forever $ do
--     client <- accept socket
--     forkFinally (echo client) (\_ -> hClose client)
--     where
--       echo :: Handle -> IO ()
--       echo client = forever $
--         hGetLine client >>= hPutStrLn client
--   
forever :: Applicative f => f a -> f b -- | Right-to-left composition of Kleisli arrows. -- (>=>), with the arguments flipped. -- -- Note how this operator resembles function composition -- (.): -- --
--   (.)   ::            (b ->   c) -> (a ->   b) -> a ->   c
--   (<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c
--   
(<=<) :: Monad m => (b -> m c) -> (a -> m b) -> a -> m c infixr 1 <=< -- | Left-to-right composition of Kleisli arrows. (>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c infixr 1 >=> -- | This generalizes the list-based filter function. filterM :: Applicative m => (a -> m Bool) -> [a] -> m [a] -- | forM is mapM with its arguments flipped. For a version -- that ignores the results see forM_. forM :: (Traversable t, Monad m) => t a -> (a -> m b) -> m (t b) -- | The sum of a collection of actions, generalizing concat. As of -- base 4.8.0.0, msum is just asum, specialized to -- MonadPlus. msum :: (Foldable t, MonadPlus m) => t (m a) -> m a -- | Evaluate each monadic action in the structure from left to right, and -- ignore the results. For a version that doesn't ignore the results see -- sequence. -- -- As of base 4.8.0.0, sequence_ is just sequenceA_, -- specialized to Monad. sequence_ :: (Foldable t, Monad m) => t (m a) -> m () -- | forM_ is mapM_ with its arguments flipped. For a version -- that doesn't ignore the results see forM. -- -- As of base 4.8.0.0, forM_ is just for_, specialized to -- Monad. forM_ :: (Foldable t, Monad m) => t a -> (a -> m b) -> m () -- | Map each element of a structure to a monadic action, evaluate these -- actions from left to right, and ignore the results. For a version that -- doesn't ignore the results see mapM. -- -- As of base 4.8.0.0, mapM_ is just traverse_, specialized -- to Monad. mapM_ :: (Foldable t, Monad m) => (a -> m b) -> t a -> m () -- | void value discards or ignores the result of -- evaluation, such as the return value of an IO action. -- --

Examples

-- -- Replace the contents of a Maybe Int with -- unit: -- --
--   >>> void Nothing
--   Nothing
--   
--   >>> void (Just 3)
--   Just ()
--   
-- -- Replace the contents of an Either Int -- Int with unit, resulting in an Either -- Int '()': -- --
--   >>> void (Left 8675309)
--   Left 8675309
--   
--   >>> void (Right 8675309)
--   Right ()
--   
-- -- Replace every element of a list with unit: -- --
--   >>> void [1,2,3]
--   [(),(),()]
--   
-- -- Replace the second element of a pair with unit: -- --
--   >>> void (1,2)
--   (1,())
--   
-- -- Discard the result of an IO action: -- --
--   >>> mapM print [1,2]
--   1
--   2
--   [(),()]
--   
--   >>> void $ mapM print [1,2]
--   1
--   2
--   
void :: Functor f => f a -> f () -- | In many situations, the liftM operations can be replaced by -- uses of ap, which promotes function application. -- --
--   return f `ap` x1 `ap` ... `ap` xn
--   
-- -- is equivalent to -- --
--   liftMn f x1 x2 ... xn
--   
ap :: Monad m => m (a -> b) -> m a -> m b -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM5 :: Monad m => (a1 -> a2 -> a3 -> a4 -> a5 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m a5 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM4 :: Monad m => (a1 -> a2 -> a3 -> a4 -> r) -> m a1 -> m a2 -> m a3 -> m a4 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right (cf. liftM2). liftM3 :: Monad m => (a1 -> a2 -> a3 -> r) -> m a1 -> m a2 -> m a3 -> m r -- | Promote a function to a monad, scanning the monadic arguments from -- left to right. For example, -- --
--   liftM2 (+) [0,1] [0,2] = [0,2,1,3]
--   liftM2 (+) (Just 1) Nothing = Nothing
--   
liftM2 :: Monad m => (a1 -> a2 -> r) -> m a1 -> m a2 -> m r -- | Promote a function to a monad. liftM :: Monad m => (a1 -> r) -> m a1 -> m r -- | Same as >>=, but with the arguments interchanged. (=<<) :: Monad m => (a -> m b) -> m a -> m b infixr 1 =<< -- | Monads that also support choice and failure. class (Alternative m, Monad m) => MonadPlus (m :: Type -> Type) -- | The identity of mplus. It should also satisfy the equations -- --
--   mzero >>= f  =  mzero
--   v >> mzero   =  mzero
--   
-- -- The default definition is -- --
--   mzero = empty
--   
mzero :: MonadPlus m => m a -- | An associative operation. The default definition is -- --
--   mplus = (<|>)
--   
mplus :: MonadPlus m => m a -> m a -> m a -- | Working with daemons, users, groups, file permissions and file -- ownerships. Not present on Windows unless shellmate is installed with -- the with-posix flag. module Control.Shell.Posix type User = String type Group = String -- | Get the currently effective user name. getCurrentUser :: Shell String -- | Get the list of groups associated with the current process. getCurrentGroups :: Shell [String] -- | Get the owner of the given file. getOwner :: FilePath -> Shell User -- | Get the group of the given file. getGroup :: FilePath -> Shell Group -- | Get the owner and group of the given file. getOwnership :: FilePath -> Shell (User, Group) -- | Set the owner of the given file. setOwner :: User -> FilePath -> Shell () -- | Set the group of the given file. setGroup :: Group -> FilePath -> Shell () -- | Set the owner and group of the given file. setOwnership :: User -> Group -> FilePath -> Shell () data CMode -- | Combines the two file modes into one that contains modes that appear -- in either. unionFileModes :: FileMode -> FileMode -> FileMode -- | Combines two file modes into one that only contains modes that appear -- in both. intersectFileModes :: FileMode -> FileMode -> FileMode -- | No permissions. nullFileMode :: FileMode -- | Owner has read permission. ownerReadMode :: FileMode -- | Owner has write permission. ownerWriteMode :: FileMode -- | Owner has execute permission. ownerExecuteMode :: FileMode -- | Owner has read, write and execute permission. ownerModes :: FileMode -- | Group has read permission. groupReadMode :: FileMode -- | Group has write permission. groupWriteMode :: FileMode -- | Group has execute permission. groupExecuteMode :: FileMode -- | Group has read, write and execute permission. groupModes :: FileMode -- | Others have read permission. otherReadMode :: FileMode -- | Others have write permission. otherWriteMode :: FileMode -- | Others have execute permission. otherExecuteMode :: FileMode -- | Others have read, write and execute permission. otherModes :: FileMode -- | Owner, group and others have read and write permission. stdFileMode :: FileMode -- | Owner, group and others have read, write and execute permission. accessModes :: FileMode -- | Set the mode (permissions, etc.) of the given file. setFileMode :: FilePath -> CMode -> Shell () -- | Get the mode of the given file. getFileMode :: FilePath -> Shell CMode -- | Set the file creation mask of this process. setFileCreationMask :: CMode -> Shell CMode -- | Daemonize a shellmate computation. This should be the last thing a -- computation does, as this function will terminate the parent -- computation. In short, daemonizing a computation involves setting the -- file creation mask to 0, closing standard input, output and error file -- descriptors, blocking sighup and changing the working directory to -- /. -- -- On Windows without Cygwin, daemonize is a no-op. Consider -- running any program intended to be deamonized using START /B -- your_app, or better yet, rewriting it as a Windows service. daemonize :: Shell () -> Shell () -- | Concurrency for Shellmate programs. module Control.Shell.Concurrent -- | A future is a computation which is run in parallel with a program's -- main thread and which may at some later point finish and return a -- value. -- -- Note that future computations are killed when their corresponding -- Future is garbage collected. This means that a future should -- *always* be awaited at some point or otherwise kept alive, to -- ensure that the computation finishes. -- -- Note that all any code called in a future using unsafeLiftIO -- must refrain from using environment variables, standard input/output, -- relative paths and the current working directory, in order to avoid -- race conditions. Code within the Shell monad, code imported -- using liftIO and external processes spawned from within -- Shell is perfectly safe. data Future a -- | A ThreadId is an abstract type representing a handle to a -- thread. ThreadId is an instance of Eq, Ord and -- Show, where the Ord instance implements an arbitrary -- total ordering over ThreadIds. The Show instance lets -- you convert an arbitrary-valued ThreadId to string form; -- showing a ThreadId value is occasionally useful when debugging -- or diagnosing the behaviour of a concurrent program. -- -- Note: in GHC, if you have a ThreadId, you essentially -- have a pointer to the thread itself. This means the thread itself -- can't be garbage collected until you drop the ThreadId. This -- misfeature will hopefully be corrected at a later date. data ThreadId -- | Run a computation in a separate thread. If the thread throws an error, -- it will simply die; the error will not propagate to its parent thread. forkIO :: Shell () -> Shell ThreadId -- | Terminate a thread spawned by forkIO. killThread :: ThreadId -> Shell () -- | Run a computation in a separate thread, with its standard input and -- output provided by the first and second handles returned respectively. -- The handles are line buffered by default. fork2 :: Shell () -> Shell (Handle, Handle, ThreadId) -- | Like fork2, but adds a third handle for standard error. fork3 :: Shell () -> Shell (Handle, Handle, Handle, ThreadId) -- | Create a future value. future :: Shell a -> Shell (Future a) -- | Wait for a future value. await :: Future a -> Shell a -- | Check whether a future value has arrived or not. check :: Future a -> Shell (Maybe a) -- | Perform the given computations in parallel. The race condition warning -- for Future when modifying environment variables or using -- relative paths still applies. parallel :: [Shell a] -> Shell [a] -- | Like parallel, but discards any return values. parallel_ :: [Shell a] -> Shell () -- | Break a list into chunks. This is quite useful for when performing -- *every* computation in parallel is too much. For instance, to download -- a list of files three at a time, one would do mapM_ (parallel_ -- downloadFile) (chunks 3 files). chunks :: Int -> [a] -> [[a]]