> And there is _no_ handle to the output of the command! An obvious hack is
> to use redirecting; here is how you implement a simple date function in
> Haskell:
>
> date :: IO String
> date =
> do system "date > /tmp/answer"
> readFile "/tmp/answer"
>
[..]
> I implemented these functions and a couple more (dealing with lazily
> generating output) in Hugs, using dynamic named pipe generation and
> redirecting. This is a hack; it would be much nicer to have a function
> like "sysInOut" builtin in Hugs (Haskell98).
There is no need (that I can see) to use named pipes... here is some
code I used (in GHC; haven't tried it in Hugs). Disclaimer: it's
*not* production code, and is ugly [I suspect it doesn't really need
two forks], but works for me. It actually does a few other things as
well, but you should be able to pick out what you need.
import IO
import Posix
import System
-- and maybe a few other things too
teeProcess :: (String -> String)
-> FilePath -> Bool -> [String] -> Maybe [(String,String)] -> IO
(ExitCode,String)
-- as executeFile, but merges stdout and stderr, outputting them together on stdout
-- (via a filter function) and also returning them as a string.
teeProcess f prog pathp args menv
= do { (pin,pout) <- createPipe
; mpid <- forkProcess
; pid <- case mpid of
Nothing -> do { mprocPid <- forkProcess
; procPid <- case mprocPid of
Nothing -> do { dupTo pout (intToFd 1)
; dupTo pout (intToFd 2)
; executeFile prog
pathp args menv
; error "teeProcess:1"
}
Just pid -> return pid
; status <- getProcessStatus True False procPid
; ec <- case status of
Just (Exited ec) -> do { fdClose pout
; return ec
}
Just (Terminated sig) -> do { raiseSignal
sig
; error
"teeProcess:2"
}
Just (Stopped sig) -> error "teeProcess:
process stopped"
Nothing -> error "teeProcess:
no info"
; exitWith ec
; error "teeProcess:3"
}
Just pid -> return pid
; fdClose pout
; hpin <- fdToHandle pin
; hSetBuffering hpin LineBuffering
; str <- hGetContents hpin -- lazily
; putStr (f str)
; status <- getProcessStatus True False pid
; ec <- case status of
Just (Exited ec) -> return ec
Just (Terminated sig) -> do { raiseSignal sig ; error "teeProcess:4" }
; return (ec,str)
}
Hope this is of use.
--KW 8-)