
Hi all, 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. (*) www.cs.mu.oz.au/~bjpop/buddha/ Cheers, Bernie.

In local.glasgow-haskell-users, you wrote:
Is there any way in GHC to reopen stdin if it has been closed?
You can call 'System.Posix.IO.dup stdin' and save this value. However, I think you then need to explicitely read from this fd as it is not possible to reset what GHC thinks stdin is currently to this new fd (I'll dig into this and maybe we'll get a setStdin :: Fd -> IO () from this, IIRC somebody else was asking for this, too). The other way involves opening /dev/stdin on hosts that support this (with the same limitation as above), including that that's currently not possible! base/GHC/Handle.hs needs a little bit of convincing (which I'm currently doing) for this to work. Volker -- http://www-i2.informatik.rwth-aachen.de/stolz/ *** PGP *** S/MIME

You can call 'System.Posix.IO.dup stdin' and save this value. However, I think you then need to explicitely read from this fd as it is not possible to reset what GHC thinks stdin is currently to this new fd (I'll dig into this and maybe we'll get a setStdin :: Fd -> IO () from this, IIRC somebody else was asking for this, too).
How does this interact with Simon's proposal for hDuplicate? Thanks for your help, Bernie.

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
participants (4)
-
Bernard James POPE
-
Glynn Clements
-
Mark Carroll
-
Volker Stolz