[project @ 2001-01-16 14:06:14 by simonmar]
authorsimonmar <unknown>
Tue, 16 Jan 2001 14:06:14 +0000 (14:06 +0000)
committersimonmar <unknown>
Tue, 16 Jan 2001 14:06:14 +0000 (14:06 +0000)
Fix a problem with our use of tcsetattr() which caused background
processes to stop when the buffering mode, or the echo status, was
changed.

tcSetAttr() is a wrapper around tcsetattr() that temporarily blocks
SIGTTOU around the call.

ghc/lib/std/cbits/echoAux.c
ghc/lib/std/cbits/setBuffering.c
ghc/lib/std/cbits/stgio.h
ghc/lib/std/cbits/tcSetAttr.c [new file with mode: 0644]

index e2b77a2..3cc6517 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: echoAux.c,v 1.3 1999/03/01 09:02:04 sof Exp $
+ * $Id: echoAux.c,v 1.4 2001/01/16 14:06:14 simonmar Exp $
  *
  * Support functions for changing echoing
  */
@@ -26,9 +26,7 @@
 #endif
 
 StgInt
-setTerminalEcho(ptr, on)
-StgForeignPtr ptr;
-StgInt on;
+setTerminalEcho(StgForeignPtr ptr, StgInt on)
 {
    IOFileObject* fo = (IOFileObject*)ptr;
    struct termios tios;
@@ -51,7 +49,7 @@ StgInt on;
      tios.c_lflag &= ~ECHO;
    }
 
-   while ( (rc = tcsetattr(fd,TCSANOW,&tios)) == -1) {
+   while ( (rc = tcSetAttr(fd,TCSANOW,&tios)) == -1) {
        if (errno != EINTR) {
            cvtErrno();
            stdErrno();
index 26bfd24..2bb240b 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: setBuffering.c,v 1.8 2000/04/14 16:19:43 rrt Exp $
+ * $Id: setBuffering.c,v 1.9 2001/01/16 14:06:14 simonmar Exp $
  *
  * hSetBuffering Runtime Support
  */
@@ -37,7 +37,6 @@ setBuffering(StgForeignPtr ptr, StgInt size)
     int input, isaterm;
     struct termios tio;
     struct stat sb;
-   
 
     /* First off, flush old buffer.. */
     if ( (fo->flags & FILEOBJ_WRITE) ) {
@@ -83,7 +82,7 @@ setBuffering(StgForeignPtr ptr, StgInt size)
            tio.c_lflag &=  ~ICANON;
            tio.c_cc[VMIN] = 1;
            tio.c_cc[VTIME] = 0;
-           if (tcsetattr(fo->fd, TCSANOW, &tio) < 0) {
+           if (tcSetAttr(fo->fd, TCSANOW, &tio) < 0) {
                cvtErrno();
                stdErrno();
                return -1;
@@ -138,7 +137,7 @@ setBuffering(StgForeignPtr ptr, StgInt size)
            return -1;
        }
        tio.c_lflag |= ICANON;
-       if (tcsetattr(fo->fd, TCSANOW, &tio) < 0) {
+       if (tcSetAttr(fo->fd, TCSANOW, &tio) < 0) {
            cvtErrno();
            stdErrno();
            return -1;
index fd5ad0d..1734b64 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: stgio.h,v 1.24 2000/11/07 10:42:57 simonmar Exp $
+ * $Id: stgio.h,v 1.25 2001/01/16 14:06:14 simonmar Exp $
  *
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1999
  *
@@ -24,28 +24,6 @@ StgAddr allocMemory__ (StgInt);
 /* closeFile.c */
 StgInt closeFile (StgForeignPtr,StgInt);
 
-/* createDirectory.c */
-StgInt createDirectory (StgByteArray);
-
-/* directoryAux.c */
-StgAddr openDir__         (StgByteArray);
-StgAddr readDir__         (StgAddr);
-StgAddr get_dirent_d_name (StgAddr);
-StgWord get_stat_st_mode  (StgAddr);
-StgInt64 get_stat_st_mtime(StgAddr);
-void     set_stat_st_mtime(StgByteArray, StgByteArray);
-StgInt  sizeof_stat       (void);
-StgInt  prim_stat         (StgAddr,StgAddr);
-StgWord const_S_IRUSR    (void);
-StgWord const_S_IWUSR    (void);
-StgWord const_S_IXUSR    (void);
-StgWord const_R_OK       (void);
-StgWord const_W_OK       (void);
-StgWord const_X_OK       (void);
-StgWord const_F_OK       (void);
-StgInt  prim_S_ISDIR     (StgWord);
-StgInt  prim_S_ISREG     (StgWord);
-
 /* echoAux.c */
 StgInt setTerminalEcho (StgForeignPtr, StgInt);
 StgInt getTerminalEcho (StgForeignPtr);
@@ -132,20 +110,10 @@ StgAddr ref_freeFileObject    (void);
 /* getBufferMode.c */
 StgInt getBufferMode (StgForeignPtr);
 
-/* getClockTime.c */
-StgInt getClockTime (StgByteArray, StgByteArray);
-StgInt  prim_getClockTime(StgByteArray, StgByteArray);
-
 /* getCPUTime.c */
 StgInt getCPUTime (StgByteArray);
 StgInt clockTicks(void);
 
-/* getCurrentDirectory.c */
-StgAddr getCurrentDirectory(void);
-
-/* getDirectoryContents.c */
-StgAddr getDirectoryContents (StgByteArray);
-
 /* getLock.c */
 int     lockFile    (int, int, int);
 int     unlockFile  (int);
@@ -169,18 +137,6 @@ StgInt     readChunk (StgForeignPtr,StgAddr,StgInt,StgInt);
 StgInt readLine  (StgForeignPtr);
 StgInt readChar  (StgForeignPtr);
 
-/* removeDirectory.c */
-StgInt removeDirectory (StgByteArray);
-
-/* removeFile.c */
-StgInt removeFile (StgByteArray);
-
-/* renameDirectory.c */
-StgInt renameDirectory (StgByteArray, StgByteArray);
-
-/* renameFile.c */
-StgInt renameFile (StgByteArray, StgByteArray);
-
 /* seekFile.c */
 StgInt seekFile  (StgForeignPtr, StgInt, StgInt, StgByteArray);
 StgInt seekFile_int64 (StgForeignPtr, StgInt, StgInt64);
@@ -202,35 +158,6 @@ StgInt showTime (StgInt, StgByteArray, StgInt, StgByteArray);
 /* system.c */
 StgInt systemCmd (StgByteArray);
 
-/* timezone.c */
-StgInt  get_tm_sec       ( StgAddr );
-StgInt  get_tm_min       ( StgAddr );
-StgInt  get_tm_hour      ( StgAddr );
-StgInt  get_tm_mday      ( StgAddr );
-StgInt  get_tm_mon       ( StgAddr );
-StgInt  get_tm_year      ( StgAddr );
-StgInt  get_tm_wday      ( StgAddr );
-StgInt  get_tm_yday      ( StgAddr );
-StgInt  get_tm_isdst     ( StgAddr );
-StgAddr prim_ZONE        ( StgAddr );
-StgInt  prim_GMTOFF      ( StgAddr );
-void    prim_SETZONE     ( StgAddr, StgAddr );
-StgInt  sizeof_word      ( void ); 
-StgInt  sizeof_struct_tm ( void );
-StgInt  sizeof_time_t    ( void );
-char*   get_ZONE         ( StgAddr );
-
-/* toLocalTime.c */
-StgInt toLocalTime (StgInt, StgByteArray, StgByteArray);
-StgInt prim_toLocalTime ( StgInt64,StgByteArray );
-
-/* toUTCTime.c */
-StgInt toUTCTime (StgInt, StgByteArray, StgByteArray);
-StgInt prim_toUTCTime ( StgInt64,StgByteArray );
-
-/* toClockSec.c */
-StgInt toClockSec (StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgInt, StgByteArray);
-
 /* writeError.c */
 StgAddr addrOf_ErrorHdrHook(void);
 void    writeErrString__ (StgAddr, StgByteArray, StgInt);
@@ -242,6 +169,12 @@ StgInt     writeFileObject (StgForeignPtr, StgInt);
 StgInt writeBuffer (StgForeignPtr, StgInt);
 StgInt  write_ (StgForeignPtr ptr, StgAddr buf, StgInt len);
 
+/* tcSetAttr.c */
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+int tcSetAttr (int fd, int options, const struct termios *tp);
+
 #endif /* ! STGIO_H */
 
 
diff --git a/ghc/lib/std/cbits/tcSetAttr.c b/ghc/lib/std/cbits/tcSetAttr.c
new file mode 100644 (file)
index 0000000..02f9fdb
--- /dev/null
@@ -0,0 +1,42 @@
+/* 
+ * (c) The GHC Team 2001
+ *
+ * $Id: tcSetAttr.c,v 1.1 2001/01/16 14:06:14 simonmar Exp $
+ *
+ * A wrapper around tcsetattr() which works for a background process.
+ */
+
+#include "Rts.h"
+#include "stgio.h"
+
+#ifdef HAVE_SIGNAL_H
+#include <signal.h>
+#endif
+
+#ifdef HAVE_TERMIOS_H
+#include <termios.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+/* tcsetattr() when invoked by a background process causes the process
+ * to be sent SIGTTOU regardless of whether the process has TOSTOP set
+ * in its terminal flags (try it...).  This function provides a
+ * wrapper which temporarily blocks SIGTTOU around the call, making it
+ * transparent.  */
+int
+tcSetAttr( int fd, int options, const struct termios *tp )
+{
+    int res;
+    sigset_t block_ttou, old_sigset;
+    
+    sigemptyset (&block_ttou);
+    sigaddset (&block_ttou, SIGTTOU);
+    sigprocmask(SIG_BLOCK, &block_ttou, &old_sigset);
+    res = tcsetattr(fd, options, tp);
+    sigprocmask(SIG_SETMASK, &old_sigset, NULL);
+
+    return res;
+}