summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonmar <unknown>2003-09-24 10:32:12 +0000
committersimonmar <unknown>2003-09-24 10:32:12 +0000
commit8fb92f95a80f57c9e6737755881bd08c701a42eb (patch)
tree99ca88f07d6632e42f57a2efe43b11fe8cfcbdc7
parentcf6845428c2bd19c6e52d3a7577e2d2bfe55f95c (diff)
downloadhaskell-8fb92f95a80f57c9e6737755881bd08c701a42eb.tar.gz
[project @ 2003-09-24 10:32:11 by simonmar]
If we change the terminal settings as a result of hSetBuffering or hSetEcho, then restore them again in hs_exit(). This is just good citizenship on Unixy platforms. We *don't* just automatically save the terminal settings and restore them at the end, because that would prevent implementing stty-like programs in Haskell. This scheme is a compromise that hopefully DTRT in most cases.
-rw-r--r--ghc/rts/RtsStartup.c36
1 files changed, 35 insertions, 1 deletions
diff --git a/ghc/rts/RtsStartup.c b/ghc/rts/RtsStartup.c
index 0c5c2a36cb..e2746e80de 100644
--- a/ghc/rts/RtsStartup.c
+++ b/ghc/rts/RtsStartup.c
@@ -1,5 +1,5 @@
/* -----------------------------------------------------------------------------
- * $Id: RtsStartup.c,v 1.75 2003/08/22 22:24:15 sof Exp $
+ * $Id: RtsStartup.c,v 1.76 2003/09/24 10:32:11 simonmar Exp $
*
* (c) The GHC Team, 1998-2002
*
@@ -60,12 +60,26 @@
#include <locale.h>
#endif
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
// Flag Structure
struct RTS_FLAGS RtsFlags;
// Count of how many outstanding hs_init()s there have been.
static int hs_init_count = 0;
+#if HAVE_TERMIOS_H
+// Here we save the terminal settings on the standard file
+// descriptors, if we need to change them (eg. to support NoBuffering
+// input).
+struct termios *saved_termios[3] = {NULL,NULL,NULL};
+#endif
+
/* -----------------------------------------------------------------------------
Starting up the RTS
-------------------------------------------------------------------------- */
@@ -319,6 +333,26 @@ hs_exit(void)
resetNonBlockingFd(1);
resetNonBlockingFd(2);
+#if HAVE_TERMIOS_H
+ // Reset the terminal settings on the standard file descriptors,
+ // if we changed them. See System.Posix.Internals.tcSetAttr for
+ // more details, including the reason we termporarily disable
+ // SIGTTOU here.
+ {
+ int fd;
+ sigset_t sigset, old_sigset;
+ sigemptyset(&sigset);
+ sigaddset(&sigset, SIGTTOU);
+ sigprocmask(SIG_BLOCK, &sigset, &old_sigset);
+ for (fd = 0; fd <= 2; fd++) {
+ if (saved_termios[fd] != NULL) {
+ tcsetattr(fd,TCSANOW,saved_termios[fd]);
+ }
+ }
+ sigprocmask(SIG_SETMASK, &old_sigset, NULL);
+ }
+#endif
+
#if defined(PAR)
/* controlled exit; good thread! */
shutdownParallelSystem(0);