Donn Cave wrote:
On Thu, 21 Sep 2006, George Brewster wrote:


I'm just tried writing a function to allow convenient embedding of shell
commands, but I'm running into behavior I don't really understand somewhere at the intersection of lazy evaluation, IO, and threading.


You may also find some unwelcome surprises in the area of pipes and
buffered I/O, that aren't specifically about Haskell.  Are you on a
UNIX platform?

I "rewrote" your function by removing both instances of forkIO, and
it worked about like I expected.  (The last one encounters an error
"broken pipe" when it tries to write "there" to the "echo hi" shell
process, because that process exits instead of reading from its input.)

I can't say whether you really need forkIO, or whether it's really going
to do what you need - not only do I not know enough about the thread
model, neither do I know what you're really trying to do.

        Donn Cave, [EMAIL PROTECTED]

Yup, I'm on linux. My goal is to have a function which gives me a lazy string which is the output of a shell command, and takes a string as input. In particular, I'd like the shell command to behave lazily (read only as much input as is needed, and write only as much output as needed), so things like this work (should terminate and print a few lines of "hi"):

main = sh "yes hi" "there" >>= sh "head" >>= putStrLn

I tried your suggestion out (remove forkIO), and when I do that, this example returns but doesn't print anything. Interestingly, my original implementation usually behaves this way also, but occasionally works as I would like. I had forked a seperate thread for writing the input string to the command so that the writing wouldn't block if the process filled up its write buffer and read buffer before we were done writing the string to it -- this doesn't seem to really have worked for me though.

For reference, here is the funciton in question:

sh :: String -> String -> IO String
sh cmd = \input ->
         do (stdin, stdout, _, pid) <- runInteractiveCommand cmd
            forkIO $ hPutStr stdin input >> hClose stdin
            forkIO $ waitForProcess pid >> return ()
            hGetContents stdout

-George

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to