From c7b81182cc496c61309904a116c693a3dedc6382 Mon Sep 17 00:00:00 2001 From: dkf Date: Thu, 25 Oct 2001 15:50:49 +0000 Subject: Fix for bug 471374; Tcl only resets serial ports on exit now if it has updated their settings first. --- ChangeLog | 9 +++++++++ unix/tclUnixChan.c | 44 +++++++++++++++++++++++++++++--------------- 2 files changed, 38 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f6d8a6..31c672a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2001-10-25 Donal K. Fellows + + * unix/tclUnixChan.c: Added stateUpdated member to struct TtyState. + (TtyCloseProc,TtySetOptionProc,TtyInit): Use stateUpdated member + of TtyState to decide whether it is necessary to reset a serial + port when Tcl closes it. Blindly resetting can cause Tcl to be + sent an unexpected SIGTSTP when it is executing in the background + [Bug 471374, reported by Chris Nelson] + 2001-10-22 Andreas Kupries * doc/ObjectType.3: Minor documentation fix, reported by David diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 9f31e8f..dbdf453 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclUnixChan.c,v 1.21 2001/08/30 08:53:15 vincentdarley Exp $ + * RCS: @(#) $Id: tclUnixChan.c,v 1.22 2001/10/25 15:50:49 dkf Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ @@ -92,6 +92,8 @@ typedef struct FileState { typedef struct TtyState { FileState fs; /* Per-instance state of the file * descriptor. Must be the first field. */ + int stateUpdated; /* Flag to say if the state has been + * modified and needs resetting. */ IOSTATE savedState; /* Initial state of device. Used to reset * state when device closed. */ } TtyState; @@ -632,7 +634,9 @@ TtyCloseProc(instanceData, interp) TtyState *ttyPtr; ttyPtr = (TtyState *) instanceData; - SETIOSTATE(ttyPtr->fs.fd, &ttyPtr->savedState); + if (ttyPtr->stateUpdated) { + SETIOSTATE(ttyPtr->fs.fd, &ttyPtr->savedState); + } return FileCloseProc(instanceData, interp); } @@ -676,6 +680,7 @@ TtySetOptionProc(instanceData, interp, optionName, value) */ TtySetAttributes(fsPtr->fd, &tty); + ((TtyState *) fsPtr)->stateUpdated = 1; return TCL_OK; } else { return Tcl_BadChannelOption(interp, optionName, "mode"); @@ -1227,34 +1232,43 @@ TtyInit(fd, initialize) ttyPtr = (TtyState *) ckalloc((unsigned) sizeof(TtyState)); GETIOSTATE(fd, &ttyPtr->savedState); - + ttyPtr->stateUpdated = 0; if (initialize) { IOSTATE iostate = ttyPtr->savedState; -#ifdef USE_TERMIOS - iostate.c_iflag = IGNBRK; - iostate.c_oflag = 0; - iostate.c_lflag = 0; - iostate.c_cflag |= CREAD; - iostate.c_cc[VMIN] = 1; - iostate.c_cc[VTIME] = 0; -#endif /* USE_TERMIOS */ - -#ifdef USE_TERMIO +#if defined(USE_TERMIOS) || defined(USE_TERMIO) + if (iostate.c_iflag != IGNBRK || + iostate.c_oflag != 0 || + iostate.c_lflag != 0 || + iostate.c_cflag & CREAD || + iostate.c_cc[VMIN] != 1 || + iostate.c_cc[VTIME] != 0) { + ttyPtr->stateUpdated = 1; + } iostate.c_iflag = IGNBRK; iostate.c_oflag = 0; iostate.c_lflag = 0; iostate.c_cflag |= CREAD; iostate.c_cc[VMIN] = 1; iostate.c_cc[VTIME] = 0; -#endif /* USE_TERMIO */ +#endif /* USE_TERMIOS|USE_TERMIO */ #ifdef USE_SGTTY + if ((iostate.sg_flags & (EVENP | ODDP)) || + !(iostate.sg_flags & RAW)) { + ttyPtr->stateUpdated = 1; + } iostate.sg_flags &= (EVENP | ODDP); iostate.sg_flags |= RAW; #endif /* USE_SGTTY */ - SETIOSTATE(fd, &iostate); + /* + * Only update if we're changing anything to avoid possible + * blocking. + */ + if (ttyPtr->stateUpdated) { + SETIOSTATE(fd, &iostate); + } } return &ttyPtr->fs; -- cgit v0.12