re-opening a closed stdin?

Simon Marlow simonmar@microsoft.com
Thu, 21 Nov 2002 10:42:42 -0000


> Simon Marlow writes:
> > I've been thinking about duplicating/replacing Handles for a while.
> > Here's  a possible interface:
> >=20
> >   -- |Returns a duplicate of the original handle, with its=20
> own buffer
> >   -- and file pointer.  The original handle's buffer is flushed,
> > including
> >   -- discarding any input data, before the handle is duplicated.
> >   hDuplicate :: Handle -> IO Handle
> >   -- |Makes the second handle a duplicate of the first handle.  The
> >   -- second handle will be closed first, if it is not already.
> >   hDuplicateTo :: Handle -> Handle -> IO ()
>=20
> I'm not too sure of the issues here. Some examples that use=20
> them would be helpful.=20

Well, I can redirect stdout like this:

  > hPutStrLn stdout "foo"
  foo
  > h <- openFile "/tmp/foo" WriteMode
  > :!cat /tmp/foo
  > hPutStrLn h "bar"
  > :!cat /tmp/foo
  > hFlush h
  > :!cat /tmp/foo
  bar
  > hDuplicateTo h stdout
  > putStrLn "wibble"
  > :!cat /tmp/foo
  bar
  wibble
  >

(note that it was GHCi that set stdout into NoBuffering mode after the
hDuplicateTo).

> The only suggestion I'd make is that the names be something=20
> with handle in them:
>=20
>    huDupHandle, hDupHandleTo

Hmm, I chose the names to be consistent with the rest of the IO library,
where anything beginning with 'h' is assumed to act on a Handle.

> > The remaining questions are:
> >  - Should you be allowed to duplicate a Handle which refers
> >    to a file opened in WriteMode?  Haskell 98 forbids having
> >    two Handles pointing to the same file opened for writing,
> >    but IMHO it's quite a reasonable thing to do.  If we don't allow
> >    this, then there needs to be another version of hDuplicateTo
> >    which invalidates the original Handle.
>=20
> Why does Haskell 98 make this restriction (I don't think that=20
> the library report says why)?

One reason, I think, is lazy I/O(*).  It's to stop you accidentally
writing to a file which is being read from lazilly and getting
unexpected results.

Cheers,
	Simon

(*) kill it! die! die!