
Is there a bug in the GHC implementation of the popen function that manifests itself when more than 4k is written to the pipe? I'm trying to reproduce in Haskell the standard UNIX shell pipe idiom: cat 4097 | cat where 4097 is a file containing 4097 bytes. My Haskell code looks as follows: -- snip -- import Posix import IO import System main :: IO () main = do sequence_ $ map printChunk chunks printChunk :: String -> IO () printChunk str = do (find_output, _, _) <- popen "cat" [] (Just str) (cat_output, _, _) <- popen "cat" [] (Just find_output) putStrLn cat_output putStrLn $ show (length str) lengths = [4095,4096..] str = repeat 'a' chunks = zipWith take lengths (repeat str) -- end snip -- I get two pieces of output, one for each of the 4095 and 4096 bytes, but nothing for 4097 bytes, the program just hangs. Is this some bizarre feature of lazy evaluation, or a mistake in the way that popen is implemented (or both)? I'm using ghc-5.04.3 on linux 2.4.20-8 (Red Hat 9). Thanks, Mark. _________________________________________________________________ On the move? Get Hotmail on your mobile phone http://www.msn.co.uk/mobile

On Mon, May 05, 2003 at 11:10:51AM +0100, Mark Preston wrote:
Is there a bug in the GHC implementation of the popen function that manifests itself when more than 4k is written to the pipe?
I'm trying to reproduce in Haskell the standard UNIX shell pipe idiom:
cat 4097 | cat
where 4097 is a file containing 4097 bytes.
I'd say that popen is trying to write too much data to the pipe and running into the pipe limit. Really it should create a separate thread for writing to the pipe (which is what I do...), so that it can feed the pipe a little data at a time. The problem is that while a pipe looks like a normal file, it is one to which a write may block, or if you use nonblocking IO, the write may need to keep trying... so I'd say that yes, it is a bug in popen, but a rather tricky one to fix in a portable manner. I suppose in the posix library one can assume that one is in a posix system and comfortably use fork on the C side, which is what I do. I only know about this because I spent all Saturday morning struggling with this very issue, except that I was using ffi and C to communicate with the pipes. If you're interested in my solution (which is an embarrassingly ugly one), I'd be happy to share it with you. I guess you could also look a the code at the following: http://www.abridgegame.org/cgi-bin/darcs?darcs** See the patch whose name starts with "ugly code", with the relevant code being in the inappropriately chosen files Curl.hs and hscurl.c. In particular, you could look at the haskell function runPipe, which I think does basically what you are trying to do. -- David Roundy http://www.abridgegame.org/darcs
participants (2)
-
David Roundy
-
Mark Preston