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