
Uwe Schmidt wrote:
in the ghc-6.4 release the posix module is deprecated. I'm looking for a replacement and tried the System.Process functions. the following first try does not work for large files. it blocks if the file "long.file" does not fit into one os-buffer. then cat blocks and therefor waitForProcess blocks
------------------------------------
module Main where
import IO import System import System.Process
main :: IO () main = do (inpH, outH, errH, pH) <- runInteractiveProcess "cat" ["long.file"] Nothing Nothing hClose inpH res <- hGetContents outH errs <- hGetContents errH
rc <- waitForProcess pH
Two relevant axioms: 1. Haskell's lazy I/O is only good for "simple, stupid programs". It fails miserably when dealing with more complex I/O scenarios (e.g. any situation where it matters as to *when* you read the data). 2. Implementing "coroutines" as two processes communicating with each other by a pair of pipes (i.e. exactly what runInteractiveProcess does) is prone to deadlock if either reads or writes are delayed. Common variations on problem #2 (in any language) are: a) With the "send request, read response" idiom, if you forget to disable buffering or flush buffers, you get deadlock. b) If you try to write too much data in one go, both pipes fill up and you get deadlock.
the following version works fine, but it looks very much like a hack
[snip]
is there a simple replacement for the popen using the System.Process module?
How about moving the waitForProcess call until *after* you have
consumed the data? BTW, you would have exactly the same problem with
popen, AFAICT.
More generally, don't call waitForProcess until there's at least a
possibility that the process might terminate eventually.
--
Glynn Clements