
dons@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?
Hi, on my computer your code (with >> return ()-s inserted) works with at most 135168=132*1024 bytes of input: import System.Exit import System.IO import System.Process 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) return (output,errput,e) 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. -- Feri.