
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 putStrLn ("rc: " ++ show rc) putStrLn ("stdout: " ++ res) putStrLn ("stderr: " ++ errs) exitWith rc ---------------------- the following version works fine, but it looks very much like a hack --------------------- module Main where import IO import System import System.Process main :: IO () main = do (inpH, outH, errH, pH) <- runInteractiveProcess "cat" ["long.filel"] Nothing Nothing hClose inpH res <- hGetContents outH errs <- hGetContents errH if (length $! res) == 0 -- hack !!! then return () else return () if (length $! errs) /= 0 -- hack !!! then return () else return () rc <- waitForProcess pH putStrLn ("rc: " ++ show rc) putStrLn ("stdout: " ++ res) putStrLn ("stderr: " ++ errs) exitWith rc ------------------------------------- is there a simple replacement for the popen using the System.Process module? uwe -- University of Applied Sciences, Wedel, Germany http://www.fh-wedel.de/~si/index.html mail:uwe@fh-wedel.de tel:++49-4103-8048-45

On Tue, 12 Apr 2005 14:22:00 +0200, Uwe Schmidt
in the ghc-6.4 release the posix module is deprecated.
I assume you're referring to popen not being available. I hope that all of System.Posix isn't being deprecated. As far as your problem, Simon answered it well. I would suggest doing explicit I/O on pipes. Also, I have a suggest for Posix.IO. It would be nice to have something equivalent to hGetBuf and hPutBuf for Posix FDs. I can make handles and use h{Get|Put}Buf, but there is extra overhead, or I can just implement fdGetBuf and fdPutBuf. The idea is to do efficient, unbuffered I/O. Dave

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
participants (3)
-
David Brown
-
Glynn Clements
-
Uwe Schmidt