On Wed, 18 Jan 2006, Dimitry Golubovsky wrote:

> Is it possible to redirect a Handle (say stdout) somewhere only within
> a running thread (started with forkIO) not touching the same handle
> for the main and other threads?

I think it's fairly simple, if I have understood your requirement.
I assume we are talking about UNIX or similar platform.  You don't
need to really modify stdout at all, it's more effective to accomplish
the redirection at a lower lever, with file descriptors.

>          ...  fdToHandle is not good because
> I need to modify the `stdout' only for that thread, not to create a
> new Handle.

Indeed, so instead of fdToHandle, you want dupTo, which will redirect
unit 1 in the process' OS level table.  Standard input, output and
error are really 0, 1, and 2 at the UNIX system level;  stdout etc.
are just process level language library constructs that add buffers.

Note the flushes in my example.  The first may be necessary to avoid
copying buffered data into the fork, which would cause it to appear
twice.  The second is a work-around for a bug that was mentioned here
only a day or two ago.

        Donn Cave, [EMAIL PROTECTED]

module Main (main) where
import System.IO (hFlush, stdout)
import System.Posix.IO
import System.Posix.Process

redirect :: FilePath -> IO () -> IO ()
redirect file fn = do
        fd <- openFd file WriteOnly (Just 420) defaultFileFlags
        x <- dupTo fd 1
        closeFd fd
        fn
        hFlush stdout

main = do
        hFlush stdout
        pid <- forkProcess $ redirect "test.out" $ putStrLn "howdy"
        st <- getProcessStatus True False pid
        putStrLn ("status " ++ (show st))


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

Reply via email to