[Haskell-cafe] How to redirect a handle within a thread (GHC 6.4.1 runtime)?

Donn Cave donn at drizzle.com
Wed Jan 18 14:32:43 EST 2006

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, donn at drizzle.com

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
        hFlush stdout

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

More information about the Haskell-Cafe mailing list