re-opening a closed stdin?

Glynn Clements glynn.clements@virgin.net
Thu, 21 Nov 2002 07:47:35 +0000


Bernard James POPE wrote:

> There's probably a really obvious answer to this, but I can't find it.
> 
> Is there any way in GHC to reopen stdin if it has been closed?
> 
> You may wonder why I'd want this. Well I'm writing a debugger
> for Haskell 98 (*) and my debugger wants to do some interaction on the terminal
> _after_ the user's program has run. If the user's program puts stdin into
> a closed or semi-closed state then that causes trouble for my debugger.
> 
> What I'd like to do is close stdin after the end of the user's program,
> flush any input waiting in the buffer, then reopen it fresh for reading.
> 
> If this can't be easily done perhaps there is another solution you can think
> of.

As others have pointed out, you can (on Unix at least) duplicate the
underlying descriptor. However, this may affect the semantics of
closing that descriptor (e.g. a TCP socket isn't "closed" at the TCP
layer until *all* corresponding descriptors have been closed).

Also, you can't (AFAICT) re-assign Haskell's stdin globally operation
in the manner of ANSI C's freopen(), although you can re-assign it
locally using IOExts.withStdin.

If you need to "really" close stdin (i.e. you can't duplicate the
descriptor), it may not be possible to reopen it, e.g. if it is an
unnamed pipe, a file which has since been deleted, a socket etc. Even
if it is technically possible, you may not always be able to determine
exactly how to reopen it, e.g. if it was a file, what was its
pathname? However, for the specific case of a terminal on Unix, you
can use Posix.getTerminalName; re-opening that will typically work.

-- 
Glynn Clements <glynn.clements@virgin.net>