[Haskell-cafe] Re: On improving libraries: wanted list

Wagner Ferenc 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 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.

More information about the Haskell-Cafe mailing list