<div class="gmail_quote">On Sat, Aug 11, 2012 at 4:13 AM, Benjamin Edwards <span dir="ltr"><<a href="mailto:edwards.benj@gmail.com" target="_blank">edwards.benj@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Hello café,<div><br></div><div>I have a program that is crashing, and I have no idea why:</div><div><br></div><div><div>module Main</div><div> where</div><div><br></div><div>import System.Process (readProcessWithExitCode)</div>
<div><br></div><div><br></div><div>main :: IO ()</div><div>main = do _ <- readProcessWithExitCode "ghc-pkg" ["describe", "hoopl"] ""</div><div> putStrLn "Should never get here"</div>
</div><div><br></div><div>this is using the process package from hackage. The program crashes with </div><div><br></div><div><div>minimal-test: fd:5: hGetContents: invalid argument (invalid byte sequence)</div><div>minimal-test: thread blocked indefinitely in an MVar operation</div>
</div><div><br></div><div>inspecting the source of readProcessWithExitCode yields an obvious explanation to the MVar problem, but I don't understand why hGetContents is so offended.</div><div><br></div><div>For the lazy it is defined as follows:</div>
<div><br></div><div><div>readProcessWithExitCode</div><div> :: FilePath -- ^ command to run</div><div> -> [String] -- ^ any arguments</div><div> -> String -- ^ standard input</div>
<div> -> IO (ExitCode,String,String) -- ^ exitcode, stdout, stderr</div><div>readProcessWithExitCode cmd args input = do</div><div> (Just inh, Just outh, Just errh, pid) <-</div><div> createProcess (proc cmd args){ std_in = CreatePipe,</div>
<div> std_out = CreatePipe,</div><div> std_err = CreatePipe }</div><div><br></div><div> outMVar <- newEmptyMVar</div><div><br></div><div> -- fork off a thread to start consuming stdout</div>
<div> out <- hGetContents outh</div><div> _ <- forkIO $ C.evaluate (length out) >> putMVar outMVar ()</div><div><br></div><div> -- fork off a thread to start consuming stderr</div><div> err <- hGetContents errh</div>
<div> _ <- forkIO $ C.evaluate (length err) >> putMVar outMVar ()</div><div><br></div><div> -- now write and flush any input</div><div> when (not (null input)) $ do hPutStr inh input; hFlush inh</div><div>
hClose inh -- done with stdin</div><div><br></div><div> -- wait on the output</div><div> takeMVar outMVar</div><div> takeMVar outMVar</div><div> hClose outh</div><div> hClose errh</div><div><br></div><div>
-- wait on the process</div><div> ex <- waitForProcess pid</div><div><br></div><div> return (ex, out, err)</div></div><div><br></div><div>Now having looked at the source of ghc-pkg it is dumping it's output using putStr and friends, so that should be using my local encoding on the system, right? and so should hGetContents in my program..?</div>
<div><br></div><div>Now, for the curious: the reason I care is that this problem has effectively prevented me from using virthualenv. Sadness and woe.</div></blockquote><div><br></div><div>I would recommend using ByteStrings. There is a link to a version of readProcessWithExitCode that uses ByteString instead of String here: <a href="http://www.haskell.org/pipermail/libraries/2012-August/018263.html">http://www.haskell.org/pipermail/libraries/2012-August/018263.html</a></div>
</div><br>