Proposal: overhaul System.Process

Simon Marlow marlowsd at gmail.com
Wed Apr 23 14:29:42 EDT 2008


David Roundy wrote:
> On Tue, Apr 22, 2008 at 7:54 PM, John Meacham <john at repetae.net> wrote:
>> On Tue, Apr 22, 2008 at 07:45:38PM -0700, Don Stewart wrote:
>>  > Finding a good type that encourages the kind of "correctness" approach
>>  > to handling errors that we like in Haskell would be good though --
>>  > if we can improve safety, cheaply, let's do it!
>>
>>  It seems more verbose and ambiguous than safe, because now you have to
>>  look up the documentation to figure out what the difference between
>>  (Left (ExitSuccess,s)) and (Right s) is, taking up precious, precious
>>  mindspace to remembering it and introducing another place a bug can be
>>  introduced. Code clarity does a lot more for correctness (and
>>  debugability) than dubious measures to improve some idea of safety.
> 
> Personally, I'd rather have a version that just throws an exception
> when the exit code is non-zero.  As Duncan mentioned, this is usually
> what you want to do.  Given that the IO monad already has pretty nice
> (and flexible) error handling, and that this is only a convenience
> function, which is easily implemented in terms of createProcess, it
> seems like we should make it actually be convenient.  Using Either for
> error handling means that we can't use this for "simple" cases where
> the right thing is to fail when the function fails.  Using a tuple as
> the output means that for "simple" cases, folks will almost always do
> the wrong thing, which is to ignore errors.

Ok, here's the new proposal.

readProcess
     :: FilePath                 -- ^ command to run
     -> [String]                 -- ^ any arguments
     -> String                   -- ^ standard input
     -> IO String                -- ^ stdout + stderr

readProcessMayFail
     :: FilePath                 -- ^ command to run
     -> [String]                 -- ^ any arguments
     -> String                   -- ^ standard input
     -> IO (ExitCode,String)     -- ^ exitcode, and stdout + stderr

It turns out to be dead easy to bind stderr and stdout to the same pipe. 
After a couple of minor tweaks the following now works:

   createProcess (proc cmd args){ std_out = CreatePipe,
                                  std_err = UseHandle stdout }

So now we have:

Prelude System.Process> readProcessMayFail "ls" ["/foo"] ""
(ExitFailure 2,"ls: /foo: No such file or directory\n")
Prelude System.Process> readProcess "ls" ["/foo"] ""
*** Exception: readProcess: ls: failed

Look ok?

Incedentally, for those that know of such things, should readProcess do 
the same signal management that system currently does?  That is, ignore 
SIGINT and SIGQUIT in the parent and restore them to the default in the 
child?

Cheers,
	Simon



More information about the Libraries mailing list