redirecting stdin/stdout

Simon Marlow
Wed, 21 Aug 2002 11:19:37 +0100

> I would like to be able to semi-permanently redirect stdout
> particularly.  That is, say something like:
> main =3D do
>   h <- openFile "myoutput" WriteMode
>   setStdOut h
>   ..crux of the program..
>   hClose h
> where any call which uses stdout either explicitly or=20
> implicitly (through
> putStr and the like) is redirecto to h.
> I didn't see anything of this sort in either the std libs IO or in the
> GHC.IO/IOBase modules...would such a thingbe possible?

Yes, it is entirely possible to do this, and in fact we used to have
such a thing (withStdout, withStderr) which got dropped when I
re-implemented the I/O system.  It's not immediately clear what the
interface should be, though.  If we have

	setStdout :: Handle -> IO ()

what happens to the original handle?  It's unfortunately not possible to
make stdout then be equal (in the =3D=3D sense) to the handle passed in,
although stdout would from then on behave like the other handle.  Since
in Haskell it is illegal to have two handles that refer to the same
file, without the handles being equal, the original handle would have to
be closed.

Also there's a slight complication caused by GHC's representation of
handles.  Some handles have two independent "sides" to cope with the
fact that a read/write stream (eg. a socket) needs two separate buffers.
It wouldn't be possible to do setStdout with a stream-type Handle (or
perhaps you just get the output side of the stream Handle).