On Sun, Aug 12, 2012 at 6:18 PM, Niklas Hambüchen <mail at nh2.me> wrote:
> I just came across the fact that running
>> createProcess (proc "asdfasdf" [])
>> with non-existing command "asdfasdf" returns perfectly fine handles.
> I would expect an exception.
> You can even hGetContents on stdout: You just get "".
>> I find this highly counter-intuitive. Is this intended?
Yes, I ran into the same thing a while back. The problem is that the
subprocess has already been forked off before it runs exec() and finds
out the file doesn't exist. The reason python reports the right error
is that it sets up a pipe from child to parent to communicate just
this error. It's more friendly, but on the other hand the
implementation is more complicated.
If you don't want to hack up the whole send-exception-over-the-pipe
thing, the easiest thing to do is to wait for the processes's return
code. If you don't want to do that, you can at least have the
subproces log, e.g.:
loggedProcess :: Process.CreateProcess -> IO (Maybe IO.Handle,
Maybe IO.Handle, Maybe IO.Handle, Process.ProcessHandle)
loggedProcess create = do
r@(_, _, _, pid) <- Process.createProcess create
Concurrent.forkIO $ do
code <- Process.waitForProcess pid
case code of
Exit.ExitFailure c -> notice $
"subprocess " ++ show (binaryOf create) ++ " failed: "
++ if c == 127 then "binary not found" else show c
_ -> return ()
return r
where
binaryOf create = case Process.cmdspec create of
Process.RawCommand fn _ -> fn
Process.ShellCommand cmd -> fst $ break (==' ') cmd
As an aside, I've had the idea to at some point go look at the latest
python's version of the subprocess module and see about porting it to
haskell, or at least make sure the haskell version doesn't suffer from
problems fixed in the python one. They went through a lot of
iterations trying to get it right (and earlier python versions are
broken in one way or another) and we might as well build on their
work.