From: simonmar Date: Tue, 16 Jan 2001 14:06:14 +0000 (+0000) Subject: [project @ 2001-01-16 14:06:14 by simonmar] X-Git-Tag: Approximately_9120_patches~2884 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=ba44023202adf345a7b29af3050bfafd336b5b58;p=ghc-hetmet.git [project @ 2001-01-16 14:06:14 by simonmar] 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. --- diff --git a/ghc/lib/std/cbits/echoAux.c b/ghc/lib/std/cbits/echoAux.c index e2b77a2..3cc6517 100644 --- a/ghc/lib/std/cbits/echoAux.c +++ b/ghc/lib/std/cbits/echoAux.c @@ -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(); diff --git a/ghc/lib/std/cbits/setBuffering.c b/ghc/lib/std/cbits/setBuffering.c index 26bfd24..2bb240b 100644 --- a/ghc/lib/std/cbits/setBuffering.c +++ b/ghc/lib/std/cbits/setBuffering.c @@ -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; diff --git a/ghc/lib/std/cbits/stgio.h b/ghc/lib/std/cbits/stgio.h index fd5ad0d..1734b64 100644 --- a/ghc/lib/std/cbits/stgio.h +++ b/ghc/lib/std/cbits/stgio.h @@ -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 +#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 index 0000000..02f9fdb --- /dev/null +++ b/ghc/lib/std/cbits/tcSetAttr.c @@ -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 +#endif + +#ifdef HAVE_TERMIOS_H +#include +#endif + +#ifdef HAVE_UNISTD_H +#include +#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; +}