-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Haskell for Unix shell scripting tasks -- -- A Haskell-library for tasks which are usually done in shell scripts. -- This includes parsing command line arguments; dealing with paths; some -- commands for dealing with files; calling external programs and -- subroutines as separate processes; pipes and redirection of input and -- output; and error handling. @package hsshellscript @version 3.2.0 module HsShellScript.GetOpt -- | Process the command-line, and return the list of values that matched -- (and those that didn't). The arguments are: -- -- -- -- getOpt returns a triple, consisting of the argument values, a -- list of options that didn't match, and a list of error messages. getOpt :: ArgOrder a -> [OptDescr a] -> [String] -> ([a], [String], [String]) -- | Return a string describing the usage of a command, derived from the -- header (first argument) and the options described by the second -- argument. usageInfo :: String -> [OptDescr a] -> String -- | What to do with options following non-options data ArgOrder a -- | no option processing after first non-option RequireOrder :: ArgOrder a -- | freely intersperse options and non-options Permute :: ArgOrder a -- | wrap non-options into options ReturnInOrder :: (String -> a) -> ArgOrder a -- | Each OptDescr describes a single option. -- -- The arguments to Option are: -- -- data OptDescr a Option :: [Char] -> [String] -> (ArgDescr a) -> String -> OptDescr a -- | Describes whether an option takes an argument or not, and if so how -- the argument is injected into a value of type a. data ArgDescr a -- | no argument expected NoArg :: a -> ArgDescr a -- | option requires argument ReqArg :: (String -> a) -> String -> ArgDescr a -- | optional argument OptArg :: (Maybe String -> a) -> String -> ArgDescr a module HsShellScript.Shell -- | Generate command (for a shell) which corresponds to the specified -- program name and argument list. The program name and arguments are the -- usual parameters for calling an external program, like when using -- runProcess or run. The generated shell command would -- achieve the same effect. The name and the arguments are properly -- quoted, using shell_quote. -- -- Note: The quoted strings are correctly recognized in shell scripts. -- But the shell bash has an annoying history expansion "feature", which -- causes it to choke on exclamation marks, when in interactive mode, -- even when quoted with double quotes. You can turn it off with set -- +o histexpand. shell_command :: String -> [String] -> String -- | Quote shell metacharacters. -- -- This function quotes strings, such that they are not misinterpreted by -- the shell. It tries to be friendly to a human reader - when special -- characters are present, then the string is quoted with double quotes. -- If not, it is left unchanged. -- -- The list of exacly which characters need to be quoted has been taken -- from the bash source code. Bash in turn, implements POSIX 1003.2. So -- the result produced should be correct. From the bash info pages: "... -- the rules for evaluation and quoting are taken from the POSIX 1003.2 -- specification for the standard Unix shell." -- -- Note: The quoted strings are correctly recognized in shell scripts. -- But the shell bash has an annoying history expansion "feature", which -- causes it to choke on exclamation marks, when in interactive mode, -- even when quoted with double quotes. You can turn it off with set -- +o histexpand. -- -- See quote. shell_quote :: String -> String -- | Quote special characters inside a string for the shell -- -- This quotes special characters inside a string, such that it is -- recognized as one string by the shell when enclosed in double quotes. -- Doesn't add the double quotes. -- -- Note: The quoted strings are correctly recognized in shell scripts. -- But the shell bash has an annoying history expansion "feature", which -- causes it to choke on exclamation marks, when in interactive mode, -- even when quoted with double quotes. You can turn it off with set -- +o histexpand. -- -- See quote, shell_quote. quote0 :: String -> String -- | Quote a string for the shell -- -- This encloses a string in double quotes and quotes any special -- characters inside, such that it will be recognized as one string by a -- shell. The double quotes are added even when they aren't needed for -- this purpose. -- -- Note: The quoted strings are correctly recognized in shell scripts. -- But the shell bash has an annoying history expansion "feature", which -- causes it to choke on exclamation marks, when in interactive mode, -- even when quoted with double quotes. You can turn it off with set -- +o histexpand. -- -- See quote0, shell_quote. quote :: String -> String module HsShellScript.Paths -- | Split a path in components. Repeated "/" characters don't -- lead to empty components. "." path components are removed. If -- the path is absolute, the first component will start with -- "/". ".." components are left intact. They can't be -- simply removed, because the preceding component might be a symlink. In -- this case, realpath is probably what you need. -- -- The case that the path is empty is treated like ".", yielding -- an empty path components list. -- -- Examples: -- --
--   slice_path "/"        = ["/"]
--   slice_path "/foo/bar" = ["/foo","bar"]
--   slice_path "..//./"   = [".."]
--   slice_path "."        = []
--   slice_path ""         = []
--   
-- -- See unslice_path, realpath, realpath_s. slice_path :: String -> [String] -- | Form a path from path components. This isn't the inverse of -- slice_path, since unslice_path . -- slice_path normalises the path. -- --
--   unslice_path [] = "."
--   unslice_path cs = concat (intersperse "/" cs)
--   
-- -- See slice_path, unsplit_parts. unslice_path :: [String] -> String -- | Normalise a path. This is done by reducing repeated / -- characters to one, and removing . path components. -- .. path components are left intact, because of possible -- symlinks. -- -- Note that the normalised path isn't 100% equivalent to the original -- one. Any trailing slash is removed. When the last path component is a -- symbolic link, then both paths denote the same thing, except for in -- the context of the readlink call. It will fail when the -- trailing slash is present (because then the path denotes the directory -- which the link points to), but it will succeed when it is absent. -- --
--   normalise_path = unslice_path . slice_path
--   
-- -- See unslice_path, slice_path. normalise_path :: String -> String -- | Split a file name in components. This are the base file name and the -- suffixes, which are separated by dots. If the name starts with a dot, -- it is regarded as part of the base name. The result is a list of file -- name components. The filename may be a path. In this case, everything -- up to the last path component will be returned as part of the base -- file name. The path gets normalised thereby. -- -- No empty suffixes are returned. If the file name contains several -- consecutive dots, they are regared as part of the preceding file name -- component. -- -- Concateneting the name components and adding dots, reproduces the -- original name, with a normalised path: concat . intersperse "." . -- slice_filename == normalise. -- -- Note that the last path component might be "..". Then it is -- not possible to deduce the refered directory's name from the path. An -- IO action for getting the real path is then necessary. -- -- Examples: -- --
--   slice_filename "a.b//./.foo.tar.gz" = ["a.b/.foo","tar","gz"]
--   slice_filename ".x..y."             = [".x.", "y."]
--   
-- -- See unslice_filename, slice_filename'. slice_filename :: String -> [String] -- | This is a variant of slice_filename. It is like -- slice_filename, except for being more efficient, and the -- filename must not contain any preceding path, since this case isn't -- considered. -- -- See slice_filename, unslice_filename. slice_filename' :: String -> [String] -- | Form file name from file name components, interspersing dots. This is -- the inverse of slice_filename, except for normalisation of any -- path. -- --
--   unslice_filename = concat . intersperse "."
--   
-- -- See slice_filename. unslice_filename :: [String] -> String -- | Split a path in directory and file name. Only in the case that the -- supplied path is empty, both parts are empty strings. Otherwise, -- "." is filled in for the corresponding part, if necessary. -- Unless the path is empty, concatenating the returned path and file -- name components with a slash in between, makes a valid path to the -- file. -- -- split_path splits off the last path component. This isn't the -- same as the text after the last /. -- -- Note that the last path component might be "..". Then it is -- not possible to deduce the refered directory's name from the path. -- Then an IO action for getting the real path is necessary. -- -- Examples: -- --
--   split_path "/a/b/c"      == ("/a/b", "c")
--   split_path "foo"         == (".", "foo")
--   split_path "foo/bar"     == ("foo", "bar")
--   split_path "foo/.."      == ("foo", "..")
--   split_path "."           == (".", ".")
--   split_path ""            == ("", "")
--   split_path "/foo"        == ("/", "foo")
--   split_path "foo/"        == (".", "foo")
--   split_path "foo/."       == (".", "foo")
--   split_path "foo///./bar" == ("foo", "bar")
--   split_path "/"           == ("/", ".")
--   
-- -- See slice_path. split_path :: String -> (String, String) -- | Get the directory part of a path. -- --
--   dir_part = fst . split_path
--   
-- -- See split_path. dir_part :: String -> String -- | Get the last path component of a path. -- --
--   filename_part = snd . split_path
--   
-- -- Examples: -- --
--   filename_part "foo/bar" == "bar"
--   filename_part "."       == "."
--   
-- -- See split_path. filename_part :: String -> String -- | Inverse of split_path, except for normalisation. -- -- This forms a path from two parts, and takes care of "." and -- empty parts. When the two components are in normalised form, then -- unsplit_path creates a normalised path. -- -- The definition: -- --
--   unsplit_path ("", "") = ""
--   unsplit_path (p, q)   = unsplit_parts [p, q]
--   
-- -- Examples: -- --
--   unsplit_path ("", "")     == ""
--   unsplit_path (".", "")    == "."
--   unsplit_path (".", ".")   == "."
--   unsplit_path ("foo", ".") == "foo"
--   
-- -- See split_path, slice_path, unsplit_parts. unsplit_path :: (String, String) -> String -- | Concatenate a list of path parts. The idea is that you can throw in -- reasonably formed parts, and get a reasonably formed version of the -- concatenated path out. -- -- "." parts are removed. Empty parts are treated as -- "." parts. One leading slash in each of any but the first -- part is removed. The result is then interspersed with slashes and -- string wise concatenated. The interior of the parts isn't examined. -- ".." components aren't treated specially. -- -- Examples: -- --
--   unsplit_parts []                       == "."
--   unsplit_parts [""]                     == "."
--   unsplit_parts ["/"]                    == "/"
--   unsplit_parts ["/", "foo"]             == "/foo"
--   unsplit_parts ["", "/foo"]             == "foo"
--   unsplit_parts ["/foo", "bar"]          == "/foo/bar"
--   unsplit_parts ["/foo", "/bar"]         == "/foo/bar"
--   unsplit_parts ["foo/", "bar"]          == "foo//bar"
--   unsplit_parts ["foo", "", ".", "bar"]  == "foo/bar"
--   unsplit_parts ["foo", "bar//./baz/"]   == "foo/bar//./baz/"
--   
-- -- See unsplit_path, unslice_path, split_path. unsplit_parts :: [String] -> String -- | Split a file name in prefix and suffix. If there isn't any suffix in -- the file name, then return an empty suffix. A dot at the beginning or -- at the end is not regarded as introducing a suffix. -- -- The last path component is what is being split. This isn't the same as -- splitting the string at the last dot. For instance, if the file name -- doesn't contain any dot, dots in previous path component's aren't -- mistaken as introducing suffixes. -- -- The path part is returned in normalised form. This means, "." -- components are removed, and multiple "/"s are reduced to one. -- -- Note that there isn't any plausibility check performed on the suffix. -- If the file name doesn't have a suffix, but happens to contain a dot, -- then this dot is mistaken as introducing a suffix. -- -- Examples: -- --
--   split_filename "path/to/foo.bar"                             = ("path/to/foo","bar")
--   split_filename "path/to/foo"                                 = ("path/to/foo","")
--   split_filename "/path.to/foo"                                = ("/path.to/foo","")
--   split_filename "a///./x"                                     = ("a/x","")
--   split_filename "dir.suffix/./"                               = ("dir","suffix")
--   split_filename "Photographie, Das 20. Jahrhundert (300 dpi)" = ("Photographie, Das 20", " Jahrhundert (300 dpi)")
--   
-- -- See slice_path, 'split_filename\'' split_filename :: String -> (String, String) -- | Variant of split_filename. This is a more efficient version of -- split_filename, for the case that you know the string is is a -- pure file name without any slashes. -- -- See split_filename. split_filename' :: String -> (String, String) -- | Inverse of split_filename. Concatenate prefix and suffix, -- adding a dot in between, iff the suffix is not empty. The path part of -- the prefix is normalised. -- -- See split_filename. unsplit_filename :: (String, String) -> String -- | Split a path in directory, base file name and suffix. split3 :: String -> (String, String, String) -- | Form path from directory, base file name and suffix parts. unsplit3 :: (String, String, String) -> String -- | Test a path for a specific suffix and split it off. -- -- If the path ends with the suffix, then the result is Just -- prefix, where prefix is the normalised path without the -- suffix. Otherwise it's Nothing. test_suffix :: String -> String -> Maybe String -- | Make a path absolute, using the current working directory. -- -- This makes a relative path absolute with respect to the current -- working directory. An absolute path is returned unmodified. -- -- The current working directory is determined with -- getCurrentDirectory which means that symbolic links in it are -- expanded and the path is normalised. This is different from -- pwd. absolute_path :: String -> IO String -- | Make a path absolute. -- -- This makes a relative path absolute with respect to a specified -- directory. An absolute path is returned unmodified. absolute_path_by :: String -> String -> String -- | Make a path absolute. -- -- This makes a relative path absolute with respect to a specified -- directory. An absolute path is returned unmodified. -- -- The order of the arguments can be confusing. You should rather use -- absolute_path_by. absolute_path' is included for -- backwards compatibility. absolute_path' :: String -> String -> String -- | Guess the ".."-component free form of a path, specified as a -- list of path components, by syntactically removing them, along with -- the preceding path components. This will produce erroneous results -- when the path contains symlinks. If the path contains leading -- ".." components, or more ".." components than -- preceeding normal components, then the ".." components can't -- be normalised away. In this case, the result is Nothing. guess_dotdot_comps :: [String] -> Maybe [String] -- | Guess the ".."-component free, normalised form of a path. The -- transformation is purely syntactic. ".." path components will -- be removed, along with their preceding path components. This will -- produce erroneous results when the path contains symlinks. If the path -- contains leading ".." components, or more ".." -- components than preceeding normal components, then the ".." -- components can't be normalised away. In this case, the result is -- Nothing. -- --
--   guess_dotdot = fmap unslice_path . guess_dotdot_comps . slice_path
--   
guess_dotdot :: String -> Maybe String -- | This module provides a more convient way of parsing command line -- arguments than the GHC GetOpt package. It makes use of GetOpt, but -- hides it from the user. It is reexported from module HsShellScript. -- -- For each command line argument, a description is to be created with -- argdesc. Then the command line arguments are evaluated with -- one of the getargs... functions. In case of an error, this -- will cause a exception, which provides an expressive error message to -- be printed. Then the arg... functions are used to extract the -- values contained in the arguments, with the right type. The typical -- use of HsShellScript.Args looks something like this: -- --
--   import HsShellScript
--   
--   main =
--      do let a_onevalue = argdesc [ desc_at_most_once, ... ]
--             a_values   = argdesc [ desc_direct, ... ]
--             a_switch   = argdesc [ ... ]
--             ...
--             header = "mclapep - My Command Line Argument Parser Example Program, version 1.0.0"
--   
--         args <- getargs header [a_onevalue, a_values, a_switch, ...]
--   
--         val  <- optarg_req a_onevalue args        -- val  :: Maybe String
--         vals <- args_req   a_values args          -- vals :: [String]
--         doit <- arg_switch a_switch args          -- doit :: Bool
--         ...
--      `catch` 
--         (\argerror -> do
--             hPutStrLn stderr $ (argerror_message argerror) ++ "\n\n" ++ (argerror_usageinfo argerror)
--             exitFailure
--         )
--   
-- -- Errors in the argument descriptions are regarded as bugs, and handled -- by aborting the program with a message which is meaningful to the -- programmer. It is assumed that the argument description is a constant -- for a given program. -- -- Errors in the arguments are reported using HsShellScript's error -- handling scheme. An error description value is generated, and either -- returned via an Either value, or thrown as an exception. module HsShellScript.Args -- | A property of a command line argument. These are generated by the -- desc_... functions, and condensed to argument descriptions of -- type ArgumentDescription by argdesc. This type is -- abstract. data ArgumentProperty -- | Description of one command line argument. These are generated by -- argdesc from a list of argument properties, and subsequently -- used by one of the getargs... functions. This type is -- abstract. data ArgumentDescription ArgumentDescription :: [Char] -> [String] -> ArgumentValueSpec -> Maybe (Int, Int) -> Maybe String -> Maybe String -> Maybe Argtester -> ArgumentDescription -- | Short option names argdesc_short_args :: ArgumentDescription -> [Char] -- | Long option names argdesc_long_args :: ArgumentDescription -> [String] -- | What about a possible value of the argument? argdesc_argarg :: ArgumentDescription -> ArgumentValueSpec -- | Minimum and maximum of number of occurences allowed argdesc_times :: ArgumentDescription -> Maybe (Int, Int) -- | Name for argument's value, for message generation argdesc_argargname :: ArgumentDescription -> Maybe String -- | Descrition of the argument, for message generation argdesc_argarg_description :: ArgumentDescription -> Maybe String -- | Argument value tester argdesc_argarg_tester :: ArgumentDescription -> Maybe Argtester -- | Does the command line argument take an value? data ArgumentValueSpec -- | No value ArgumentValue_none :: ArgumentValueSpec -- | Value required ArgumentValue_required :: ArgumentValueSpec -- | Value optional ArgumentValue_optional :: ArgumentValueSpec -- | Argument value tester function. This tests the format of an argument's -- value for errors. The tester function is specified by -- desc_tester or such, as part of the argument description. -- -- The tester is passed the argument value. If the format is correct, -- then it returns Nothing. If there is an error, then it -- returns Just msgf, with msgf being an error message -- generation function. This function gets passed the argument -- description, and produces the error message. The argument description -- typically is used to extract a descriptive name of the argument (using -- argname or argname_a) to be included in the error -- message. type Argtester = String -> Maybe (ArgumentDescription -> String) -- | Make an argument description from a list of argument properties. This -- condenses the list to an argument description, which can be uses by -- the getargs... functions and the argument value extraction -- functions. argdesc :: [ArgumentProperty] -> ArgumentDescription -- | Short name of the argument. This specifies a character for a one -- letter style argument, like -x. There can be specified -- several for the same argument. Each argument needs at least either a -- short or a long name. desc_short :: Char -> ArgumentProperty -- | Long name of the argument. This specifies a GNU style long name for -- the argument, like --arg or --arg=.... There can be -- specified several names for the same argument. Each argument needs at -- least either a short or a long name. desc_long :: String -> ArgumentProperty -- | Signal that this is the description of direct arguments. Direct -- arguments are the ones not introduced by any short or long argument -- names (like -x or --arg), or which occur after the -- special argument --. The presence of desc_direct in -- the argument properties list signals argdesc that this is the -- description of the direct arguments. There may be at most one such -- description. desc_direct :: ArgumentProperty -- | Signal that the argument requires a value. desc_value_required :: ArgumentProperty -- | Signal that the argument optionally has a value. The user may or may -- not specify a value to this argument. desc_value_optional :: ArgumentProperty -- | Specify lower and upper bound on the number of times an argument may -- occur. desc_times :: Int -> Int -> ArgumentProperty -- | Signal that the argument must be present exactly once. This is -- meaningful only for arguments which can take a value. desc_once :: ArgumentProperty -- | Signal that the argument must occur at least one time. desc_at_least_once :: ArgumentProperty -- | Signal that the argument must occur at most one time. desc_at_most_once :: ArgumentProperty -- | Signal that the argument may occur any number of times. desc_any_times :: ArgumentProperty -- | Signal that the argument must have at least the specified number of -- occurences, and has no upper limit of occurences. desc_at_least :: Int -> ArgumentProperty -- | Signal that the argument does not need to be present, and may occur at -- most the specified number of times. desc_at_most :: Int -> ArgumentProperty -- | Specify the descriptive name for command line argument's value. Used -- for the generation of the usage message. The name should be very -- short. desc_argname :: String -> ArgumentProperty -- | Specify a short description of what the argument does. Used for the -- generation of the usage message. This is to fit on one line, after the -- short and long argument names. It should be 40 characters long or so. desc_description :: String -> ArgumentProperty -- | Specify a tester for this argument. The tester is a function which -- tests the argument value for format errors. Typically, it tests -- whether the value can be parsed to some target type. If the test -- fails, the tester produces an error message. When parsing the command -- line arguments (which getargs or related), all the testers -- are applied to the respective argument values, and an ArgError -- is thrown in case of failure. By using a tester, it can be ensured -- that the argument values abide a specific format when extracting them, -- such that they can be parsed without errors, e.g. myarg = read -- (reqarg_req args d_myarg). -- -- An argument tester is a function of type Argtester. -- -- See readtester, desc_integer, -- desc_nonneg_integer, Argtester. desc_tester :: Argtester -> ArgumentProperty -- | Specify that the value of this argument, if present, is a positive -- integer. This will cause an error when the command line is parsed, and -- the argument's value doesn't specify an integer. -- --
--   desc_integer = desc_tester (readtester (reads :: ReadS Int) "Integer expected.")
--   
-- -- See desc_tester. desc_integer :: ArgumentProperty -- | Specify that the value of this argument, if present, is a non-negative -- integer. This will cause an error when the command line is parsed, and -- the value doesn't specify a non-negative integer. -- --
--   desc_nonneg_integer = desc_tester (readtester ((filter (\(a,_) -> a >= 0) . reads) :: ReadS Int) "Non-negative integer expected." )
--   
-- -- See desc_tester. desc_nonneg_integer :: ArgumentProperty -- | Build an argument tester from a reads like function. -- Typically, a specialisation of the standard prelude function -- read is used. Example: readtester "Integer expected." -- (reads :: ReadS Int) readtester :: ReadS a -> String -> Argtester -- | This represents the parsed contents of the command line. It is -- returned by the getargs... functions, and passed on to the -- value extraction functions by the user. -- -- See getargs, getargs_ordered, 'getargs\'', -- 'getargs_ordered\''. data Arguments -- | Parse command line arguments. The arguments are taken from a call to -- getArgs and parsed. Any error is thrown as a -- ArgError exception. The result is a value from which the -- information in the command line can be extracted by the -- arg..., reqarg... and optarg... functions. -- -- Named arguments (like -x or --arg) and direct -- arguments may occur in any order. getargs :: String -> [ArgumentDescription] -> IO Arguments -- | Parse command line arguments. The arguments are taken from a call to -- getArgs and parsed. Any error is thrown as a -- ArgError exception. The result is a value from which the -- information in the command line can be extracted by the -- arg..., reqarg... and optarg... functions. -- -- All arguments after the first direct argument are regarded as direct -- arguments. This means that argument names introduced by - or -- -- no longer take effect. getargs_ordered :: String -> [ArgumentDescription] -> IO Arguments -- | Parse the specified command line. Any error is returned as Left -- argerror. In case of success, the result is returned as Right -- res. From the result, the information in the command line can be -- extracted by the arg..., reqarg... and -- optarg... functions. -- -- Named arguments (like -x or --arg) and direct -- arguments may occur in any order. getargs' :: String -> [String] -> [ArgumentDescription] -> Either ArgError Arguments -- | Parse the specified command line. Any error is returned as Left -- argerror. In case of success, the result is returned as Right -- res. From the result, the information in the command line can be -- extracted by the arg..., reqarg... and -- optarg... functions. -- -- All arguments after the first direct argument are regarded as direct -- arguments. This means that argument names introduced by - or -- -- no longer take effect. getargs_ordered' :: String -> [String] -> [ArgumentDescription] -> Either ArgError Arguments -- | getargs as a pure function, instead of an IO action. This -- allows to make evaluated command line arguments global values. This -- calls getargs to parse the command line arguments. -- GHC.IO.unsafePerformIO is used to take the result out of the -- IO monad. -- --
--   unsafe_getargs header descs = GHC.IO.unsafePerformIO $ getargs header descs
--   
-- -- The getargs action is performed on demand, when the parse -- result is evaluated. It may result in an ArgError being thrown. -- In order to avoid this happening at unexpected times, the -- main function should, start with the line seq args -- (return ()), where args is the result of -- unsafe_getargs,. This will trigger any command line argument -- errors at the beginning of the program. (See section 6.2 of the Hakell -- Report for the definition of seq). -- -- A typical use of unsafe_getargs looks like this: -- --
--   header = "..."
--   descs = [ d_myflag, ... ]
--   
--   d_myflag = argdesc [ ... ]
--   
--   args = unsafe_getargs header descs
--   myflag = arg_switch args d_myflag
--   
--   main = mainwrapper $ do
--      seq args (return ())
--      ...
--   
-- -- See getargs, unsafe_getargs_ordered. unsafe_getargs :: String -> [ArgumentDescription] -> Arguments -- | getargs_ordered as a pure function, instead of an IO action. -- This is exactly like unsafe_getargs, but using -- getargs_ordered instead of getargs. -- --
--   unsafe_getargs_ordered = GHC.IO.unsafePerformIO $ getargs_ordered header descs
--   
-- -- See unsafe_getargs. unsafe_getargs_ordered :: String -> [ArgumentDescription] -> Arguments -- | Query whether a certain switch is specified on the command line. A -- switch is an argument which is allowed zero or one time, and has no -- value. arg_switch :: Arguments -> ArgumentDescription -> Bool -- | Query the number of occurences of an argument. arg_times :: Arguments -> ArgumentDescription -> Int -- | Query the values of an argument with optional value. This is for -- arguments which take an optional value, and may occur several times. -- The occurences with value are represented as Just value, the -- occurences without are represented as Nothing. args_opt :: Arguments -> ArgumentDescription -> [Maybe String] -- | Query the values of an argument with required value. This is for -- arguments which require a value, and may occur several times. args_req :: Arguments -> ArgumentDescription -> [String] -- | Query the optional value of a required argument. This is for arguments -- which must occur once, and may have a value. If the argument is -- specified, its value is returned as Just value. If it isn't, -- the result is Nothing. reqarg_opt :: Arguments -> ArgumentDescription -> Maybe String -- | Query the value of a required argument. This is for arguments which -- must occur exactly once, and require a value. reqarg_req :: Arguments -> ArgumentDescription -> String -- | Query the optional value of an optional argument. This is for -- arguments which may occur zero or one time, and which may or may not -- have a value. If the argument doesn't occur, the result is -- Nothing. If it does occur, but has no value, then the result -- is Just Nothing. If it does occur with value, the result is -- Just (Just value). optarg_opt :: Arguments -> ArgumentDescription -> Maybe (Maybe String) -- | Query the value of an optional argument. This is for optional -- arguments which require a value, and may occur at most once. The -- result is Just value if the argument occurs, and -- Nothing if it doesn't occur. optarg_req :: Arguments -> ArgumentDescription -> Maybe String -- | Whether the specified argument occurs in the command line. arg_occurs :: Arguments -> ArgumentDescription -> Bool -- | None of the specifed arguments may be present. -- -- Throws an ArgError if any of the arguments are present. args_none :: [ArgumentDescription] -> Arguments -> IO () -- | All of the specified arguments must be present. -- -- Throws an ArgError if any is missing. args_all :: [ArgumentDescription] -> Arguments -> IO () -- | Exactly one of the specified arguments must be present. -- -- Otherwise throw an ArgError. args_one :: [ArgumentDescription] -> Arguments -> IO () -- | At most one of the specified arguments may be present. -- -- Otherwise throw an ArgError. args_at_most_one :: [ArgumentDescription] -> Arguments -> IO () -- | At least one of the specified arguments must be present. -- -- Otherwise throw an ArgError. args_at_least_one :: [ArgumentDescription] -> Arguments -> IO () -- | When the specified argument is present, then none of the other -- arguments may be present. -- -- Otherwise throw an ArgError. arg_conflicts :: ArgumentDescription -> [ArgumentDescription] -> Arguments -> IO () -- | Error thrown when there is an error in the command line arguments. data ArgError ArgError :: String -> String -> ArgError -- | Error message generated by HsShellScript.Args. argerror_message :: ArgError -> String -- | Usage information derived from the argument descriptions. argerror_usageinfo :: ArgError -> String -- | Get the usage information from the parsed arguments. The usage info -- contains the header specified to the corresponding getargs... -- function, and descriptions of the command line arguments. usage_info :: Arguments -> String -- | Generate a descriptive argument name from an argument description, -- suitable for use in error messages. This uses the long and short -- argument names (as specified by desc_short and -- desc_long) and generates descriptive names of the argument like -- "-f", "-myflag", "-f/--myflag", etc. All the argument names are -- included. In case of direct arguments (see desc_direct), the -- descriptive name is "(direct argument)". argname :: ArgumentDescription -> String -- | Generate a descriptive argument name from an argument description, -- beginning with "argument". This uses the long and short argument names -- (as specified by desc_short and desc_long) and generates -- descriptive names of the argument like "argument -f", "argument -- -myflag", "argument -f/--myflag", etc. All the argument names are -- included. In case of direct arguments (see desc_direct), the -- descriptive name is "direct argument". argname_a :: ArgumentDescription -> String instance Typeable ArgError instance Eq ArgumentValueSpec instance Show ArgumentValueSpec instance Ord ArgumentValueSpec instance Show ArgError instance Exception ArgError instance Ord ArgumentDescription instance Eq ArgumentDescription module HsShellScript.ProcErr -- | Improved version of System.Posix.Files.setFileMode, which -- sets the file name in the IOError which is thrown in case of -- an error. The implementation in GHC 6.2.2 neglects to do this. -- --
--   setFileMode' path mode =
--      fill_in_filename path $
--         setFileMode path mode
--   
setFileMode' :: FilePath -> FileMode -> IO () -- | Execute an IO action as a separate process, and wait for it to finish. -- Report errors as exceptions. -- -- This forks a child process, which performs the specified IO action. In -- case the child process has been stopped by a signal, the parent -- blocks. -- -- If the action throws an IOError, it is transmitted to the -- parent. It is then raised there, as if it happened locally. The child -- then aborts quietly with an exit code of 0. -- -- Exceptions in the child process, other than IOErrors, result -- in an error message on stderr, and a ProcessStatus -- exception in the parent, with the value of Exited (ExitFailure -- 1). The following exceptions are understood by subproc, -- and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- If the child process exits with an exit code other than zero, or it is -- terminated by a signal, the corresponding ProcessStatus is -- raised as an exception in the parent program. Only IOErrors -- are transmitted to the parent. -- -- When used in conjunction with an exec variant, this means -- that the parent process can tell the difference between failure of the -- exec call itself, and failure of the child program being -- executed after a successful call of the exec variant. In case -- of failure of the exec call, You get the IOError, -- which happened in the child when calling executeFile (from -- the GHC hierarchical libraries). In case of the called program -- failing, you get the ProcessStatus. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally (unless it throws an IOError). The child process is -- then properly terminated by subproc, such that no resources, -- which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- If you want to run an external program, by calling one of the -- exec variants in the child action, you might want to call -- runprog instead of subproc. -- -- Examples: -- -- Run a program with the environment replaced: -- --
--   subproc (execpe "foobar" ["1","2","3"] new_env)
--   
-- -- This results in a ProcessStatus exception: -- --
--   subproc (exec "/bin/false" [])
--   
-- -- This results in an IOError (unless you actually have -- /frooble): -- --
--   subproc (exec "/frooble" [])
--   
-- -- See runprog, spawn, exec, execp, -- exece, execpe. subproc :: IO a -> IO () -- | Execute an IO action as a separate process, and wait for it to finish. -- Report errors as exceptions. -- -- This function is included only for backwards compatibility. New -- code should use subproc instead, which has better -- error handling. -- -- The program forks a child process and performs the specified action. -- Then it waits for the child process to finish. If it exits in any way -- which indicates an error, the ProcessStatus is thrown. -- -- The parent process waits for the child processes, which have been -- stopped by a signal. -- -- See HsShellScript#subr for further details. -- -- See subproc, spawn. call :: IO a -> IO () -- | Execute an IO action as a separate process, and continue without -- waiting for it to finish. -- -- The program forks a child process, which performs the specified action -- and terminates. The child's process ID is returned. -- -- See HsShellScript#subr for further details. -- -- See subproc. spawn :: IO a -> IO ProcessID spawn_loc :: String -> IO a -> IO ProcessID -- | Run an external program. This starts a program as a child process, and -- waits for it to finish. The executable is searched via the -- PATH. -- -- This function is included for backwards compatibility only. New -- code should use runprog, which has much better -- error handling. -- -- When the specified program can't be executed, an error message is -- printed, and the main process gets a ProcessStatus thrown, -- with the value Exited (ExitFailure 1). This means that the -- main program can't distinguish between failure of calling the program -- and the program exiting with an exit code of 1. However, an error -- message "Error calling ...", including the description in the IOError -- produced by the failed execp call, is printed on -- stderr. -- -- run prog par is essentially call (execp prog par). -- -- Example: -- --
--   run "/usr/bin/foobar" ["some", "args"]
--      `catch` (\ps -> do -- oops...
--                 )
--   
-- -- See runprog, subproc, spawn. run :: FilePath -> [String] -> IO () -- | An error which occured when calling an external program. The fields -- specifiy the details of the call. -- -- See show_runerror, to_ioe, as_ioe, -- System.Posix.ProcessStatus. data RunError RunError :: String -> [String] -> [(String, String)] -> String -> ProcessStatus -> Maybe CInt -> RunError -- | Program name re_prog :: RunError -> String -- | Program arguments re_pars :: RunError -> [String] -- | The environment in use when the call was done re_env :: RunError -> [(String, String)] -- | The working directory when the call was done re_wd :: RunError -> String -- | The process status of the failure re_ps :: RunError -> ProcessStatus -- | The error (errno) code re_errno :: RunError -> Maybe CInt -- | Make a readable error message. This includes all the fields of -- RunError except for the environment. -- -- See RunError. show_runerror :: RunError -> String -- | Generate a human-readable description of a ProcessStatus. -- -- See exec, runprog and -- System.Posix.ProcessStatus in the GHC hierarchical library -- documentation. explain_processstatus :: ProcessStatus -> String -- | Convert a RunError to an IOError. -- -- The IOError type isn't capable of holding all the information -- which is contained in a RunError. The environment is left -- out, and most of the other fields are included only informally, in the -- description. -- -- The fields of the generated IOError are: -- -- -- -- See as_ioe, runprog, show_runerror. to_ioe :: RunError -> IOError -- | Call the specified IO action (which is expected to contain calls of -- runprog) and convert any RunError exceptions to -- IOErrors. -- -- The conversion is done by to_ioe. -- -- See to_ioe, runprog. as_ioe :: IO a -> IO a -- | Run an external program, and report errors as exceptions. The -- executable is searched via the PATH. In case the child -- process has been stopped by a signal, the parent blocks. -- -- In case the program exits in an way which indicates an error, or is -- terminated by a signal, a RunError is thrown. It contains the -- details of the call. The runprog action can also be converted -- to throw IOErrors instaed, by applying as_ioe to it. -- Either can be used to generate an informative error message. -- -- In case of starting the program itself failed, an IOError is -- thrown. -- -- runprog prog par is a simple front end to subproc. -- It is essentially subproc (execp prog par), apart from -- building a RunError from a ProcessStatus. -- -- Example 1: -- --
--   do runprog "foo" ["some", "args"]
--      ...
--   `catch` (\re -> do errm (show_runerror re)
--                         ...
--              )
--   
-- -- Example 2: -- --
--   do as_ioe $ runprog "foo" ["some", "args"]
--      ...
--   `catch` (\ioe -> do errm (show_ioerror ioe)
--                          ...
--              )
--   
-- -- See subproc, spawn, RunError, -- show_runerror, to_ioe, as_ioe. runprog :: FilePath -> [String] -> IO () -- | Print an action as a shell command, then perform it. -- -- This is used with actions such as runprog, exec or -- subproc. For instance, echo runprog prog args is a -- variant of runprog prog args, which prints what is being done -- before doing it. -- -- See runprog, subproc, exec. echo :: (FilePath -> [String] -> IO ()) -> FilePath -> [String] -> IO () -- | Execute an external program. This replaces the running process. The -- path isn't searched, the environment isn't changed. In case of -- failure, an IOError is thrown. -- --
--   exec path args =
--      execute_file path False args Nothing
--   
-- -- See execute_file, HsShellScript#exec. exec :: String -> [String] -> IO a -- | Execute an external program. This replaces the running process. The -- path is searched, the environment isn't changed. In case of failure, -- an IOError is thrown. -- --
--   execp prog args =
--      execute_file prog True args Nothing
--   
-- -- See execute_file, HsShellScript#exec. execp :: String -> [String] -> IO a -- | Execute an external program. This replaces the running process. The -- path isn't searched, the environment of the program is set as -- specified. In case of failure, an IOError is thrown. -- --
--   exece path args env =
--      execute_file path False args (Just env)
--   
-- -- See execute_file, HsShellScript#exec. exece :: String -> [String] -> [(String, String)] -> IO a -- | Execute an external program. This replaces the running process. The -- path is searched, the environment of the program is set as specified. -- In case of failure, an IOError is thrown. -- --
--   execpe prog args env =
--      execute_file prog True args (Just env)
--   
-- -- See execute_file, HsShellScript#exec. execpe :: String -> [String] -> [(String, String)] -> IO a -- | Build left handed pipe of stdout. -- -- "p -|- q" builds an IO action from the two IO actions -- p and q. q is executed in an external -- process. The standard output of p is sent to the standard -- input of q through a pipe. The result action consists of -- forking off q (connected with a pipe), and p. -- -- The result action does not run p in a separate -- process. So, the pipe itself can be seen as a modified action -- p, forking a connected q. The pipe is called "left -- handed", because p remains unforked, and not q. -- -- The exit code of q is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Examples: -- --
--   call (exec "/usr/bin/foo" [] -|- exec "/usr/bin/bar" [])
--   
-- --
--   call (    execp "foo" ["..."]
--         -|= ( -- Do something with foo's output
--               do cnt <- lazy_contents "-"
--                  ...
--             )
--        )
--   
-- -- See subproc, '(=|-)', '(-|=)'. (-|-) :: IO a -> IO b -> IO a -- | Build left handed pipe of stderr. -- -- "p =|- q" builds an IO action from the two IO actions -- p and q. q is executed in an external -- process. The standard error output of p is sent to the -- standard input of q through a pipe. The result action -- consists of forking off q (connected with a pipe), and -- p. -- -- The result action does not run p in a separate -- process. So, the pipe itself can be seen as a modified action -- p, forking a connected q. The pipe is called "left -- handed", because p has this property, and not q. -- -- The exit code of q is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   call (exec "/usr/bin/foo" [] =|- exec "/usr/bin/bar" [])
--   
-- -- See subproc, '(-|-)', '(-|=)'. (=|-) :: IO a -> IO b -> IO a -- | Build right handed pipe of stdout. -- -- "p -|= q" builds an IO action from the two IO actions -- p and q. p is executed in an external -- process. The standard output of p is sent to the standard -- input of q through a pipe. The result action consists of -- forking off p (connected with a pipe), and q. -- -- The result action does not run q in a separate -- process. So, the pipe itself can be seen as a modified action -- q, forking a connected p. The pipe is called "right -- handed", because q has this property, and not p. -- -- The exit code of p is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   @call (exec \"\/usr\/bin\/foo\" [] -|= exec \"\/usr\/bin\/bar\" [])@
--   
-- -- See subproc, '(=|-)', '(=|=)'. (-|=) :: IO a -> IO b -> IO b -- | Build right handed pipe of stderr. -- -- "p =|= q" builds an IO action from the two IO actions -- p and q. p is executed in an external -- process. The standard error output of p is sent to the -- standard input of q through a pipe. The result action -- consists of forking off p (connected with a pipe), and -- q. -- -- The result action does not run q in a separate -- process. So, the pipe itself can be seen as a modified action -- q, forking a connected p. The pipe is called "right -- handed", because q has this property, and not p. -- -- The exit code of p is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   call (exec "/usr/bin/foo" [] =|= exec "/usr/bin/bar" [])
--   
-- -- See subproc, =|-, -|=. (=|=) :: IO a -> IO b -> IO b -- | Temporarily replace a handle. This makes a backup copy of the original -- handle (typically a standard handle), overwrites it with the specified -- one, runs the specified action, and restores the handle from the -- backup. -- -- Example: -- --
--   h <- openFile "/tmp/log" WriteMode
--   redirect stdout h io
--   hClose h
--   
-- -- This is the same as -- --
--   io ->- "/tmp/log"
--   
-- -- See -|-, =|-. redirect :: Handle -> Handle -> IO a -> IO a redirect_helper :: Handle -> IOMode -> IO b -> FilePath -> IO b -- | Redirect the standard output of the specified IO action to a file. The -- file will be overwritten, if it already exists. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/program" [] ->- "/tmp/output"
--   
-- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use ->>- -- instead. -- -- See subproc, runprog, ->>-, =>-. (->-) :: IO a -> FilePath -> IO a -- | Redirect the standard output of the specified IO action to a file. If -- the file already exists, the output will be appended. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/noisy/program" [] ->>- "/dev/null"
--   
-- -- See subproc, runprog, '(->-)', '(=>>-)'. (->>-) :: IO a -> FilePath -> IO a -- | Redirect the standard error output of the specified IO action to a -- file. If the file already exists, it will be overwritten. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use =>>- -- instead. -- -- Example: -- --
--   run "/path/to/foo" [] =>- "/tmp/errlog"
--   
-- -- See subproc, runprog, '(->-)', '(=>>-)'. (=>-) :: IO a -> FilePath -> IO a -- | Redirect the standard error output of the specified IO action to a -- file. If the file already exists, the output will be appended. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/program" [] =>>- "/dev/null"
--   
-- -- See subproc, runprog, '(->>-)', '(=>-)'. (=>>-) :: IO a -> FilePath -> IO a -- | Redirect both stdout and stderr to a file. This is equivalent to the -- shell's &> operator. If the file already exists, it -- will be overwritten. -- -- What's actually modified are the stdout and stderr -- handles, not the file descriptors 1 and 2. The exec functions -- know about this. See HsShellScript#fdpipes and -- HsShellScript#exec for details. -- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use -&>>- -- instead. -- --
--   (-&>-) io path = err_to_out io ->- path
--   
-- -- Example: -- --
--   call (exec "/path/to/foo" [] -&>- "log")
--   
-- -- See '(-&>>-)', err_to_out. (-&>-) :: IO a -> FilePath -> IO a -- | Redirect both stdout and stderr to a file. If the file already exists, -- the output will be appended. -- -- What's actually modified are the stdout and stderr -- handles, not the file descriptors 1 and 2. The exec functions -- know about this. See HsShellScript#fdpipes and -- HsShellScript#exec for details. -- --
--   (-&>>-) io path = (err_to_out >> io) ->>- path
--   
-- -- Example: -- --
--   run "/some/noisy/program" [] -&>>- "/dev/null"
--   
-- -- See '(-&>-)', out_to_err. (-&>>-) :: IO a -> FilePath -> IO a -- | Redirect stdin from a file. This modifies the specified action, such -- that the standard input is read from a file. -- -- What's actually modified is the stdin handle, not the file -- descriptor 0. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   call (exec "/path/to/foo" [] -<- "bar")
--   
-- -- See exec, runprog, '(->-)', '(=>-)'. (-<-) :: IO a -> FilePath -> IO a -- | Send the error output of the specified action to its standard output. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- --
--   err_to_out = redirect stderr stdout
--   
-- -- See redirect. err_to_out :: IO a -> IO a -- | Send the output of the specified action to its standard error output. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- --
--   redirect stdout stderr
--   
-- -- See redirect. out_to_err :: IO a -> IO a pipe_fork_dup :: IO a -> Bool -> Bool -> Bool -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessID) -- | Run an IO action as a separate process, and pipe some text to its -- stdin. Then close the pipe and wait for the child process to -- finish. -- -- This forks a child process, which executes the specified action. The -- specified text is sent to the action's stdin through a pipe. -- Then the pipe is closed. In case the action replaces the process by -- calling an exec variant, it is made sure that the process -- gets the text on it's file descriptor 0. -- -- In case the action fails (exits with an exit status other than 0, or -- is terminated by a signal), the ProcessStatus is thrown, such -- as reported by getProcessStatus. No attempt is made to create -- more meaningful exceptions, like it is done by -- runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the termination of the child. The parent gets a -- ProcessStatus exception, with the value of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Example: -- --
--   pipe_to "blah" (exec "/usr/bin/foo" ["bar"])
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See subproc, runprog, -<-, h_pipe_to. pipe_to :: String -> IO a -> IO () -- | Run an IO action as a separate process, and get a connection (a pipe) -- to its stdin as a file handle. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stdin, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 0 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). If the child action throws an -- exception, an error message is printed on stderr, and the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- If the child process exits in a way which signals an error, the -- corresponding ProcessStatus is returned by -- getProcessStatus. See getProcessStatus for details. -- -- Example: -- --
--   (handle, pid) <- h_pipe_to $ exec "/usr/bin/foo" ["bar"]
--   hPutStrLn handle "Some text to go through the pipe"
--   (Just ps) <- getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- See -<-, pipe_to, pipe_from, -- pipe_from2. See HsShellScript#fdpipes for more details. h_pipe_to :: IO a -> IO (Handle, ProcessID) -- | Run an IO action as a separate process, and read its stdout -- strictly. Then wait for the child process to finish. This is like the -- backquote feature of shells. -- -- This forks a child process, which executes the specified action. The -- output of the child is read from its standard output. In case it -- replaces the process by calling an exec variant, it is make -- sure that the output is read from the new process' file descriptor 1. -- -- The end of the child's output is reached when either the standard -- output is closed, or the child process exits. The program blocks until -- the action exits, even if the child closes its standard output -- earlier. So the parent process always notices a failure of the action -- (when it exits in a way which indicates an error). -- -- When the child action exits in a way which indicates an error, the -- corresponding ProcessStatus is thrown. See -- getProcessStatus. No attempt is made to create more meaningful -- exceptions, like it is done by runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the proper termination of the child. The parent -- gets a ProcessStatus exception, with the value of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, pipe_from does not remove -- any trailing newline characters. The entire output of the action is -- returned. You might want to apply chomp to the result. -- -- Example: -- --
--   output <- pipe_from $ exec "/bin/mount" []
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See exec, pipe_to, pipe_from2, -- h_pipe_from, lazy_pipe_from, chomp, -- silently. pipe_from :: IO a -> IO String -- | Run an IO action as a separate process, and read its standard error -- output strictly. Then wait for the child process to finish. This is -- like the backquote feature of shells. This function is exactly the -- same as pipe_from, except that the standard error output is -- read, instead of the standard output. -- -- This forks a child process, which executes the specified action. The -- error output of the child is read from its standard error output. In -- case it replaces the process by calling an exec variant, it -- is made sure that the output is read from the new process' file -- descriptor 2. -- -- The end of the child's error output is reached when either the -- standard error output is closed, or the child process exits. The -- program blocks until the action exits, even if the child closes its -- standard error output earlier. So the parent process always notices a -- failure of the action (which means it exits in a way which indicates -- an error). -- -- When the child action exits in a way which indicates an error, the -- corresponding ProcessStatus is thrown. See -- getProcessStatus. No attempt is made to create more meaningful -- exceptions, like it is done by runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the proper termination of the child. This means -- that the error message is sent through the pipe, to the parent -- process. The message can be found in the text which has been read from -- the child process. It doesn't appear on the console. -- -- The parent gets a ProcessStatus exception, with the value of -- Exited (ExitFailure 1). The following exceptions are -- understood, and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, pipe_from2 does not remove -- any trailing newline characters. The entire error output of the action -- is returned. You might want to apply chomp to the result. -- -- Example: -- --
--   output <- pipe_from $ exec "/bin/mount" []
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See exec, pipe_to, pipe_from, -- h_pipe_from2, lazy_pipe_from2, silently. See -- HsShellScript#fdpipes for more details. pipe_from2 :: IO a -> IO String -- | Run an IO action as a separate process, and connect to its -- stdout with a file handle. This is like the backquote feature -- of shells. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stdout, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 1 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- When you call getProcessStatus blockingly, you must first -- ensure that all data has been read, or close the handle. Otherwise -- you'll get a deadlock. When you close the handle before all data has -- been read, then the child gets a SIGPIPE signal. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). No attempt is made to create more -- meaningful exceptions, like it is done by -- runprog/subproc. If the child action throws an -- exception, an error message is printed on stderr, and the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Example: -- --
--   (h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
--   
-- -- See exec, pipe_to, h_pipe_from2, -- pipe_from, lazy_pipe_from, chomp, -- silently. See HsShellScript#fdpipes for more details. h_pipe_from :: IO a -> IO (Handle, ProcessID) -- | Run an IO action as a separate process, and connect to its -- stderr with a file handle. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stderr, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 2 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- When you call getProcessStatus blockingly, you must first -- ensure that all data has been read, or close the handle. Otherwise -- you'll get a deadlock. When you close the handle before all data has -- been read, then the child gets a SIGPIPE signal. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). No attempt is made to create more -- meaningful exceptions, like it is done by -- runprog/subproc. If the child action throws an -- exception, an error message is printed on stderr. This means -- that the message goes through the pipe to the parent process. Then the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Example: -- --
--   (h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
--   
-- -- See exec, pipe_from, pipe_from2, -- h_pipe_from, pipe_to, lazy_pipe_from, -- chomp, silently. h_pipe_from2 :: IO a -> IO (Handle, ProcessID) -- | Run an IO action in a separate process, and read its standard output, -- The output is read lazily, as the returned string is evaluated. The -- child's output along with its process ID are returned. -- -- This forks a child process, which executes the specified action. The -- output of the child is read lazily through a pipe, which connncts to -- its standard output. In case the child replaces the process by calling -- an exec variant, it is make sure that the output is read from -- the new process' file descriptor 1. -- -- lazy_pipe_from calls hGetContents, in order to read -- the pipe lazily. This means that the file handle goes to semi-closed -- state. The handle holds a file descriptor, and as long as the string -- isn't fully evaluated, this file descriptor won't be closed. For the -- file descriptor to be closed, first its standard output needs to be -- closed on the child side. This happens when the child explicitly -- closes it, or the child process exits. When afterwards the string on -- the parent side is completely evaluated, the handle, along with the -- file descritor it holds, are closed and freed. -- -- If you use the string in such a way that you only access the beginning -- of the string, the handle will remain in semi-closed state, holding a -- file descriptor, even when the pipe is closed on the child side. When -- you do that repeatedly, you may run out of file descriptors. -- -- Unless you're sure that your program will reach the string's end, you -- should take care for it explicitly, by doing something like this: -- --
--   (output, pid) <- lazy_pipe_from (exec "\/usr\/bin\/foobar" [])
--   ...
--   seq (length output) (return ())   
--   
-- -- This will read the entire standard output of the child, even if it -- isn't needed. You can't cut the child process' output short, when you -- use lazy_pipe_from. If you need to do this, you should use -- h_pipe_from, which gives you the handle, which can then be -- closed by hClose, even if the child's output isn't completed: -- --
--   (h, pid) <- h_pipe_from io
--   
--   -- Lazily read io's output
--   output <- hGetContents h
--   ...
--   -- Not eveyting read yet, but cut io short.
--   hClose h   
--   
--   -- Wait for io to finish, and detect errors
--   (Just ps) <- System.Posix.getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- When you close the handle before all data has been read, then the -- child gets a SIGPIPE signal. -- -- After all the output has been read, you should call -- getProcessStatus on the child's process ID, in order to -- detect errors. Be aware that you must evaluate the whole string, -- before calling getProcessStatus blockingly, or you'll get a -- deadlock. -- -- You won't get an exception, if the child action exits in a way which -- indicates an error. Errors occur asynchronously, when the output -- string is evaluated. You must detect errors by yourself, by calling -- getProcessStatus. -- -- In case the action doesn't replace the child process with an external -- program, an exception may be thrown out of the action. This results in -- an error message on stderr, and the proper termination of the -- child. The ProcessStatus, which can be accessed in the parent -- process by getProcessStatus, is Exited (ExitFailure -- 1). The following exceptions are understood, and result in -- corresponding messages: ArgError, ProcessStatus, -- RunError, IOError and ExitCode. Other -- exceptions result in the generic message, as produced by -- show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, lazy_pipe_from does not -- remove any trailing newline characters. The entire output of the -- action is returned. You might want to apply chomp to the -- result. -- -- See exec, pipe_to, pipe_from, h_pipe_from, -- lazy_pipe_from2, silently. lazy_pipe_from :: IO a -> IO (String, ProcessID) -- | Run an IO action in a separate process, and read its standard error -- output, The output is read lazily, as the returned string is -- evaluated. The child's error output along with its process ID are -- returned. -- -- This forks a child process, which executes the specified action. The -- error output of the child is read lazily through a pipe, which -- connncts to its standard error output. In case the child replaces the -- process by calling an exec variant, it is make sure that the -- output is read from the new process' file descriptor 1. -- -- lazy_pipe_from calls hGetContents, in order to read -- the pipe lazily. This means that the file handle goes to semi-closed -- state. The handle holds a file descriptor, and as long as the string -- isn't fully evaluated, this file descriptor won't be closed. For the -- file descriptor to be closed, first its standard error output needs to -- be closed on the child side. This happens when the child explicitly -- closes it, or the child process exits. When afterwards the string on -- the parent side is completely evaluated, the handle, along with the -- file descritor it holds, are closed and freed. -- -- If you use the string in such a way that you only access the beginning -- of the string, the handle will remain in semi-closed state, holding a -- file descriptor, even when the pipe is closed on the child side. When -- you do that repeatedly, you may run out of file descriptors. -- -- Unless you're sure that your program will reach the string's end, you -- should take care for it explicitly, by doing something like this: -- --
--   (errmsg, pid) <- lazy_pipe_from2 (exec "/usr/bin/foobar" [])
--   ...
--   seq (length errmsg) (return ())   
--   
-- -- This will read the entire standard error output of the child, even if -- it isn't needed. You can't cut the child process' output short, when -- you use lazy_pipe_from. If you need to do this, you should -- use h_pipe_from, which gives you the handle, which can then -- be closed by hClose, even if the child's output isn't -- completed: -- --
--   (h, pid) <- h_pipe_from io
--   
--   -- Lazily read io's output
--   output <- hGetContents h
--   ...
--   -- Not eveyting read yet, but cut io short.
--   hClose h   
--   
--   -- Wait for io to finish, and detect errors
--   (Just ps) <- System.Posix.getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- When you close the handle before all data has been read, then the -- child gets a SIGPIPE signal. -- -- After all the output has been read, you should call -- getProcessStatus on the child's process ID, in order to -- detect errors. Be aware that you must evaluate the whole string, -- before calling getProcessStatus blockingly, or you'll get a -- deadlock. -- -- You won't get an exception, if the child action exits in a way which -- indicates an error. Errors occur asynchronously, when the output -- string is evaluated. You must detect errors by yourself, by calling -- getProcessStatus. -- -- In case the action doesn't replace the child process with an external -- program, an exception may be thrown out of the action. This results in -- an error message on stderr. This means that the message is -- sent through the pipe, to the parent process. Then the child process -- is properly terminated. The ProcessStatus, which can be -- accessed in the parent process by getProcessStatus, is -- Exited (ExitFailure 1). The following exceptions are -- understood, and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, lazy_pipe_from does not -- remove any trailing newline characters. The entire output of the -- action is returned. You might want to apply chomp to the -- result. -- -- See exec, pipe_to, pipe_from2, -- h_pipe_from2, lazy_pipe_from, silently. lazy_pipe_from2 :: IO a -> IO (String, ProcessID) -- | Run an IO action as a separate process, and optionally connect to its -- stdin, its stdout and its stderr output -- with pipes. -- -- See pipe_from, pipe_from2, pipe_to. pipes :: IO a -> Bool -> Bool -> Bool -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessID) -- | Forcibly terminate the program, circumventing normal program shutdown. -- -- This is the _exit(2) system call. No cleanup actions -- installed with bracket are performed, no data buffered by -- file handles is written out, etc. _exit :: Int -> IO a -- | Generate an error message from an errno value. This is the -- POSIX strerror system library function. -- -- See the man page strerror(3). strerror :: Errno -> IO String -- | Read the global system error number. This is the POSIX errno -- value. This function is redundant. Use -- Foreign.C.Error.getErrno instead. errno :: IO Errno -- | Print error message corresponding to the specified errno -- error number. This is similar to the POSIX system library function -- perror. -- -- See the man page perror(3). perror' :: Errno -> String -> IO () -- | Print error message corresponding to the global errno error -- number. This is the same as the POSIX system library function -- perror. -- -- See the man page perror(3). perror :: String -> IO () -- | Print a message to stderr and exit with an exit code -- indicating an error. -- --
--   failIO msg = hPutStrLn stderr msg >> exitFailure
--   
failIO :: String -> IO a -- | Modify an IO action to return the exit code of a failed program call, -- instead of throwing an exception. -- -- This is used to modify the error reporting behaviour of an IO action -- which uses 'run'/'runprog' or 'call'/'subproc'. When an external -- program exits with an exit code which indicates an error, normally an -- exception is thrown. After exitcode has been applied, the -- exit code is retruned instead. -- -- The caught exceptions are RunError and ProcessStatus. -- Termination by a signal is still reported by an exception, which is -- passed through. -- -- Example: ec <- exitcode $ runprog "foo" ["bar"] -- -- See runprog, subproc, run, call. exitcode :: IO () -> IO ExitCode -- | Create and throw an IOError from the current errno -- value, an optional handle and an optional file name. -- -- This is an extended version of the Foreign.C.Error.throwErrno -- function from the GHC libraries, which additionally allows to specify -- a handle and a file name to include in the IOError thrown. -- -- See Foreign.C.Error.throwErrno, -- Foreign.C.Error.errnoToIOError. throwErrno' :: String -> Maybe Handle -> Maybe FilePath -> IO a -- | Convert an IOError to a string. -- -- There is an instance declaration of IOError in Show -- in the GHC.IO library, but show_ioerror produces a -- more readable, and more complete, message. show_ioerror :: IOError -> String -- | Call the shell to execute a command. In case of an error, throw the -- ProcessStatus (such as (Exited (ExitFailure ec))) as -- an exception. This is like the Haskell standard library function -- system, except that error handling is brought in accordance -- with HsShellScript's scheme. -- -- exitcode . system_throw is the same as the system -- function, except that when the called shell is terminated or stopped -- by a signal, this still lead to the ProcessStatus being -- thrown. The Haskell library report says nothing about what happens in -- this case, when using the system function. -- --
--   system_throw cmd = run "/bin/sh" ["-c", "--", cmd]
--   
-- -- This function is deprecated. You should rather use -- system_runprog, which provides for much better error reporting. system_throw :: String -> IO () -- | Call the shell to execute a command. In case of an error, a -- RunError ist thrown. This is like the Haskell standard -- library function system, except that error handling is -- brought in accordance with HsShellScript's scheme. (It is not a -- front end to system.) -- --
--   system_runprog cmd = runprog "/bin/sh" ["-c", "--", cmd]
--   
-- -- Example: Call "foo" and report Errors as IOErrors, rather -- than RunErrors. -- --
--   as_ioe $ system_runprog "foo" ["bar", "baz"]
--   
-- -- See RunError, as_ioe system_runprog :: String -> IO () -- | Run a subroutine as a child process, but don't let it produce any -- messages. Read its stdout and stderr instead, and -- append it to the contents of a mutable variable. The idea is that you -- can run some commands silently, and report them and their messages to -- the user only when something goes wrong. -- -- If the child process terminates in a way which indicates an error, -- then the process status is thrown, in the same way as runprog -- does. If the subroutine throws an (Exited ec) exception (of -- type ProcessStatus), such as thrown by runprog, then -- the child process exits with the same exit code, such that the parent -- process reports it to the caller, again as a ProcessStatus -- exception. -- -- When the subroutine finishes, the child process is terminated with -- _exit 0. When it throws an exception, an error message -- is printed and it is terminated with _exit 1. See -- HsShellScript#subr for details. -- -- The standard output (and the standard error output) of the parent -- process are flushed before the fork, such that no output appears -- twice. -- -- Example: -- --
--   let handler :: IORef String -> ProcessStatus -> IO ()
--       handler msgref ps = do hPutStrLn stderr ("Command failed with " ++ show ps ++ ". Actions so far: ")
--                              msg <- readIORef msgref
--                              hPutStrLn stderr msg
--                              exitWith (ExitFailure 1)
--   
--   msgref <- newIORef ""
--   do silently msgref $ do putStrLn "Now doing foobar:"
--                           echo exec "/foo/bar" ["arguments"]
--      silently msgref $ echo exec "/bar/baz" ["arguments"]
--   `catch` (handler msgref)
--   
-- -- See lazy_pipe_from, subproc, runprog, Data.IORef. silently :: IORef String -> IO () -> IO () -- | Modify a subroutine action in order to make it suitable to run as a -- child process. -- -- This is used by functions like call, silently, -- pipe_to etc. The action is executed. When it returns, the -- (child) process is terminated with _exit 0 (after -- flushing stdout), circumventing normal program shutdown. When -- it throws an exception, an error message is printed and the (child) -- process is terminated with _exit 1. child :: IO a -> IO b -- | Print text to stdout. -- -- This is a shorthand for putStrLn, except for stderr -- being flushed beforehand. This way normal output and error output -- appear in order, even when they aren't buffered as by default. -- -- An additional newline is printed at the end. -- --
--   outm msg = do
--      hFlush stderr
--      putStrLn msg
--   
outm :: String -> IO () -- | Print text to stdout. -- -- This is a shorthand for putStr, except for stderr -- being flushed beforehand. This way normal output and error output -- appear in order, even when they aren't buffered as by default. -- -- No newline is printed at the end. -- --
--   outm_ msg = do
--      hFlush stderr
--      putStr msg
--   
outm_ :: String -> IO () -- | Colorful log message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in cyan. Additionally, a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm_, errm, errm_. logm :: String -> IO () -- | Colorful log message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in cyan. No a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, errm, errm_. logm_ :: String -> IO () -- | Colorful error message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in red. Additionally, a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, logm_, errm_. errm :: String -> IO () -- | Colorful error message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in red. No a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, logm_, errm. errm_ :: String -> IO () -- | In case the specified action throws an IOError, fill in its filename -- field. This way, more useful error messages can be produced. -- -- Example: -- --
--   -- Oh, the GHC libraries neglect to fill in the file name
--   executeFile' prog a b c =
--      fill_in_filename prog $ executeFile prog a b c
--   
-- -- See fill_in_location, add_location. fill_in_filename :: String -> IO a -> IO a -- | In case the specified action throws an IOError, fill in its location -- field. This way, more useful error messages can be produced. -- -- Example: -- --
--   my_fun a b c = do
--      -- ...
--      fill_in_location "my_fun" $  -- Give the caller a more useful location information in case of failure
--         rename "foo" "bar"
--      -- ...
--   
-- -- See fill_in_filename. fill_in_location :: String -> IO a -> IO a -- | In case the specified action throws an IOError, add a line to its -- location field. This way, more useful error messages can be produced. -- The specified string is prepended to the old location, separating it -- with a newline from the previous location, if any. When using this -- thoroughly, you get a reverse call stack in IOErrors. -- -- Example: -- --
--   my_fun =
--      add_location "my_fun" $ do
--         -- ...
--   
-- -- See fill_in_filename, fill_in_location. add_location :: String -> IO a -> IO a -- | This is a replacement for System.Posix.Process.executeFile. -- It does additional preparations, then calls executeFile. -- executeFile can't normally be used directly, -- because it doesn't do the things which are outlined here. -- -- This are the differences to executeFile: -- --
    --
  1. stdout and stderr are flushed.
  2. --
  3. The standard file descriptors 0-2 are made copies of the file -- descriptors which the standard handles currently use. This is -- necessary because they might no longer use the standard handles. See -- HsShellScript#fdpipes.
  4. --
-- -- If the standard handles stdin, stdout, -- stderr aren't in closed state, and they aren't already -- connected to the respective standard file descriptors, their file -- descriptors are copied to the respective standard file descriptors -- (with dup2). Backup copies are made of the file descriptors -- which are overwritten. If some of the standard handles are closed, the -- corresponding standard file descriptors are closed as well. -- --
    --
  1. All file descriptors, except for the standard ones, are set to -- close-on-exec (see fcntl(2)), and will be closed on -- successful replacement of the process. Before that, the old file -- descriptor flags are saved.
  2. --
  3. The standard file descriptors are set to blocking mode, since GHC -- 6.2.2 sets file descriptors to non-blocking (except 0-2, which may get -- overwritten by a non-blocking one in step 2). The called program -- doesn't expect that.
  4. --
  5. In case replacing the process fails, the file descriptors are -- reset to the original state. The file descriptors flags are restored, -- and the file descriptors 0-2 are overwritten again, with their backup -- copies. Then an IOError is thrown.
  6. --
  7. In any IOError, the program is filled in as the file name -- (executeFile neglects this).
  8. --
  9. The return type is a generic a, rather than -- ().
  10. --
-- -- Also see HsShellScript#exec. execute_file :: FilePath -> Bool -> [String] -> Maybe [(String, String)] -> IO a unsafeWithHandleFd :: Handle -> (Fd -> IO a) -> IO a unsafeWithHandleFd' :: Handle -> MVar Handle__ -> (Fd -> IO a) -> IO a -- | Check if a handle is connected to a terminal. -- -- This is a front end to the isatty(3) function (see man page). -- It is useful, for instance, to determine if color escape sequences -- should be generated. isatty :: Handle -> IO Bool flush_outerr :: IO () tyCon_ProcessStatus :: TypeRep receive_ioerror :: Fd -> IO (Maybe IOError) send_ioerror :: Fd -> IOError -> IO () encode_ioerror :: IOError -> String decode_ioerror :: String -> Maybe IOError ioe_types :: [(IOErrorType, Integer)] ioetype_num :: IOError -> Integer num_ioetype :: Integer -> IOErrorType c_close_on_exec :: CInt -> (IO CInt) _exit_prim :: CInt -> (IO ()) foreign_strerror :: CInt -> (Ptr CChar) c_save_fdflags :: IO (Ptr CInt) c_prepare_fd_flags_for_exec :: IO () c_restore_fdflags :: (Ptr CInt) -> (IO ()) c_fcntl_dupfd :: CInt -> (CInt -> (IO CInt)) close :: CInt -> (IO CInt) dup2 :: CInt -> (CInt -> (IO CInt)) hssh_c_isatty :: CInt -> (IO CInt) instance Typeable RunError instance Show RunError instance Eq RunError instance Exception ProcessStatus instance Show Errno instance Typeable ProcessStatus instance Exception RunError module HsShellScript.Misc -- | Format an Int with leading zeros. If the string -- representation of the Inŧ is longer than the number of -- characters to fill up, this produces as many characters as needed. zeros :: Int -> Int -> String -- | Remove trailing newlines. This is silimar to perl's chomp -- procedure. chomp :: String -> String -- | Get contents of a file or of stdin. This is a simple frontend -- to hGetContents. A file name of "-" designates -- stdin. The contents are read lazily as the string is evaluated. -- -- (The handle which we read from will be in semi-closed state. Once all -- input has read, it is closed automatically (Haskell Library Report -- 11.2.1). Therefore we don't need to return it). -- --
--   lazy_contents path = do
--       h   <- if path == "-" then return stdin else openFile path ReadMode
--       hGetContents h
--   
lazy_contents :: String -> IO String -- | Get contents of a file or of stdin eagerly. This is the same -- as lazy_contents, except for the contents being read -- immediately. contents :: String -> IO String -- | Test for the existence of a path. This is the disjunction of -- Directory.doesDirectoryExist and -- Directory.doesFileExist. For an dangling symlink, this will -- return False. path_exists :: String -> IO Bool -- | Test for the existence of a path. This uses -- System.Posix.Files.getFileStatus to determine whether the -- path exists in any form in the file system. For a dangling symlink, -- the result is True. path_exists' :: String -> IO Bool -- | Test if path points to a directory. This will return True for -- a symlink pointing to a directory. It's a shortcut for -- Directory.doesDirectoryExist. is_dir :: String -> IO Bool -- | Test if path points to a file. This is a shortcut for -- Directory.doesFileExist. is_file :: String -> IO Bool -- | This is the System.Posix.Files.getFileStatus function from -- the GHC libraries, with improved error reporting. The GHC function -- doesn't include the file name in the IOError when the call -- fails, making error messages much less useful. getFileStatus' -- rectifies this. -- -- See getFileStatus. getFileStatus' :: FilePath -> IO FileStatus -- | This is the System.Posix.Files.fileAccess function from the -- GHC libraries, with improved error reporting. The GHC function doesn't -- include the file name in the IOError when the call fails, -- making error messages much less useful. fileAccess' rectifies -- this. -- -- See fileAccess. fileAccess' :: FilePath -> Bool -> Bool -> Bool -> IO Bool -- | Create a temporary file. This will create a new, empty file, with a -- path which did not previously exist in the file system. The path -- consists of the specified prefix, a sequence of random characters -- (digits and letters), and the specified suffix. The file is created -- with read-write permissions for the user, and no permissons for the -- group and others. The ownership is set to the effective user ID of the -- process. The group ownership is set either to the effective group ID -- of the process or to the group ID of the parent directory (depending -- on filesystem type and mount options on Linux - see open(2) -- for details). -- -- See tmp_file, temp_dir, with_temp_file. temp_file :: Int -> String -> String -> IO FilePath -- | Create a temporary directory. This will create a new directory, with a -- path which did not previously exist in the file system. The path -- consists of the specified prefix, a sequence of random characters -- (digits and letters), and the specified suffix. The directory is -- normally created with read-write-execute permissions for the user, and -- no permissons for the group and others. But this may be further -- restricted by the process's umask in the usual way. -- -- The newly created directory will be owned by the effective uid of the -- process. If the directory containing the it has the set group id bit -- set, or if the filesystem is mounted with BSD group semantics, the new -- directory will inherit the group ownership from its parent; otherwise -- it will be owned by the effective gid of the process. (See -- mkdir(2)) -- -- See tmp_dir, temp_file, with_temp_dir. temp_dir :: Int -> String -> String -> IO FilePath -- | Create a temporary file. This will create a new, empty file, with -- read-write permissions for the user, and no permissons for the group -- and others. The path consists of the specified prefix, a dot, and six -- random characters (digits and letters). -- --
--   tmp_file prefix = temp_file 6 (prefix ++ ".") ""
--   
-- -- See temp_file, tmp_dir, with_tmp_file. tmp_file :: String -> IO FilePath -- | Create a temporary directory. This will create a new directory, with -- read-write-execute permissions for the user (unless further restricted -- by the process's umask), and no permissons for the group and others. -- The path consists of the specified prefix, a dot, and six random -- characters (digits and letters). -- --
--   tmp_dir prefix = temp_dir 6 (prefix ++ ".") ""
--   
-- -- See temp_dir, tmp_file, with_tmp_dir. tmp_dir :: String -> IO FilePath -- | Create and open a temporary file, perform some action with it, and -- delete it afterwards. This is a front end to the temp_file -- function. The file and its path are created in the same way. The IO -- action is passed a handle of the new file. When it finishes - normally -- or with an exception - the file is deleted. -- -- See temp_file, with_tmp_file, with_temp_dir. with_temp_file :: Int -> String -> String -> (Handle -> IO a) -> IO a -- | Create a temporary directory, perform some action with it, and delete -- it afterwards. This is a front end to the temp_dir function. -- The directory and its path are created in the same way. The IO action -- is passed the path of the new directory. When it finishes - normally -- or with an exception - the directory is deleted. -- -- The action must clean up any files it creates inside the directory by -- itself. with_temp_dir doesn't delete any files inside, so the -- directory could be removed. If the directory isn't empty, an -- IOError results (with the path filled in). When the action -- throws an exception, and the temporary directory cannot be removed, -- then the exception is passed through, rather than replacing it with -- the IOError. (This is because it's probably exactly because of that -- exception that the directory isn't empty and can't be removed). -- -- See temp_dir, with_tmp_dir, with_temp_file. with_temp_dir :: Int -> String -> String -> (FilePath -> IO a) -> IO a -- | Create and open a temporary file, perform some action with it, and -- delete it afterwards. This is a front end to the tmp_file -- function. The file and its path are created in the same way. The IO -- action is passed a handle of the new file. When it finishes - normally -- or with an exception - the file is deleted. -- -- See tmp_file, with_temp_file, with_tmp_dir. with_tmp_file :: String -> (Handle -> IO a) -> IO a -- | Create a temporary directory, perform some action with it, and delete -- it afterwards. This is a front end to the tmp_dir function. The -- directory and its path are created in the same way. The IO action is -- passed the path of the new directory. When it finishes - normally or -- with an exception - the directory is deleted. -- -- The action must clean up any files it creates inside the directory by -- itself. with_temp_dir doesn't delete any files inside, so the -- directory could be removed. If the directory isn't empty, an -- IOError results (with the path filled in). When the action -- throws an exception, and the temporary directory cannot be removed, -- then the exception is passed through, rather than replacing it with -- the IOError. (This is because it's probably exactly because of that -- exception that the directory isn't empty and can't be removed). -- --
--   with_tmp_dir prefix io = with_temp_dir 6 (prefix ++ ".") "" io
--   
-- -- See tmp_dir, with_temp_dir, with_tmp_file. with_tmp_dir :: String -> (FilePath -> IO a) -> IO a -- | Create a temporary path. This will generate a path which does not yet -- exist in the file system. It consists of the specified prefix, a -- sequence of random characters (digits and letters), and the specified -- suffix. -- -- Avoid relying on the generated path not to exist in the file -- system. Or else you'll get a potential race condition, since some -- other process might create the path after temp_path, before -- you use it. This is a security risk. The global random number -- generator (Random.randomRIO) is used to generate the random -- characters. These might not be that random after all, and could -- potentially be guessed. Rather use temp_file or -- temp_dir. -- -- See temp_file, temp_dir. temp_path :: Int -> String -> String -> IO FilePath untilIO :: Monad m => m b -> (b -> m Bool) -> m b -- | One entry of mount information. This is the same as struct -- mntent from <mntent.h>. A list of these is -- returned by the functions which read mount information. -- -- See read_mounts, read_mtab, read_fstab. data Mntent Mntent :: String -> String -> String -> String -> Int -> Int -> Mntent -- | Device file ("name of mounted file system") mnt_fsname :: Mntent -> String -- | Mount point mnt_dir :: Mntent -> String -- | Which kind of file system ("see mntent.h") mnt_type :: Mntent -> String -- | Mount options ("see mntent.h") mnt_opts :: Mntent -> String -- | Dump frequency in days mnt_freq :: Mntent -> Int -- | "Pass number on parallel fsck" mnt_passno :: Mntent -> Int -- | Read mount information. This is a front end to the -- setmntent(3), getmntent(3), endmntent(3) -- system library functions. -- -- When the setmntent call fails, the errno value is -- converted to an IOError and thrown. -- -- See read_mtab, read_fstab. read_mounts :: String -> IO [Mntent] -- | Get the currently mounted file systems. -- --
--   read_mtab = read_mounts "/etc/mtab"
--   
-- -- See read_mounts. read_mtab :: IO [Mntent] -- | Get the system wide file system table. -- --
--   read_fstab = read_mounts "/etc/fstab"
--   
-- -- See read_mounts. read_fstab :: IO [Mntent] o_CREAT :: CInt o_EXCL :: CInt -- | Change the working directory temporarily. This executes the specified -- IO action with a new working directory, and restores it afterwards -- (exception-safely). with_wd :: FilePath -> IO a -> IO a -- | This is an interface to the POSIX glob function, which does -- wildcard expansion in paths. The list of matched paths is returned. -- It's empty for no match (rather than the original pattern). In case -- anything goes wrong (such as permission denied), an IOError is thrown. -- -- This does not do tilde expansion, which is done (among many -- unwanted other things) by wordexp. The only flag used for the -- call to glob is GLOB_ERR. -- -- The behaviour in case of non-existing path components is inconsistent -- in the GNU version of the underlying glob function. glob -- /doesnt_exist/foo will return the empty list, whereas -- glob /doesnt_exist/* causes a No such file or -- directory IOError. -- -- See man pages glob(3) and wordexp(3). glob :: String -> IO [String] hsshellscript_open_nonvariadic :: (Ptr CChar) -> (CInt -> (CUInt -> (IO CInt))) c_close :: CInt -> (IO CInt) c_mkdir :: (Ptr CChar) -> (CUInt -> (IO CInt)) setmntent :: (Ptr CChar) -> ((Ptr CChar) -> (IO (Ptr ()))) endmntent :: (Ptr ()) -> (IO CInt) c_getmntent :: (Ptr ()) -> (IO (Ptr ())) do_glob :: (Ptr ()) -> ((Ptr CChar) -> (IO CInt)) globfree :: (Ptr ()) -> (IO ()) instance Typeable Mntent instance Read Mntent instance Show Mntent instance Eq Mntent module HsShellScript.Commands -- | Do a call to the realpath(3) system library function. This -- makes the path absolute, normalizes it and expands all symbolic links. -- In case of an error, an IOError is thrown. realpath :: String -> IO String -- | Determine the target of a symbolic link. This uses the -- readlink(2) system call. The result is a path which is either -- absolute, or relative to the directory which the symlink is in. In -- case of an error, an IOError is thrown. The path is included -- and can be accessed with IO.ioeGetFileName. Note that, if the -- path to the symlink ends with a slash, this path denotes the directory -- pointed to, not the symlink. In this case the call to will fail -- because of "Invalid argument". readlink :: String -> IO String -- | Determine the target of a symbolic link. This uses the -- readlink(2) system call. The target is converted, such that -- it is relative to the current working directory, if it isn't absolute. -- Note that, if the path to the symlink ends with a slash, this path -- denotes the directory pointed to, not the symlink. In this case -- the call to readlink will fail with an IOError -- because of "Invalid argument". In case of any error, a proper -- IOError is thrown. readlink' :: String -> IO String -- | Determine whether a path is a symbolic link. The result for a dangling -- symlink is True. The path must exist in the file system. In -- case of an error, a proper IOError is thrown. is_symlink :: String -> IO Bool -- | Return the normalised, absolute version of a specified path. The path -- is made absolute with the current working directory, and is -- syntactically normalised afterwards. This is the same as what the -- realpath program reports with the -s option. It's -- almost the same as what it reports when called from a shell. The -- difference lies in the shell's idea of the current working directory. -- See cd for details. -- -- See cd, normalise_path. realpath_s :: String -> IO String -- | Make a symbolic link. This is the symlink(2) function. Any -- error results in an IOError thrown. The path of the intended -- symlink is included in the IOError and can be accessed with -- ioeGetFileName from the Haskell standard library IO. symlink :: String -> String -> IO () -- | Call the du program. See du(1). du :: (Integral int, Read int, Show int) => int -> String -> IO int -- | Create directory. This is a shorthand to -- System.Directory.createDirectory from the Haskell standard -- library. In case of an error, the path is included in the -- IOError, which GHC's implementation neglects to do. mkdir :: String -> IO () -- | Remove directory. This is Directory.removeDirectory from the -- Haskell standard library. In case of an error, the path is included in -- the IOError, which GHC's implementation neglects to do. rmdir :: String -> IO () -- | Remove file. This is Directory.removeFile from the Haskell -- standard library, which is a direct frontend to the unlink(2) -- system call in GHC. rm :: String -> IO () -- | Change directory. This is an alias for -- Directory.setCurrentDirectory from the Haskell standard -- library. In case of an error, the path is included in the -- IOError, which GHC's implementation neglects to do. -- -- Note that this command is subtly different from the shell's -- cd command. It changes the process' working directory. This -- is always a realpath. Symlinks are expanded. The shell, on the other -- hand, keeps track of the current working directory separately, in a -- different way: symlinks are not expanded. The shell's idea of -- the working directory is different from the working directory which a -- process has. -- -- This means that the same sequence of cd commands, when done -- in a real shell script, will lead into the same directory. But the -- working directory as reported by the shell's pwd command may -- differ from the corresponding one, reported by -- getCurrentDirectory. -- -- (When talking about the "shell", I'm talking about bash, regardless of -- whether started as /bin/bash or in compatibility mode, as -- /bin/sh. I presume it's the standard behavior for the POSIX -- standard shell.) -- -- See pwd. cd :: String -> IO () -- | Get program start working directory. This is the PWD -- environent variable, which is kept by the shell (bash, at least). It -- records the directory path in which the program has been started. -- Symbolic links in this path aren't expanded. In this way, it differs -- from getCurrentDirectory from the Haskell standard library. pwd :: IO String -- | Execute /bin/chmod -- --
--   chmod = run "/bin/chmod"
--   
chmod :: [String] -> IO () -- | Execute /bin/chown -- --
--   chown = run "/bin/chown"
--   
chown :: [String] -> IO () -- | Execute the cp program cp :: String -> String -> IO () -- | Execute the mv program mv :: String -> String -> IO () number :: Parser Int parse_mt_status :: Parser (Int, Int) -- | Run the command mt status for querying the tape drive status, -- and parse its output. mt_status :: IO (Int, Int) -- | The rename(2) system call to rename and/or move a file. The -- renameFile action from the Haskell standard library doesn't -- do it, because the two paths may not refer to directories. Failure -- results in an IOError thrown. The new path is included -- in the IOError and can be accessed with -- IO.ioeGetFileName. rename :: String -> String -> IO () -- | Rename a file. This first tries rename, which is most -- efficient. If it fails, because source and target path point to -- different file systems (as indicated by the errno value -- EXDEV), then /bin/mv is called. -- -- See rename, mv. rename_mv :: FilePath -> FilePath -> IO () -- | Rename a file or directory, and cope with read only issues. -- -- This renames a file or directory, using rename, sets the -- necessary write permissions beforehand, and restores them afterwards. -- This is more efficient than force_mv, because no external -- program needs to be called, but it can rename files only inside the -- same file system. See force_cmd for a detailed description. -- -- The new path may be an existing directory. In this case, it is assumed -- that the old file is to be moved into this directory (like with -- mv). The new path is then completed with the file name -- component of the old path. You won't get an "already exists" error. -- --
--   force_rename = force_cmd rename
--   
-- -- See force_cmd, rename. force_rename :: String -> String -> IO () -- | Move a file or directory, and cope with read only issues. -- -- This moves a file or directory, using the external command -- mv, sets the necessary write permissions beforehand, and -- restores them afterwards. This is less efficient than -- force_rename, because the external program mv needs -- to be called, but it can move files between file systems. See -- force_cmd for a detailed description. -- --
--   force_mv src tgt = fill_in_location "force_mv" $ force_cmd (\src tgt -> run "/bin/mv" ["--", src, tgt]) src tgt
--   
-- -- See force_cmd, force_mv. force_mv :: String -> String -> IO () -- | Rename a file with rename, or when necessary with mv, -- and cope with read only issues. -- -- The necessary write permissions are set, then the file is renamed, -- then the permissions are restored. -- -- First, the rename system call is tried, which is most -- efficient. If it fails, because source and target path point to -- different file systems (as indicated by the errno value -- EXDEV), then /bin/mv is called. -- --
--   force_rename_mv old new = fill_in_location "force_rename_mv" $ force_cmd rename_mv old new
--   
-- -- See rename_mv, rename, mv, force_cmd. force_rename_mv :: FilePath -> FilePath -> IO () -- | Call a command which moves a file or directory, and cope with read -- only issues. -- -- This function is for calling a command, which renames files. -- Beforehand, write permissions are set in order to enable the -- operation, and afterwards the permissions are restored. The command is -- meant to be something like rename or run "/bin/mv". -- -- In order to change the name of a file or dirctory, but leave it in the -- super directory it is in, the super directory must be writeable. In -- order to move a file or directory to a different super directory, both -- super directories and the file/directory to be moved must be -- writeable. I don't know what this behaviour is supposed to be good -- for. -- -- This function copes with the case that the file/directory to be moved -- or renamed, or the super directories are read only. It makes the -- necessary places writeable, calls the command, and makes them read -- only again, if they were before. The user needs the necessary -- permissions for changing the corresponding write permissions. If an -- error occurs (such as file not found, or insufficient permissions), -- then the write permissions are restored to the state before, before -- the exception is passed through to the caller. -- -- The command must take two arguments, the old path and the new path. It -- is expected to create the new path in the file system, such that the -- correct write permissions of the new path can be set by -- force_cmd after executing it. -- -- The new path may be an existing directory. In this case, it is assumed -- that the old file is to be moved into this directory (like with -- mv). The new path is completed with the file name component -- of the old path, before it is passed to the command, such that the -- command is supplied the complete new path. -- -- Examples: -- --
--   force_cmd rename from to
--   force_cmd (\from to -> run "/bin/mv" ["-i", "-v", "--", from, to]) from to
--   
-- -- See force_rename, force_mv, rename. force_cmd :: (String -> String -> IO ()) -> String -> String -> IO () -- | Make a file or directory writeable for the user, perform an action, -- and restore its writeable status. An IOError is raised when the user -- doesn't have permission to make the file or directory writeable. -- --
--   force_writeable path io = force_writeable2 path (io >>= \res -> return (path, res))
--   
-- -- Example: -- --
--   -- Need to create a new directory in /foo/bar, even if that's write protected
--   force_writeable "/foo/bar" $ mkdir "/foo/bar/baz"
--   
-- -- See force_cmd, force_writeable2. force_writeable :: String -> IO a -> IO a -- | Make a file or directory writeable for the user, perform an action, -- and restore its writeable status. The action may change the name of -- the file or directory. Therefore it returns the new name, along with -- another return value, which is passed to the caller. -- -- The writeable status is only changed back if it has been changed by -- force_writeable2 before. An IOError is raised when the user -- doesn'h have permission to make the file or directory writeable, or -- when the new path doesn't exist. -- -- See force_cmd, force_writeable. force_writeable2 :: String -> IO (String, a) -> IO a -- | Call the fdupes program in order to find identical files. It -- outputs a list of groups of file names, such that the files in each -- group are identical. Each of these groups is further analysed by the -- fdupes action. It is split to a list of lists of paths, such -- that each list of paths corresponds to one of the directories which -- have been searched by the fdupes program. If you just want -- groups of identical files, then apply map concat to the -- result. -- -- The fdupes /program doesn't handle multiple occurences -- of the same directory, or in recursive mode one specified directory -- containing another, properly. The same file may get reported multiple -- times, and identical files may not get reported./ -- -- The paths are normalised (using normalise_path). fdupes :: [String] -> [String] -> IO [[[String]]] replace_location :: String -> String -> IO a -> IO a hsshellscript_get_realpath :: (Ptr CChar) -> (IO (Ptr CChar)) hsshellscript_get_readlink :: (Ptr CChar) -> (IO (Ptr CChar)) foreign_symlink :: (Ptr CChar) -> ((Ptr CChar) -> (IO CInt)) foreign_rename :: (Ptr CChar) -> ((Ptr CChar) -> (IO CInt)) module HsShellScript -- | Create directory. This is a shorthand to -- System.Directory.createDirectory from the Haskell standard -- library. In case of an error, the path is included in the -- IOError, which GHC's implementation neglects to do. mkdir :: String -> IO () -- | Remove directory. This is Directory.removeDirectory from the -- Haskell standard library. In case of an error, the path is included in -- the IOError, which GHC's implementation neglects to do. rmdir :: String -> IO () -- | Get program start working directory. This is the PWD -- environent variable, which is kept by the shell (bash, at least). It -- records the directory path in which the program has been started. -- Symbolic links in this path aren't expanded. In this way, it differs -- from getCurrentDirectory from the Haskell standard library. pwd :: IO String -- | Change directory. This is an alias for -- Directory.setCurrentDirectory from the Haskell standard -- library. In case of an error, the path is included in the -- IOError, which GHC's implementation neglects to do. -- -- Note that this command is subtly different from the shell's -- cd command. It changes the process' working directory. This -- is always a realpath. Symlinks are expanded. The shell, on the other -- hand, keeps track of the current working directory separately, in a -- different way: symlinks are not expanded. The shell's idea of -- the working directory is different from the working directory which a -- process has. -- -- This means that the same sequence of cd commands, when done -- in a real shell script, will lead into the same directory. But the -- working directory as reported by the shell's pwd command may -- differ from the corresponding one, reported by -- getCurrentDirectory. -- -- (When talking about the "shell", I'm talking about bash, regardless of -- whether started as /bin/bash or in compatibility mode, as -- /bin/sh. I presume it's the standard behavior for the POSIX -- standard shell.) -- -- See pwd. cd :: String -> IO () -- | Do a call to the realpath(3) system library function. This -- makes the path absolute, normalizes it and expands all symbolic links. -- In case of an error, an IOError is thrown. realpath :: String -> IO String -- | Return the normalised, absolute version of a specified path. The path -- is made absolute with the current working directory, and is -- syntactically normalised afterwards. This is the same as what the -- realpath program reports with the -s option. It's -- almost the same as what it reports when called from a shell. The -- difference lies in the shell's idea of the current working directory. -- See cd for details. -- -- See cd, normalise_path. realpath_s :: String -> IO String -- | Test for the existence of a path. This is the disjunction of -- Directory.doesDirectoryExist and -- Directory.doesFileExist. For an dangling symlink, this will -- return False. path_exists :: String -> IO Bool -- | Test for the existence of a path. This uses -- System.Posix.Files.getFileStatus to determine whether the -- path exists in any form in the file system. For a dangling symlink, -- the result is True. path_exists' :: String -> IO Bool -- | Test if path points to a file. This is a shortcut for -- Directory.doesFileExist. is_file :: String -> IO Bool -- | Test if path points to a directory. This will return True for -- a symlink pointing to a directory. It's a shortcut for -- Directory.doesDirectoryExist. is_dir :: String -> IO Bool -- | Change the working directory temporarily. This executes the specified -- IO action with a new working directory, and restores it afterwards -- (exception-safely). with_wd :: FilePath -> IO a -> IO a -- | Determine whether a path is a symbolic link. The result for a dangling -- symlink is True. The path must exist in the file system. In -- case of an error, a proper IOError is thrown. is_symlink :: String -> IO Bool -- | Make a symbolic link. This is the symlink(2) function. Any -- error results in an IOError thrown. The path of the intended -- symlink is included in the IOError and can be accessed with -- ioeGetFileName from the Haskell standard library IO. symlink :: String -> String -> IO () -- | Determine the target of a symbolic link. This uses the -- readlink(2) system call. The result is a path which is either -- absolute, or relative to the directory which the symlink is in. In -- case of an error, an IOError is thrown. The path is included -- and can be accessed with IO.ioeGetFileName. Note that, if the -- path to the symlink ends with a slash, this path denotes the directory -- pointed to, not the symlink. In this case the call to will fail -- because of "Invalid argument". readlink :: String -> IO String -- | Determine the target of a symbolic link. This uses the -- readlink(2) system call. The target is converted, such that -- it is relative to the current working directory, if it isn't absolute. -- Note that, if the path to the symlink ends with a slash, this path -- denotes the directory pointed to, not the symlink. In this case -- the call to readlink will fail with an IOError -- because of "Invalid argument". In case of any error, a proper -- IOError is thrown. readlink' :: String -> IO String -- | Remove file. This is Directory.removeFile from the Haskell -- standard library, which is a direct frontend to the unlink(2) -- system call in GHC. rm :: String -> IO () -- | Execute /bin/chmod -- --
--   chmod = run "/bin/chmod"
--   
chmod :: [String] -> IO () -- | Execute /bin/chown -- --
--   chown = run "/bin/chown"
--   
chown :: [String] -> IO () -- | Execute the cp program cp :: String -> String -> IO () -- | Execute the mv program mv :: String -> String -> IO () -- | The rename(2) system call to rename and/or move a file. The -- renameFile action from the Haskell standard library doesn't -- do it, because the two paths may not refer to directories. Failure -- results in an IOError thrown. The new path is included -- in the IOError and can be accessed with -- IO.ioeGetFileName. rename :: String -> String -> IO () -- | Rename a file. This first tries rename, which is most -- efficient. If it fails, because source and target path point to -- different file systems (as indicated by the errno value -- EXDEV), then /bin/mv is called. -- -- See rename, mv. rename_mv :: FilePath -> FilePath -> IO () -- | Rename a file or directory, and cope with read only issues. -- -- This renames a file or directory, using rename, sets the -- necessary write permissions beforehand, and restores them afterwards. -- This is more efficient than force_mv, because no external -- program needs to be called, but it can rename files only inside the -- same file system. See force_cmd for a detailed description. -- -- The new path may be an existing directory. In this case, it is assumed -- that the old file is to be moved into this directory (like with -- mv). The new path is then completed with the file name -- component of the old path. You won't get an "already exists" error. -- --
--   force_rename = force_cmd rename
--   
-- -- See force_cmd, rename. force_rename :: String -> String -> IO () -- | Move a file or directory, and cope with read only issues. -- -- This moves a file or directory, using the external command -- mv, sets the necessary write permissions beforehand, and -- restores them afterwards. This is less efficient than -- force_rename, because the external program mv needs -- to be called, but it can move files between file systems. See -- force_cmd for a detailed description. -- --
--   force_mv src tgt = fill_in_location "force_mv" $ force_cmd (\src tgt -> run "/bin/mv" ["--", src, tgt]) src tgt
--   
-- -- See force_cmd, force_mv. force_mv :: String -> String -> IO () -- | Rename a file with rename, or when necessary with mv, -- and cope with read only issues. -- -- The necessary write permissions are set, then the file is renamed, -- then the permissions are restored. -- -- First, the rename system call is tried, which is most -- efficient. If it fails, because source and target path point to -- different file systems (as indicated by the errno value -- EXDEV), then /bin/mv is called. -- --
--   force_rename_mv old new = fill_in_location "force_rename_mv" $ force_cmd rename_mv old new
--   
-- -- See rename_mv, rename, mv, force_cmd. force_rename_mv :: FilePath -> FilePath -> IO () -- | Call a command which moves a file or directory, and cope with read -- only issues. -- -- This function is for calling a command, which renames files. -- Beforehand, write permissions are set in order to enable the -- operation, and afterwards the permissions are restored. The command is -- meant to be something like rename or run "/bin/mv". -- -- In order to change the name of a file or dirctory, but leave it in the -- super directory it is in, the super directory must be writeable. In -- order to move a file or directory to a different super directory, both -- super directories and the file/directory to be moved must be -- writeable. I don't know what this behaviour is supposed to be good -- for. -- -- This function copes with the case that the file/directory to be moved -- or renamed, or the super directories are read only. It makes the -- necessary places writeable, calls the command, and makes them read -- only again, if they were before. The user needs the necessary -- permissions for changing the corresponding write permissions. If an -- error occurs (such as file not found, or insufficient permissions), -- then the write permissions are restored to the state before, before -- the exception is passed through to the caller. -- -- The command must take two arguments, the old path and the new path. It -- is expected to create the new path in the file system, such that the -- correct write permissions of the new path can be set by -- force_cmd after executing it. -- -- The new path may be an existing directory. In this case, it is assumed -- that the old file is to be moved into this directory (like with -- mv). The new path is completed with the file name component -- of the old path, before it is passed to the command, such that the -- command is supplied the complete new path. -- -- Examples: -- --
--   force_cmd rename from to
--   force_cmd (\from to -> run "/bin/mv" ["-i", "-v", "--", from, to]) from to
--   
-- -- See force_rename, force_mv, rename. force_cmd :: (String -> String -> IO ()) -> String -> String -> IO () -- | Make a file or directory writeable for the user, perform an action, -- and restore its writeable status. An IOError is raised when the user -- doesn't have permission to make the file or directory writeable. -- --
--   force_writeable path io = force_writeable2 path (io >>= \res -> return (path, res))
--   
-- -- Example: -- --
--   -- Need to create a new directory in /foo/bar, even if that's write protected
--   force_writeable "/foo/bar" $ mkdir "/foo/bar/baz"
--   
-- -- See force_cmd, force_writeable2. force_writeable :: String -> IO a -> IO a -- | Make a file or directory writeable for the user, perform an action, -- and restore its writeable status. The action may change the name of -- the file or directory. Therefore it returns the new name, along with -- another return value, which is passed to the caller. -- -- The writeable status is only changed back if it has been changed by -- force_writeable2 before. An IOError is raised when the user -- doesn'h have permission to make the file or directory writeable, or -- when the new path doesn't exist. -- -- See force_cmd, force_writeable. force_writeable2 :: String -> IO (String, a) -> IO a -- | This is the System.Posix.Files.getFileStatus function from -- the GHC libraries, with improved error reporting. The GHC function -- doesn't include the file name in the IOError when the call -- fails, making error messages much less useful. getFileStatus' -- rectifies this. -- -- See getFileStatus. getFileStatus' :: FilePath -> IO FileStatus -- | This is the System.Posix.Files.fileAccess function from the -- GHC libraries, with improved error reporting. The GHC function doesn't -- include the file name in the IOError when the call fails, -- making error messages much less useful. fileAccess' rectifies -- this. -- -- See fileAccess. fileAccess' :: FilePath -> Bool -> Bool -> Bool -> IO Bool -- | Improved version of System.Posix.Files.setFileMode, which -- sets the file name in the IOError which is thrown in case of -- an error. The implementation in GHC 6.2.2 neglects to do this. -- --
--   setFileMode' path mode =
--      fill_in_filename path $
--         setFileMode path mode
--   
setFileMode' :: FilePath -> FileMode -> IO () -- | Run the command mt status for querying the tape drive status, -- and parse its output. mt_status :: IO (Int, Int) -- | Call the fdupes program in order to find identical files. It -- outputs a list of groups of file names, such that the files in each -- group are identical. Each of these groups is further analysed by the -- fdupes action. It is split to a list of lists of paths, such -- that each list of paths corresponds to one of the directories which -- have been searched by the fdupes program. If you just want -- groups of identical files, then apply map concat to the -- result. -- -- The fdupes /program doesn't handle multiple occurences -- of the same directory, or in recursive mode one specified directory -- containing another, properly. The same file may get reported multiple -- times, and identical files may not get reported./ -- -- The paths are normalised (using normalise_path). fdupes :: [String] -> [String] -> IO [[[String]]] -- | Call the du program. See du(1). du :: (Integral int, Read int, Show int) => int -> String -> IO int -- | Execute an IO action as a separate process, and wait for it to finish. -- Report errors as exceptions. -- -- This forks a child process, which performs the specified IO action. In -- case the child process has been stopped by a signal, the parent -- blocks. -- -- If the action throws an IOError, it is transmitted to the -- parent. It is then raised there, as if it happened locally. The child -- then aborts quietly with an exit code of 0. -- -- Exceptions in the child process, other than IOErrors, result -- in an error message on stderr, and a ProcessStatus -- exception in the parent, with the value of Exited (ExitFailure -- 1). The following exceptions are understood by subproc, -- and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- If the child process exits with an exit code other than zero, or it is -- terminated by a signal, the corresponding ProcessStatus is -- raised as an exception in the parent program. Only IOErrors -- are transmitted to the parent. -- -- When used in conjunction with an exec variant, this means -- that the parent process can tell the difference between failure of the -- exec call itself, and failure of the child program being -- executed after a successful call of the exec variant. In case -- of failure of the exec call, You get the IOError, -- which happened in the child when calling executeFile (from -- the GHC hierarchical libraries). In case of the called program -- failing, you get the ProcessStatus. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally (unless it throws an IOError). The child process is -- then properly terminated by subproc, such that no resources, -- which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- If you want to run an external program, by calling one of the -- exec variants in the child action, you might want to call -- runprog instead of subproc. -- -- Examples: -- -- Run a program with the environment replaced: -- --
--   subproc (execpe "foobar" ["1","2","3"] new_env)
--   
-- -- This results in a ProcessStatus exception: -- --
--   subproc (exec "/bin/false" [])
--   
-- -- This results in an IOError (unless you actually have -- /frooble): -- --
--   subproc (exec "/frooble" [])
--   
-- -- See runprog, spawn, exec, execp, -- exece, execpe. subproc :: IO a -> IO () -- | Execute an IO action as a separate process, and continue without -- waiting for it to finish. -- -- The program forks a child process, which performs the specified action -- and terminates. The child's process ID is returned. -- -- See HsShellScript#subr for further details. -- -- See subproc. spawn :: IO a -> IO ProcessID -- | Run an external program, and report errors as exceptions. The -- executable is searched via the PATH. In case the child -- process has been stopped by a signal, the parent blocks. -- -- In case the program exits in an way which indicates an error, or is -- terminated by a signal, a RunError is thrown. It contains the -- details of the call. The runprog action can also be converted -- to throw IOErrors instaed, by applying as_ioe to it. -- Either can be used to generate an informative error message. -- -- In case of starting the program itself failed, an IOError is -- thrown. -- -- runprog prog par is a simple front end to subproc. -- It is essentially subproc (execp prog par), apart from -- building a RunError from a ProcessStatus. -- -- Example 1: -- --
--   do runprog "foo" ["some", "args"]
--      ...
--   `catch` (\re -> do errm (show_runerror re)
--                         ...
--              )
--   
-- -- Example 2: -- --
--   do as_ioe $ runprog "foo" ["some", "args"]
--      ...
--   `catch` (\ioe -> do errm (show_ioerror ioe)
--                          ...
--              )
--   
-- -- See subproc, spawn, RunError, -- show_runerror, to_ioe, as_ioe. runprog :: FilePath -> [String] -> IO () -- | An error which occured when calling an external program. The fields -- specifiy the details of the call. -- -- See show_runerror, to_ioe, as_ioe, -- System.Posix.ProcessStatus. data RunError RunError :: String -> [String] -> [(String, String)] -> String -> ProcessStatus -> Maybe CInt -> RunError -- | Program name re_prog :: RunError -> String -- | Program arguments re_pars :: RunError -> [String] -- | The environment in use when the call was done re_env :: RunError -> [(String, String)] -- | The working directory when the call was done re_wd :: RunError -> String -- | The process status of the failure re_ps :: RunError -> ProcessStatus -- | The error (errno) code re_errno :: RunError -> Maybe CInt -- | Make a readable error message. This includes all the fields of -- RunError except for the environment. -- -- See RunError. show_runerror :: RunError -> String -- | Convert a RunError to an IOError. -- -- The IOError type isn't capable of holding all the information -- which is contained in a RunError. The environment is left -- out, and most of the other fields are included only informally, in the -- description. -- -- The fields of the generated IOError are: -- -- -- -- See as_ioe, runprog, show_runerror. to_ioe :: RunError -> IOError -- | Call the specified IO action (which is expected to contain calls of -- runprog) and convert any RunError exceptions to -- IOErrors. -- -- The conversion is done by to_ioe. -- -- See to_ioe, runprog. as_ioe :: IO a -> IO a -- | Execute an external program. This replaces the running process. The -- path isn't searched, the environment isn't changed. In case of -- failure, an IOError is thrown. -- --
--   exec path args =
--      execute_file path False args Nothing
--   
-- -- See execute_file, HsShellScript#exec. exec :: String -> [String] -> IO a -- | Execute an external program. This replaces the running process. The -- path is searched, the environment isn't changed. In case of failure, -- an IOError is thrown. -- --
--   execp prog args =
--      execute_file prog True args Nothing
--   
-- -- See execute_file, HsShellScript#exec. execp :: String -> [String] -> IO a -- | Execute an external program. This replaces the running process. The -- path isn't searched, the environment of the program is set as -- specified. In case of failure, an IOError is thrown. -- --
--   exece path args env =
--      execute_file path False args (Just env)
--   
-- -- See execute_file, HsShellScript#exec. exece :: String -> [String] -> [(String, String)] -> IO a -- | Execute an external program. This replaces the running process. The -- path is searched, the environment of the program is set as specified. -- In case of failure, an IOError is thrown. -- --
--   execpe prog args env =
--      execute_file prog True args (Just env)
--   
-- -- See execute_file, HsShellScript#exec. execpe :: String -> [String] -> [(String, String)] -> IO a -- | Print an action as a shell command, then perform it. -- -- This is used with actions such as runprog, exec or -- subproc. For instance, echo runprog prog args is a -- variant of runprog prog args, which prints what is being done -- before doing it. -- -- See runprog, subproc, exec. echo :: (FilePath -> [String] -> IO ()) -> FilePath -> [String] -> IO () -- | Run a subroutine as a child process, but don't let it produce any -- messages. Read its stdout and stderr instead, and -- append it to the contents of a mutable variable. The idea is that you -- can run some commands silently, and report them and their messages to -- the user only when something goes wrong. -- -- If the child process terminates in a way which indicates an error, -- then the process status is thrown, in the same way as runprog -- does. If the subroutine throws an (Exited ec) exception (of -- type ProcessStatus), such as thrown by runprog, then -- the child process exits with the same exit code, such that the parent -- process reports it to the caller, again as a ProcessStatus -- exception. -- -- When the subroutine finishes, the child process is terminated with -- _exit 0. When it throws an exception, an error message -- is printed and it is terminated with _exit 1. See -- HsShellScript#subr for details. -- -- The standard output (and the standard error output) of the parent -- process are flushed before the fork, such that no output appears -- twice. -- -- Example: -- --
--   let handler :: IORef String -> ProcessStatus -> IO ()
--       handler msgref ps = do hPutStrLn stderr ("Command failed with " ++ show ps ++ ". Actions so far: ")
--                              msg <- readIORef msgref
--                              hPutStrLn stderr msg
--                              exitWith (ExitFailure 1)
--   
--   msgref <- newIORef ""
--   do silently msgref $ do putStrLn "Now doing foobar:"
--                           echo exec "/foo/bar" ["arguments"]
--      silently msgref $ echo exec "/bar/baz" ["arguments"]
--   `catch` (handler msgref)
--   
-- -- See lazy_pipe_from, subproc, runprog, Data.IORef. silently :: IORef String -> IO () -> IO () -- | Call the shell to execute a command. In case of an error, a -- RunError ist thrown. This is like the Haskell standard -- library function system, except that error handling is -- brought in accordance with HsShellScript's scheme. (It is not a -- front end to system.) -- --
--   system_runprog cmd = runprog "/bin/sh" ["-c", "--", cmd]
--   
-- -- Example: Call "foo" and report Errors as IOErrors, rather -- than RunErrors. -- --
--   as_ioe $ system_runprog "foo" ["bar", "baz"]
--   
-- -- See RunError, as_ioe system_runprog :: String -> IO () -- | Call the shell to execute a command. In case of an error, throw the -- ProcessStatus (such as (Exited (ExitFailure ec))) as -- an exception. This is like the Haskell standard library function -- system, except that error handling is brought in accordance -- with HsShellScript's scheme. -- -- exitcode . system_throw is the same as the system -- function, except that when the called shell is terminated or stopped -- by a signal, this still lead to the ProcessStatus being -- thrown. The Haskell library report says nothing about what happens in -- this case, when using the system function. -- --
--   system_throw cmd = run "/bin/sh" ["-c", "--", cmd]
--   
-- -- This function is deprecated. You should rather use -- system_runprog, which provides for much better error reporting. system_throw :: String -> IO () -- | This is a replacement for System.Posix.Process.executeFile. -- It does additional preparations, then calls executeFile. -- executeFile can't normally be used directly, -- because it doesn't do the things which are outlined here. -- -- This are the differences to executeFile: -- --
    --
  1. stdout and stderr are flushed.
  2. --
  3. The standard file descriptors 0-2 are made copies of the file -- descriptors which the standard handles currently use. This is -- necessary because they might no longer use the standard handles. See -- HsShellScript#fdpipes.
  4. --
-- -- If the standard handles stdin, stdout, -- stderr aren't in closed state, and they aren't already -- connected to the respective standard file descriptors, their file -- descriptors are copied to the respective standard file descriptors -- (with dup2). Backup copies are made of the file descriptors -- which are overwritten. If some of the standard handles are closed, the -- corresponding standard file descriptors are closed as well. -- --
    --
  1. All file descriptors, except for the standard ones, are set to -- close-on-exec (see fcntl(2)), and will be closed on -- successful replacement of the process. Before that, the old file -- descriptor flags are saved.
  2. --
  3. The standard file descriptors are set to blocking mode, since GHC -- 6.2.2 sets file descriptors to non-blocking (except 0-2, which may get -- overwritten by a non-blocking one in step 2). The called program -- doesn't expect that.
  4. --
  5. In case replacing the process fails, the file descriptors are -- reset to the original state. The file descriptors flags are restored, -- and the file descriptors 0-2 are overwritten again, with their backup -- copies. Then an IOError is thrown.
  6. --
  7. In any IOError, the program is filled in as the file name -- (executeFile neglects this).
  8. --
  9. The return type is a generic a, rather than -- ().
  10. --
-- -- Also see HsShellScript#exec. execute_file :: FilePath -> Bool -> [String] -> Maybe [(String, String)] -> IO a -- | Modify a subroutine action in order to make it suitable to run as a -- child process. -- -- This is used by functions like call, silently, -- pipe_to etc. The action is executed. When it returns, the -- (child) process is terminated with _exit 0 (after -- flushing stdout), circumventing normal program shutdown. When -- it throws an exception, an error message is printed and the (child) -- process is terminated with _exit 1. child :: IO a -> IO b -- | Generate a human-readable description of a ProcessStatus. -- -- See exec, runprog and -- System.Posix.ProcessStatus in the GHC hierarchical library -- documentation. explain_processstatus :: ProcessStatus -> String -- | Execute an IO action as a separate process, and wait for it to finish. -- Report errors as exceptions. -- -- This function is included only for backwards compatibility. New -- code should use subproc instead, which has better -- error handling. -- -- The program forks a child process and performs the specified action. -- Then it waits for the child process to finish. If it exits in any way -- which indicates an error, the ProcessStatus is thrown. -- -- The parent process waits for the child processes, which have been -- stopped by a signal. -- -- See HsShellScript#subr for further details. -- -- See subproc, spawn. call :: IO a -> IO () -- | Run an external program. This starts a program as a child process, and -- waits for it to finish. The executable is searched via the -- PATH. -- -- This function is included for backwards compatibility only. New -- code should use runprog, which has much better -- error handling. -- -- When the specified program can't be executed, an error message is -- printed, and the main process gets a ProcessStatus thrown, -- with the value Exited (ExitFailure 1). This means that the -- main program can't distinguish between failure of calling the program -- and the program exiting with an exit code of 1. However, an error -- message "Error calling ...", including the description in the IOError -- produced by the failed execp call, is printed on -- stderr. -- -- run prog par is essentially call (execp prog par). -- -- Example: -- --
--   run "/usr/bin/foobar" ["some", "args"]
--      `catch` (\ps -> do -- oops...
--                 )
--   
-- -- See runprog, subproc, spawn. run :: FilePath -> [String] -> IO () -- | Redirect the standard output of the specified IO action to a file. The -- file will be overwritten, if it already exists. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/program" [] ->- "/tmp/output"
--   
-- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use ->>- -- instead. -- -- See subproc, runprog, ->>-, =>-. (->-) :: IO a -> FilePath -> IO a -- | Redirect the standard output of the specified IO action to a file. If -- the file already exists, the output will be appended. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/noisy/program" [] ->>- "/dev/null"
--   
-- -- See subproc, runprog, '(->-)', '(=>>-)'. (->>-) :: IO a -> FilePath -> IO a -- | Redirect the standard error output of the specified IO action to a -- file. If the file already exists, it will be overwritten. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use =>>- -- instead. -- -- Example: -- --
--   run "/path/to/foo" [] =>- "/tmp/errlog"
--   
-- -- See subproc, runprog, '(->-)', '(=>>-)'. (=>-) :: IO a -> FilePath -> IO a -- | Redirect the standard error output of the specified IO action to a -- file. If the file already exists, the output will be appended. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   run "/some/program" [] =>>- "/dev/null"
--   
-- -- See subproc, runprog, '(->>-)', '(=>-)'. (=>>-) :: IO a -> FilePath -> IO a -- | Redirect stdin from a file. This modifies the specified action, such -- that the standard input is read from a file. -- -- What's actually modified is the stdin handle, not the file -- descriptor 0. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- -- Example: -- --
--   call (exec "/path/to/foo" [] -<- "bar")
--   
-- -- See exec, runprog, '(->-)', '(=>-)'. (-<-) :: IO a -> FilePath -> IO a -- | Redirect both stdout and stderr to a file. This is equivalent to the -- shell's &> operator. If the file already exists, it -- will be overwritten. -- -- What's actually modified are the stdout and stderr -- handles, not the file descriptors 1 and 2. The exec functions -- know about this. See HsShellScript#fdpipes and -- HsShellScript#exec for details. -- -- Note: You can't redirect to "/dev/null" this way, because GHC -- 6.4's openFile throws an "invalid argument" IOError. (This -- may be a bug in the GHC 6.4 libraries). Use -&>>- -- instead. -- --
--   (-&>-) io path = err_to_out io ->- path
--   
-- -- Example: -- --
--   call (exec "/path/to/foo" [] -&>- "log")
--   
-- -- See '(-&>>-)', err_to_out. (-&>-) :: IO a -> FilePath -> IO a -- | Redirect both stdout and stderr to a file. If the file already exists, -- the output will be appended. -- -- What's actually modified are the stdout and stderr -- handles, not the file descriptors 1 and 2. The exec functions -- know about this. See HsShellScript#fdpipes and -- HsShellScript#exec for details. -- --
--   (-&>>-) io path = (err_to_out >> io) ->>- path
--   
-- -- Example: -- --
--   run "/some/noisy/program" [] -&>>- "/dev/null"
--   
-- -- See '(-&>-)', out_to_err. (-&>>-) :: IO a -> FilePath -> IO a -- | Send the error output of the specified action to its standard output. -- -- What's actually modified is the stdout handle, not the file -- descriptor 1. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- --
--   err_to_out = redirect stderr stdout
--   
-- -- See redirect. err_to_out :: IO a -> IO a -- | Send the output of the specified action to its standard error output. -- -- What's actually modified is the stderr handle, not the file -- descriptor 2. The exec functions know about this. See -- HsShellScript#fdpipes and HsShellScript#exec for -- details. -- --
--   redirect stdout stderr
--   
-- -- See redirect. out_to_err :: IO a -> IO a -- | Build left handed pipe of stdout. -- -- "p -|- q" builds an IO action from the two IO actions -- p and q. q is executed in an external -- process. The standard output of p is sent to the standard -- input of q through a pipe. The result action consists of -- forking off q (connected with a pipe), and p. -- -- The result action does not run p in a separate -- process. So, the pipe itself can be seen as a modified action -- p, forking a connected q. The pipe is called "left -- handed", because p remains unforked, and not q. -- -- The exit code of q is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Examples: -- --
--   call (exec "/usr/bin/foo" [] -|- exec "/usr/bin/bar" [])
--   
-- --
--   call (    execp "foo" ["..."]
--         -|= ( -- Do something with foo's output
--               do cnt <- lazy_contents "-"
--                  ...
--             )
--        )
--   
-- -- See subproc, '(=|-)', '(-|=)'. (-|-) :: IO a -> IO b -> IO a -- | Build left handed pipe of stderr. -- -- "p =|- q" builds an IO action from the two IO actions -- p and q. q is executed in an external -- process. The standard error output of p is sent to the -- standard input of q through a pipe. The result action -- consists of forking off q (connected with a pipe), and -- p. -- -- The result action does not run p in a separate -- process. So, the pipe itself can be seen as a modified action -- p, forking a connected q. The pipe is called "left -- handed", because p has this property, and not q. -- -- The exit code of q is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   call (exec "/usr/bin/foo" [] =|- exec "/usr/bin/bar" [])
--   
-- -- See subproc, '(-|-)', '(-|=)'. (=|-) :: IO a -> IO b -> IO a -- | Build right handed pipe of stdout. -- -- "p -|= q" builds an IO action from the two IO actions -- p and q. p is executed in an external -- process. The standard output of p is sent to the standard -- input of q through a pipe. The result action consists of -- forking off p (connected with a pipe), and q. -- -- The result action does not run q in a separate -- process. So, the pipe itself can be seen as a modified action -- q, forking a connected p. The pipe is called "right -- handed", because q has this property, and not p. -- -- The exit code of p is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   @call (exec \"\/usr\/bin\/foo\" [] -|= exec \"\/usr\/bin\/bar\" [])@
--   
-- -- See subproc, '(=|-)', '(=|=)'. (-|=) :: IO a -> IO b -> IO b -- | Build right handed pipe of stderr. -- -- "p =|= q" builds an IO action from the two IO actions -- p and q. p is executed in an external -- process. The standard error output of p is sent to the -- standard input of q through a pipe. The result action -- consists of forking off p (connected with a pipe), and -- q. -- -- The result action does not run q in a separate -- process. So, the pipe itself can be seen as a modified action -- q, forking a connected p. The pipe is called "right -- handed", because q has this property, and not p. -- -- The exit code of p is silently ignored. The process ID of the -- forked copy of q isn't returned to the caller, so it's lost. -- -- See HsShellScript#subr and HsShellScript#exec for -- further details. -- -- Example: -- --
--   call (exec "/usr/bin/foo" [] =|= exec "/usr/bin/bar" [])
--   
-- -- See subproc, =|-, -|=. (=|=) :: IO a -> IO b -> IO b -- | Temporarily replace a handle. This makes a backup copy of the original -- handle (typically a standard handle), overwrites it with the specified -- one, runs the specified action, and restores the handle from the -- backup. -- -- Example: -- --
--   h <- openFile "/tmp/log" WriteMode
--   redirect stdout h io
--   hClose h
--   
-- -- This is the same as -- --
--   io ->- "/tmp/log"
--   
-- -- See -|-, =|-. redirect :: Handle -> Handle -> IO a -> IO a -- | Run an IO action as a separate process, and pipe some text to its -- stdin. Then close the pipe and wait for the child process to -- finish. -- -- This forks a child process, which executes the specified action. The -- specified text is sent to the action's stdin through a pipe. -- Then the pipe is closed. In case the action replaces the process by -- calling an exec variant, it is made sure that the process -- gets the text on it's file descriptor 0. -- -- In case the action fails (exits with an exit status other than 0, or -- is terminated by a signal), the ProcessStatus is thrown, such -- as reported by getProcessStatus. No attempt is made to create -- more meaningful exceptions, like it is done by -- runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the termination of the child. The parent gets a -- ProcessStatus exception, with the value of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Example: -- --
--   pipe_to "blah" (exec "/usr/bin/foo" ["bar"])
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See subproc, runprog, -<-, h_pipe_to. pipe_to :: String -> IO a -> IO () -- | Run an IO action as a separate process, and get a connection (a pipe) -- to its stdin as a file handle. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stdin, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 0 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). If the child action throws an -- exception, an error message is printed on stderr, and the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- If the child process exits in a way which signals an error, the -- corresponding ProcessStatus is returned by -- getProcessStatus. See getProcessStatus for details. -- -- Example: -- --
--   (handle, pid) <- h_pipe_to $ exec "/usr/bin/foo" ["bar"]
--   hPutStrLn handle "Some text to go through the pipe"
--   (Just ps) <- getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- See -<-, pipe_to, pipe_from, -- pipe_from2. See HsShellScript#fdpipes for more details. h_pipe_to :: IO a -> IO (Handle, ProcessID) -- | Run an IO action as a separate process, and read its stdout -- strictly. Then wait for the child process to finish. This is like the -- backquote feature of shells. -- -- This forks a child process, which executes the specified action. The -- output of the child is read from its standard output. In case it -- replaces the process by calling an exec variant, it is make -- sure that the output is read from the new process' file descriptor 1. -- -- The end of the child's output is reached when either the standard -- output is closed, or the child process exits. The program blocks until -- the action exits, even if the child closes its standard output -- earlier. So the parent process always notices a failure of the action -- (when it exits in a way which indicates an error). -- -- When the child action exits in a way which indicates an error, the -- corresponding ProcessStatus is thrown. See -- getProcessStatus. No attempt is made to create more meaningful -- exceptions, like it is done by runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the proper termination of the child. The parent -- gets a ProcessStatus exception, with the value of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, pipe_from does not remove -- any trailing newline characters. The entire output of the action is -- returned. You might want to apply chomp to the result. -- -- Example: -- --
--   output <- pipe_from $ exec "/bin/mount" []
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See exec, pipe_to, pipe_from2, -- h_pipe_from, lazy_pipe_from, chomp, -- silently. pipe_from :: IO a -> IO String -- | Run an IO action in a separate process, and read its standard output, -- The output is read lazily, as the returned string is evaluated. The -- child's output along with its process ID are returned. -- -- This forks a child process, which executes the specified action. The -- output of the child is read lazily through a pipe, which connncts to -- its standard output. In case the child replaces the process by calling -- an exec variant, it is make sure that the output is read from -- the new process' file descriptor 1. -- -- lazy_pipe_from calls hGetContents, in order to read -- the pipe lazily. This means that the file handle goes to semi-closed -- state. The handle holds a file descriptor, and as long as the string -- isn't fully evaluated, this file descriptor won't be closed. For the -- file descriptor to be closed, first its standard output needs to be -- closed on the child side. This happens when the child explicitly -- closes it, or the child process exits. When afterwards the string on -- the parent side is completely evaluated, the handle, along with the -- file descritor it holds, are closed and freed. -- -- If you use the string in such a way that you only access the beginning -- of the string, the handle will remain in semi-closed state, holding a -- file descriptor, even when the pipe is closed on the child side. When -- you do that repeatedly, you may run out of file descriptors. -- -- Unless you're sure that your program will reach the string's end, you -- should take care for it explicitly, by doing something like this: -- --
--   (output, pid) <- lazy_pipe_from (exec "\/usr\/bin\/foobar" [])
--   ...
--   seq (length output) (return ())   
--   
-- -- This will read the entire standard output of the child, even if it -- isn't needed. You can't cut the child process' output short, when you -- use lazy_pipe_from. If you need to do this, you should use -- h_pipe_from, which gives you the handle, which can then be -- closed by hClose, even if the child's output isn't completed: -- --
--   (h, pid) <- h_pipe_from io
--   
--   -- Lazily read io's output
--   output <- hGetContents h
--   ...
--   -- Not eveyting read yet, but cut io short.
--   hClose h   
--   
--   -- Wait for io to finish, and detect errors
--   (Just ps) <- System.Posix.getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- When you close the handle before all data has been read, then the -- child gets a SIGPIPE signal. -- -- After all the output has been read, you should call -- getProcessStatus on the child's process ID, in order to -- detect errors. Be aware that you must evaluate the whole string, -- before calling getProcessStatus blockingly, or you'll get a -- deadlock. -- -- You won't get an exception, if the child action exits in a way which -- indicates an error. Errors occur asynchronously, when the output -- string is evaluated. You must detect errors by yourself, by calling -- getProcessStatus. -- -- In case the action doesn't replace the child process with an external -- program, an exception may be thrown out of the action. This results in -- an error message on stderr, and the proper termination of the -- child. The ProcessStatus, which can be accessed in the parent -- process by getProcessStatus, is Exited (ExitFailure -- 1). The following exceptions are understood, and result in -- corresponding messages: ArgError, ProcessStatus, -- RunError, IOError and ExitCode. Other -- exceptions result in the generic message, as produced by -- show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, lazy_pipe_from does not -- remove any trailing newline characters. The entire output of the -- action is returned. You might want to apply chomp to the -- result. -- -- See exec, pipe_to, pipe_from, h_pipe_from, -- lazy_pipe_from2, silently. lazy_pipe_from :: IO a -> IO (String, ProcessID) -- | Run an IO action as a separate process, and connect to its -- stdout with a file handle. This is like the backquote feature -- of shells. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stdout, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 1 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- When you call getProcessStatus blockingly, you must first -- ensure that all data has been read, or close the handle. Otherwise -- you'll get a deadlock. When you close the handle before all data has -- been read, then the child gets a SIGPIPE signal. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). No attempt is made to create more -- meaningful exceptions, like it is done by -- runprog/subproc. If the child action throws an -- exception, an error message is printed on stderr, and the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Example: -- --
--   (h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
--   
-- -- See exec, pipe_to, h_pipe_from2, -- pipe_from, lazy_pipe_from, chomp, -- silently. See HsShellScript#fdpipes for more details. h_pipe_from :: IO a -> IO (Handle, ProcessID) -- | Run an IO action as a separate process, and read its standard error -- output strictly. Then wait for the child process to finish. This is -- like the backquote feature of shells. This function is exactly the -- same as pipe_from, except that the standard error output is -- read, instead of the standard output. -- -- This forks a child process, which executes the specified action. The -- error output of the child is read from its standard error output. In -- case it replaces the process by calling an exec variant, it -- is made sure that the output is read from the new process' file -- descriptor 2. -- -- The end of the child's error output is reached when either the -- standard error output is closed, or the child process exits. The -- program blocks until the action exits, even if the child closes its -- standard error output earlier. So the parent process always notices a -- failure of the action (which means it exits in a way which indicates -- an error). -- -- When the child action exits in a way which indicates an error, the -- corresponding ProcessStatus is thrown. See -- getProcessStatus. No attempt is made to create more meaningful -- exceptions, like it is done by runprog/subproc. -- -- Exceptions in the action result in an error message on -- stderr, and the proper termination of the child. This means -- that the error message is sent through the pipe, to the parent -- process. The message can be found in the text which has been read from -- the child process. It doesn't appear on the console. -- -- The parent gets a ProcessStatus exception, with the value of -- Exited (ExitFailure 1). The following exceptions are -- understood, and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, pipe_from2 does not remove -- any trailing newline characters. The entire error output of the action -- is returned. You might want to apply chomp to the result. -- -- Example: -- --
--   output <- pipe_from $ exec "/bin/mount" []
--   
-- -- Example: Access both stdin and stdout of an external -- program. -- --
--   import HsShellScript
--   
--   main = mainwrapper $ do
--   
--      res <- pipe_from $
--         pipe_to "2\n3\n1" $
--            exec "/usr/bin/sort" []
--   
--      putStrLn res
--   
-- -- See exec, pipe_to, pipe_from, -- h_pipe_from2, lazy_pipe_from2, silently. See -- HsShellScript#fdpipes for more details. pipe_from2 :: IO a -> IO String -- | Run an IO action in a separate process, and read its standard error -- output, The output is read lazily, as the returned string is -- evaluated. The child's error output along with its process ID are -- returned. -- -- This forks a child process, which executes the specified action. The -- error output of the child is read lazily through a pipe, which -- connncts to its standard error output. In case the child replaces the -- process by calling an exec variant, it is make sure that the -- output is read from the new process' file descriptor 1. -- -- lazy_pipe_from calls hGetContents, in order to read -- the pipe lazily. This means that the file handle goes to semi-closed -- state. The handle holds a file descriptor, and as long as the string -- isn't fully evaluated, this file descriptor won't be closed. For the -- file descriptor to be closed, first its standard error output needs to -- be closed on the child side. This happens when the child explicitly -- closes it, or the child process exits. When afterwards the string on -- the parent side is completely evaluated, the handle, along with the -- file descritor it holds, are closed and freed. -- -- If you use the string in such a way that you only access the beginning -- of the string, the handle will remain in semi-closed state, holding a -- file descriptor, even when the pipe is closed on the child side. When -- you do that repeatedly, you may run out of file descriptors. -- -- Unless you're sure that your program will reach the string's end, you -- should take care for it explicitly, by doing something like this: -- --
--   (errmsg, pid) <- lazy_pipe_from2 (exec "/usr/bin/foobar" [])
--   ...
--   seq (length errmsg) (return ())   
--   
-- -- This will read the entire standard error output of the child, even if -- it isn't needed. You can't cut the child process' output short, when -- you use lazy_pipe_from. If you need to do this, you should -- use h_pipe_from, which gives you the handle, which can then -- be closed by hClose, even if the child's output isn't -- completed: -- --
--   (h, pid) <- h_pipe_from io
--   
--   -- Lazily read io's output
--   output <- hGetContents h
--   ...
--   -- Not eveyting read yet, but cut io short.
--   hClose h   
--   
--   -- Wait for io to finish, and detect errors
--   (Just ps) <- System.Posix.getProcessStatus True False pid
--   when (ps /= Exited ExitSuccess) $
--      throw ps
--   
-- -- When you close the handle before all data has been read, then the -- child gets a SIGPIPE signal. -- -- After all the output has been read, you should call -- getProcessStatus on the child's process ID, in order to -- detect errors. Be aware that you must evaluate the whole string, -- before calling getProcessStatus blockingly, or you'll get a -- deadlock. -- -- You won't get an exception, if the child action exits in a way which -- indicates an error. Errors occur asynchronously, when the output -- string is evaluated. You must detect errors by yourself, by calling -- getProcessStatus. -- -- In case the action doesn't replace the child process with an external -- program, an exception may be thrown out of the action. This results in -- an error message on stderr. This means that the message is -- sent through the pipe, to the parent process. Then the child process -- is properly terminated. The ProcessStatus, which can be -- accessed in the parent process by getProcessStatus, is -- Exited (ExitFailure 1). The following exceptions are -- understood, and result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Unlike shells' backquote feature, lazy_pipe_from does not -- remove any trailing newline characters. The entire output of the -- action is returned. You might want to apply chomp to the -- result. -- -- See exec, pipe_to, pipe_from2, -- h_pipe_from2, lazy_pipe_from, silently. lazy_pipe_from2 :: IO a -> IO (String, ProcessID) -- | Run an IO action as a separate process, and connect to its -- stderr with a file handle. -- -- This forks a subprocess, which executes the specified action. A file -- handle, which is connected to its stderr, is returned. The -- child's ProcessID is returned as well. If the action replaces -- the child process, by calling an exec variant, it is made -- sure that its file descriptor 2 is connected to the returned file -- handle. -- -- This gives you full control of the pipe, and of the forked process. -- But you must cope with the child process by yourself. -- -- When you call getProcessStatus blockingly, you must first -- ensure that all data has been read, or close the handle. Otherwise -- you'll get a deadlock. When you close the handle before all data has -- been read, then the child gets a SIGPIPE signal. -- -- Unless you replace the child process, calling an exec -- variant, the child should let the control flow leave the action -- normally. The child process is then properly terminated, such that no -- resources, which have been duplicated by the fork, cause problems. See -- HsShellScript#subr for details. -- -- Errors can only be detected by examining the child's process status -- (using getProcessStatus). No attempt is made to create more -- meaningful exceptions, like it is done by -- runprog/subproc. If the child action throws an -- exception, an error message is printed on stderr. This means -- that the message goes through the pipe to the parent process. Then the -- child process exits with a ProcessStatus of Exited -- (ExitFailure 1). The following exceptions are understood, and -- result in corresponding messages: ArgError, -- ProcessStatus, RunError, IOError and -- ExitCode. Other exceptions result in the generic message, as -- produced by show. -- -- Example: -- --
--   (h,pid) <- h_pipe_from $ exec "/usr/bin/foo" ["bar"]
--   
-- -- See exec, pipe_from, pipe_from2, -- h_pipe_from, pipe_to, lazy_pipe_from, -- chomp, silently. h_pipe_from2 :: IO a -> IO (Handle, ProcessID) -- | Run an IO action as a separate process, and optionally connect to its -- stdin, its stdout and its stderr output -- with pipes. -- -- See pipe_from, pipe_from2, pipe_to. pipes :: IO a -> Bool -> Bool -> Bool -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessID) -- | Create a temporary file. This will create a new, empty file, with -- read-write permissions for the user, and no permissons for the group -- and others. The path consists of the specified prefix, a dot, and six -- random characters (digits and letters). -- --
--   tmp_file prefix = temp_file 6 (prefix ++ ".") ""
--   
-- -- See temp_file, tmp_dir, with_tmp_file. tmp_file :: String -> IO FilePath -- | Create a temporary directory. This will create a new directory, with -- read-write-execute permissions for the user (unless further restricted -- by the process's umask), and no permissons for the group and others. -- The path consists of the specified prefix, a dot, and six random -- characters (digits and letters). -- --
--   tmp_dir prefix = temp_dir 6 (prefix ++ ".") ""
--   
-- -- See temp_dir, tmp_file, with_tmp_dir. tmp_dir :: String -> IO FilePath -- | Create a temporary file. This will create a new, empty file, with a -- path which did not previously exist in the file system. The path -- consists of the specified prefix, a sequence of random characters -- (digits and letters), and the specified suffix. The file is created -- with read-write permissions for the user, and no permissons for the -- group and others. The ownership is set to the effective user ID of the -- process. The group ownership is set either to the effective group ID -- of the process or to the group ID of the parent directory (depending -- on filesystem type and mount options on Linux - see open(2) -- for details). -- -- See tmp_file, temp_dir, with_temp_file. temp_file :: Int -> String -> String -> IO FilePath -- | Create a temporary directory. This will create a new directory, with a -- path which did not previously exist in the file system. The path -- consists of the specified prefix, a sequence of random characters -- (digits and letters), and the specified suffix. The directory is -- normally created with read-write-execute permissions for the user, and -- no permissons for the group and others. But this may be further -- restricted by the process's umask in the usual way. -- -- The newly created directory will be owned by the effective uid of the -- process. If the directory containing the it has the set group id bit -- set, or if the filesystem is mounted with BSD group semantics, the new -- directory will inherit the group ownership from its parent; otherwise -- it will be owned by the effective gid of the process. (See -- mkdir(2)) -- -- See tmp_dir, temp_file, with_temp_dir. temp_dir :: Int -> String -> String -> IO FilePath -- | Create a temporary path. This will generate a path which does not yet -- exist in the file system. It consists of the specified prefix, a -- sequence of random characters (digits and letters), and the specified -- suffix. -- -- Avoid relying on the generated path not to exist in the file -- system. Or else you'll get a potential race condition, since some -- other process might create the path after temp_path, before -- you use it. This is a security risk. The global random number -- generator (Random.randomRIO) is used to generate the random -- characters. These might not be that random after all, and could -- potentially be guessed. Rather use temp_file or -- temp_dir. -- -- See temp_file, temp_dir. temp_path :: Int -> String -> String -> IO FilePath -- | Create and open a temporary file, perform some action with it, and -- delete it afterwards. This is a front end to the tmp_file -- function. The file and its path are created in the same way. The IO -- action is passed a handle of the new file. When it finishes - normally -- or with an exception - the file is deleted. -- -- See tmp_file, with_temp_file, with_tmp_dir. with_tmp_file :: String -> (Handle -> IO a) -> IO a -- | Create a temporary directory, perform some action with it, and delete -- it afterwards. This is a front end to the tmp_dir function. The -- directory and its path are created in the same way. The IO action is -- passed the path of the new directory. When it finishes - normally or -- with an exception - the directory is deleted. -- -- The action must clean up any files it creates inside the directory by -- itself. with_temp_dir doesn't delete any files inside, so the -- directory could be removed. If the directory isn't empty, an -- IOError results (with the path filled in). When the action -- throws an exception, and the temporary directory cannot be removed, -- then the exception is passed through, rather than replacing it with -- the IOError. (This is because it's probably exactly because of that -- exception that the directory isn't empty and can't be removed). -- --
--   with_tmp_dir prefix io = with_temp_dir 6 (prefix ++ ".") "" io
--   
-- -- See tmp_dir, with_temp_dir, with_tmp_file. with_tmp_dir :: String -> (FilePath -> IO a) -> IO a -- | Create and open a temporary file, perform some action with it, and -- delete it afterwards. This is a front end to the temp_file -- function. The file and its path are created in the same way. The IO -- action is passed a handle of the new file. When it finishes - normally -- or with an exception - the file is deleted. -- -- See temp_file, with_tmp_file, with_temp_dir. with_temp_file :: Int -> String -> String -> (Handle -> IO a) -> IO a -- | Create a temporary directory, perform some action with it, and delete -- it afterwards. This is a front end to the temp_dir function. -- The directory and its path are created in the same way. The IO action -- is passed the path of the new directory. When it finishes - normally -- or with an exception - the directory is deleted. -- -- The action must clean up any files it creates inside the directory by -- itself. with_temp_dir doesn't delete any files inside, so the -- directory could be removed. If the directory isn't empty, an -- IOError results (with the path filled in). When the action -- throws an exception, and the temporary directory cannot be removed, -- then the exception is passed through, rather than replacing it with -- the IOError. (This is because it's probably exactly because of that -- exception that the directory isn't empty and can't be removed). -- -- See temp_dir, with_tmp_dir, with_temp_file. with_temp_dir :: Int -> String -> String -> (FilePath -> IO a) -> IO a -- | One entry of mount information. This is the same as struct -- mntent from <mntent.h>. A list of these is -- returned by the functions which read mount information. -- -- See read_mounts, read_mtab, read_fstab. data Mntent Mntent :: String -> String -> String -> String -> Int -> Int -> Mntent -- | Device file ("name of mounted file system") mnt_fsname :: Mntent -> String -- | Mount point mnt_dir :: Mntent -> String -- | Which kind of file system ("see mntent.h") mnt_type :: Mntent -> String -- | Mount options ("see mntent.h") mnt_opts :: Mntent -> String -- | Dump frequency in days mnt_freq :: Mntent -> Int -- | "Pass number on parallel fsck" mnt_passno :: Mntent -> Int -- | Read mount information. This is a front end to the -- setmntent(3), getmntent(3), endmntent(3) -- system library functions. -- -- When the setmntent call fails, the errno value is -- converted to an IOError and thrown. -- -- See read_mtab, read_fstab. read_mounts :: String -> IO [Mntent] -- | Get the currently mounted file systems. -- --
--   read_mtab = read_mounts "/etc/mtab"
--   
-- -- See read_mounts. read_mtab :: IO [Mntent] -- | Get the system wide file system table. -- --
--   read_fstab = read_mounts "/etc/fstab"
--   
-- -- See read_mounts. read_fstab :: IO [Mntent] -- | Print text to stdout. -- -- This is a shorthand for putStrLn, except for stderr -- being flushed beforehand. This way normal output and error output -- appear in order, even when they aren't buffered as by default. -- -- An additional newline is printed at the end. -- --
--   outm msg = do
--      hFlush stderr
--      putStrLn msg
--   
outm :: String -> IO () -- | Print text to stdout. -- -- This is a shorthand for putStr, except for stderr -- being flushed beforehand. This way normal output and error output -- appear in order, even when they aren't buffered as by default. -- -- No newline is printed at the end. -- --
--   outm_ msg = do
--      hFlush stderr
--      putStr msg
--   
outm_ :: String -> IO () -- | Colorful log message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in cyan. Additionally, a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm_, errm, errm_. logm :: String -> IO () -- | Colorful log message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in cyan. No a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, errm, errm_. logm_ :: String -> IO () -- | Colorful error message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in red. Additionally, a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, logm_, errm_. errm :: String -> IO () -- | Colorful error message to stderr. -- -- This prints a message to stderr. When stderr is -- connected to a terminal (as determined by isatty(3)), -- additional escape sequences are printed, which make the message appear -- in red. No a newline character is output at the end. -- -- stdout is flushed beforehand. So normal output and error -- output appear in order, even when they aren't buffered as by default. -- -- See logm, logm_, errm. errm_ :: String -> IO () -- | Check if a handle is connected to a terminal. -- -- This is a front end to the isatty(3) function (see man page). -- It is useful, for instance, to determine if color escape sequences -- should be generated. isatty :: Handle -> IO Bool -- | Format an Int with leading zeros. If the string -- representation of the Inŧ is longer than the number of -- characters to fill up, this produces as many characters as needed. zeros :: Int -> Int -> String -- | Remove trailing newlines. This is silimar to perl's chomp -- procedure. chomp :: String -> String -- | Get contents of a file or of stdin. This is a simple frontend -- to hGetContents. A file name of "-" designates -- stdin. The contents are read lazily as the string is evaluated. -- -- (The handle which we read from will be in semi-closed state. Once all -- input has read, it is closed automatically (Haskell Library Report -- 11.2.1). Therefore we don't need to return it). -- --
--   lazy_contents path = do
--       h   <- if path == "-" then return stdin else openFile path ReadMode
--       hGetContents h
--   
lazy_contents :: String -> IO String -- | Get contents of a file or of stdin eagerly. This is the same -- as lazy_contents, except for the contents being read -- immediately. contents :: String -> IO String -- | This is an interface to the POSIX glob function, which does -- wildcard expansion in paths. The list of matched paths is returned. -- It's empty for no match (rather than the original pattern). In case -- anything goes wrong (such as permission denied), an IOError is thrown. -- -- This does not do tilde expansion, which is done (among many -- unwanted other things) by wordexp. The only flag used for the -- call to glob is GLOB_ERR. -- -- The behaviour in case of non-existing path components is inconsistent -- in the GNU version of the underlying glob function. glob -- /doesnt_exist/foo will return the empty list, whereas -- glob /doesnt_exist/* causes a No such file or -- directory IOError. -- -- See man pages glob(3) and wordexp(3). glob :: String -> IO [String] -- | Error reporting wrapper for the main function. This catches -- any HsShellScript generated exceptions, and IOErrors, prints -- an error message and exits with exitFailure. The -- main function typically looks like this: -- --
--   main = mainwrapper $ do ...
--   
-- -- The exceptions caught are ArgError, RunError, -- ProcessStatus and IOError. mainwrapper :: IO a -> IO a -- | Read the global system error number. This is the POSIX errno -- value. This function is redundant. Use -- Foreign.C.Error.getErrno instead. errno :: IO Errno -- | Generate an error message from an errno value. This is the -- POSIX strerror system library function. -- -- See the man page strerror(3). strerror :: Errno -> IO String -- | Print error message corresponding to the specified errno -- error number. This is similar to the POSIX system library function -- perror. -- -- See the man page perror(3). perror' :: Errno -> String -> IO () -- | Print error message corresponding to the global errno error -- number. This is the same as the POSIX system library function -- perror. -- -- See the man page perror(3). perror :: String -> IO () -- | Print a message to stderr and exit with an exit code -- indicating an error. -- --
--   failIO msg = hPutStrLn stderr msg >> exitFailure
--   
failIO :: String -> IO a -- | Modify an IO action to return the exit code of a failed program call, -- instead of throwing an exception. -- -- This is used to modify the error reporting behaviour of an IO action -- which uses 'run'/'runprog' or 'call'/'subproc'. When an external -- program exits with an exit code which indicates an error, normally an -- exception is thrown. After exitcode has been applied, the -- exit code is retruned instead. -- -- The caught exceptions are RunError and ProcessStatus. -- Termination by a signal is still reported by an exception, which is -- passed through. -- -- Example: ec <- exitcode $ runprog "foo" ["bar"] -- -- See runprog, subproc, run, call. exitcode :: IO () -> IO ExitCode -- | Create and throw an IOError from the current errno -- value, an optional handle and an optional file name. -- -- This is an extended version of the Foreign.C.Error.throwErrno -- function from the GHC libraries, which additionally allows to specify -- a handle and a file name to include in the IOError thrown. -- -- See Foreign.C.Error.throwErrno, -- Foreign.C.Error.errnoToIOError. throwErrno' :: String -> Maybe Handle -> Maybe FilePath -> IO a -- | Convert an IOError to a string. -- -- There is an instance declaration of IOError in Show -- in the GHC.IO library, but show_ioerror produces a -- more readable, and more complete, message. show_ioerror :: IOError -> String -- | In case the specified action throws an IOError, fill in its filename -- field. This way, more useful error messages can be produced. -- -- Example: -- --
--   -- Oh, the GHC libraries neglect to fill in the file name
--   executeFile' prog a b c =
--      fill_in_filename prog $ executeFile prog a b c
--   
-- -- See fill_in_location, add_location. fill_in_filename :: String -> IO a -> IO a -- | In case the specified action throws an IOError, fill in its location -- field. This way, more useful error messages can be produced. -- -- Example: -- --
--   my_fun a b c = do
--      -- ...
--      fill_in_location "my_fun" $  -- Give the caller a more useful location information in case of failure
--         rename "foo" "bar"
--      -- ...
--   
-- -- See fill_in_filename. fill_in_location :: String -> IO a -> IO a -- | In case the specified action throws an IOError, add a line to its -- location field. This way, more useful error messages can be produced. -- The specified string is prepended to the old location, separating it -- with a newline from the previous location, if any. When using this -- thoroughly, you get a reverse call stack in IOErrors. -- -- Example: -- --
--   my_fun =
--      add_location "my_fun" $ do
--         -- ...
--   
-- -- See fill_in_filename, fill_in_location. add_location :: String -> IO a -> IO a