[Haskell-cafe] Re: On improving libraries: wanted list
wferi at niif.hu
Thu Dec 14 19:14:10 EST 2006
dons at cse.unsw.edu.au (Donald Bruce Stewart) writes:
> Can't we do something like this, on top of System.Process?
> Do we need unix* stuff anymore?
on my computer your code (with >> return ()-s inserted) works with at
most 135168=132*1024 bytes of input:
import Control.Concurrent (forkIO, newEmptyMVar, putMVar, takeMVar)
import qualified Control.Exception
popen :: FilePath -> [String] -> Maybe String -> IO (String,String,ExitCode)
popen file args minput =
Control.Exception.handle (\e -> return (,show e,error (show e))) $ do
(inp,out,err,pid) <- runInteractiveProcess file args Nothing Nothing
case minput of
Just input -> hPutStr inp input >> hClose inp -- importante!
Nothing -> return ()
output <- hGetContents out
errput <- hGetContents err
forkIO (Control.Exception.evaluate (length output) >> return ())
forkIO (Control.Exception.evaluate (length errput) >> return ())
e <- Control.Exception.catch (waitForProcess pid) (\_ -> return ExitSuccess)
main = do (out,err,code) <- popen "/bin/cat"  (Just $ take 135168 input)
putStrLn $ "exit status: " ++ show code
putStrLn $ "out: " ++ show (length out) ++ " characters"
putStrLn $ "err=" ++ err
where input = concat [show n ++ "," | n<-[1..]]
One more byte, and cat blocks on writing to its pipe. No wonder,
nobody reads the other end, as our hPutStr to cat also blocks, as a
direct consequence. Moving the case beyond the forkIO-s resolves
this. Btw, why don't you close the other handles? Btw2 runCommand in
http://happs.org/HAppS/src/HAppS/Util/Common.hs takes a similar
approach with MVar-s; I wonder if they are really needed.
More information about the Haskell-Cafe