diff options
Diffstat (limited to 'unix/tclUnixChan.c')
-rw-r--r-- | unix/tclUnixChan.c | 229 |
1 files changed, 14 insertions, 215 deletions
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 2745e9b..2081adc 100644 --- a/unix/tclUnixChan.c +++ b/unix/tclUnixChan.c @@ -10,38 +10,12 @@ * 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.77.2.6 2007/12/04 16:55:54 dgp Exp $ + * RCS: @(#) $Id: tclUnixChan.c,v 1.77.2.7 2008/03/07 22:05:10 dgp Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ #include "tclIO.h" /* To get Channel type declaration. */ -/* - * sys/ioctl.h has already been included by tclPort.h. Including termios.h or - * termio.h causes a bunch of warning messages because some duplicate (but not - * contradictory) #defines exist in termios.h and/or termio.h - */ - -#undef NL0 -#undef NL1 -#undef CR0 -#undef CR1 -#undef CR2 -#undef CR3 -#undef TAB0 -#undef TAB1 -#undef TAB2 -#undef XTABS -#undef BS0 -#undef BS1 -#undef FF0 -#undef FF1 -#undef ECHO -#undef NOFLSH -#undef TOSTOP -#undef FLUSHO -#undef PENDIN - #define SUPPORTS_TTY #undef DIRECT_BAUD @@ -65,22 +39,6 @@ # define GETCONTROL(fd, intPtr) ioctl((fd), TIOCMGET, (intPtr)) # define SETCONTROL(fd, intPtr) ioctl((fd), TIOCMSET, (intPtr)) - /* - * TIP #35 introduced a different on exit flush/close behavior that does - * not work correctly with standard channels on all systems. The problem - * is tcflush throws away waiting channel data. This may be necessary for - * true serial channels that may block, but isn't correct in the standard - * case. This might be replaced with tcdrain instead, but that can block. - * For now, we revert to making this do nothing, and TtyOutputProc being - * the same old FileOutputProc. - hobbs [Bug #525783] - */ - -# define BAD_TIP35_FLUSH 0 -# if BAD_TIP35_FLUSH -# define TTYFLUSH(fd) tcflush((fd), TCIOFLUSH); -# else -# define TTYFLUSH(fd) -# endif /* BAD_TIP35_FLUSH */ # ifdef FIONREAD # define GETREADQUEUE(fd, int) ioctl((fd), FIONREAD, &(int)) # elif defined(FIORDCHK) @@ -106,6 +64,9 @@ # if !defined(CRTSCTS) && defined(CNEW_RTSCTS) # define CRTSCTS CNEW_RTSCTS # endif /* !CRTSCTS&CNEW_RTSCTS */ +# if !defined(PAREXT) && defined(CMSPAR) +# define PAREXT CMSPAR +# endif /* !PAREXT&&CMSPAR */ #else /* !USE_TERMIOS */ #ifdef USE_TERMIO @@ -158,8 +119,6 @@ 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; @@ -270,8 +229,6 @@ static int TcpOutputProc(ClientData instanceData, const char *buf, int toWrite, int *errorCode); static void TcpWatchProc(ClientData instanceData, int mask); #ifdef SUPPORTS_TTY -static int TtyCloseProc(ClientData instanceData, - Tcl_Interp *interp); static void TtyGetAttributes(int fd, TtyAttrs *ttyPtr); static int TtyGetOptionProc(ClientData instanceData, Tcl_Interp *interp, const char *optionName, @@ -282,10 +239,6 @@ static unsigned long TtyGetSpeed(int baud); #endif /* DIRECT_BAUD */ static FileState * TtyInit(int fd, int initialize); static void TtyModemStatusStr(int status, Tcl_DString *dsPtr); -#if BAD_TIP35_FLUSH -static int TtyOutputProc(ClientData instanceData, - const char *buf, int toWrite, int *errorCode); -#endif /* BAD_TIP35_FLUSH */ static int TtyParseMode(Tcl_Interp *interp, const char *mode, int *speedPtr, int *parityPtr, int *dataPtr, int *stopPtr); @@ -331,13 +284,9 @@ static Tcl_ChannelType fileChannelType = { static Tcl_ChannelType ttyChannelType = { "tty", /* Type name. */ TCL_CHANNEL_VERSION_5, /* v5 channel */ - TtyCloseProc, /* Close proc. */ + FileCloseProc, /* Close proc. */ FileInputProc, /* Input proc. */ -#if BAD_TIP35_FLUSH - TtyOutputProc, /* Output proc. */ -#else /* !BAD_TIP35_FLUSH */ FileOutputProc, /* Output proc. */ -#endif /* BAD_TIP35_FLUSH */ NULL, /* Seek proc. */ TtySetOptionProc, /* Set option proc. */ TtyGetOptionProc, /* Get option proc. */ @@ -404,29 +353,11 @@ FileBlockModeProc( * TCL_MODE_NONBLOCKING. */ { FileState *fsPtr = (FileState *) instanceData; - int curStatus; -#ifndef USE_FIONBIO - curStatus = fcntl(fsPtr->fd, F_GETFL); - if (mode == TCL_MODE_BLOCKING) { - CLEAR_BITS(curStatus, O_NONBLOCK); - } else { - SET_BITS(curStatus, O_NONBLOCK); - } - if (fcntl(fsPtr->fd, F_SETFL, curStatus) < 0) { - return errno; - } - curStatus = fcntl(fsPtr->fd, F_GETFL); -#else /* USE_FIONBIO */ - if (mode == TCL_MODE_BLOCKING) { - curStatus = 0; - } else { - curStatus = 1; - } - if (ioctl(fsPtr->fd, (int) FIONBIO, &curStatus) < 0) { + if (TclUnixSetBlockingMode(fsPtr->fd, mode) < 0) { return errno; } -#endif /* !USE_FIONBIO */ + return 0; } @@ -738,94 +669,6 @@ FileGetHandleProc( } #ifdef SUPPORTS_TTY -/* - *---------------------------------------------------------------------- - * - * TtyCloseProc -- - * - * This function is called from the generic IO level to perform - * channel-type-specific cleanup when a tty based channel is closed. - * - * Results: - * 0 if successful, errno if failed. - * - * Side effects: - * Closes the device of the channel. - * - *---------------------------------------------------------------------- - */ - -static int -TtyCloseProc( - ClientData instanceData, /* Tty state. */ - Tcl_Interp *interp) /* For error reporting - unused. */ -{ -#if BAD_TIP35_FLUSH - TtyState *ttyPtr = (TtyState *) instanceData; -#endif /* BAD_TIP35_FLUSH */ - -#ifdef TTYFLUSH - TTYFLUSH(ttyPtr->fs.fd); -#endif /* TTYFLUSH */ - -#if 0 - /* - * TIP#35 agreed to remove the unsave so that TCL could be used as a - * simple stty. It would be cleaner to remove all the stuff related to - * TtyState.stateUpdated - * TtyState.savedState - * Then the structure TtyState would be the same as FileState. IMO this - * cleanup could better be done for the final 8.4 release after nobody - * complained about the missing unsave. - schroedter - */ - if (ttyPtr->stateUpdated) { - SETIOSTATE(ttyPtr->fs.fd, &ttyPtr->savedState); - } -#endif - - return FileCloseProc(instanceData, interp); -} - -/* - *---------------------------------------------------------------------- - * - * TtyOutputProc-- - * - * This function is invoked from the generic IO level to write output to - * a TTY channel. - * - * Results: - * The number of bytes written is returned or -1 on error. An output - * argument contains a POSIX error code if an error occurred, or zero. - * - * Side effects: - * Writes output on the output device of the channel if the channel is - * not designated to be closed. - * - *---------------------------------------------------------------------- - */ - -#if BAD_TIP35_FLUSH -static int -TtyOutputProc( - ClientData instanceData, /* File state. */ - const char *buf, /* The data buffer. */ - int toWrite, /* How many bytes to write? */ - int *errorCodePtr) /* Where to store error code. */ -{ - if (TclInExit()) { - /* - * Do not write data during Tcl exit. Serial port may block preventing - * Tcl from exit. - */ - - return toWrite; - } - - return FileOutputProc(instanceData, buf, toWrite, errorCodePtr); -} -#endif /* BAD_TIP35_FLUSH */ - #ifdef USE_TERMIOS /* *---------------------------------------------------------------------- @@ -912,7 +755,6 @@ TtySetOptionProc( */ TtySetAttributes(fsPtr->fd, &tty); - ((TtyState *) fsPtr)->stateUpdated = 1; return TCL_OK; } @@ -1704,10 +1546,10 @@ TtyInit( int initialize) { TtyState *ttyPtr; + int stateUpdated = 0; ttyPtr = (TtyState *) ckalloc((unsigned) sizeof(TtyState)); GETIOSTATE(fd, &ttyPtr->savedState); - ttyPtr->stateUpdated = 0; if (initialize) { IOSTATE iostate = ttyPtr->savedState; @@ -1718,7 +1560,7 @@ TtyInit( iostate.c_cflag & CREAD || iostate.c_cc[VMIN] != 1 || iostate.c_cc[VTIME] != 0) { - ttyPtr->stateUpdated = 1; + stateUpdated = 1; } iostate.c_iflag = IGNBRK; iostate.c_oflag = 0; @@ -1741,7 +1583,7 @@ TtyInit( * Only update if we're changing anything to avoid possible blocking. */ - if (ttyPtr->stateUpdated) { + if (stateUpdated) { SETIOSTATE(fd, &iostate); } } @@ -1969,36 +1811,15 @@ TcpBlockModeProc( * TCL_MODE_NONBLOCKING. */ { TcpState *statePtr = (TcpState *) instanceData; - int setting; -#ifndef USE_FIONBIO - setting = fcntl(statePtr->fd, F_GETFL); if (mode == TCL_MODE_BLOCKING) { CLEAR_BITS(statePtr->flags, TCP_ASYNC_SOCKET); - CLEAR_BITS(setting, O_NONBLOCK); } else { SET_BITS(statePtr->flags, TCP_ASYNC_SOCKET); - SET_BITS(setting, O_NONBLOCK); } - if (fcntl(statePtr->fd, F_SETFL, setting) < 0) { + if (TclUnixSetBlockingMode(statePtr->fd, mode) < 0) { return errno; } -#else /* USE_FIONBIO */ - if (mode == TCL_MODE_BLOCKING) { - CLEAR_BITS(statePtr->flags, TCP_ASYNC_SOCKET); - setting = 0; - if (ioctl(statePtr->fd, (int) FIONBIO, &setting) == -1) { - return errno; - } - } else { - SET_BITS(statePtr->flags, TCP_ASYNC_SOCKET); - setting = 1; - if (ioctl(statePtr->fd, (int) FIONBIO, &setting) == -1) { - return errno; - } - } -#endif /* !USE_FIONBIO */ - return 0; } @@ -2026,7 +1847,6 @@ WaitForConnect( { int timeOut; /* How long to wait. */ int state; /* Of calling TclWaitForFile. */ - int flags; /* fcntl flags for the socket. */ /* * If an asynchronous connect is in progress, attempt to wait for it to @@ -2043,14 +1863,7 @@ WaitForConnect( state = TclUnixWaitForFile(statePtr->fd, TCL_WRITABLE | TCL_EXCEPTION, timeOut); if (!(statePtr->flags & TCP_ASYNC_SOCKET)) { -#ifndef USE_FIONBIO - flags = fcntl(statePtr->fd, F_GETFL); - CLEAR_BITS(flags, O_NONBLOCK); - (void) fcntl(statePtr->fd, F_SETFL, flags); -#else /* USE_FIONBIO */ - flags = 0; - (void) ioctl(statePtr->fd, FIONBIO, &flags); -#endif /* !USE_FIONBIO */ + (void) TclUnixSetBlockingMode(statePtr->fd, TCL_MODE_BLOCKING); } if (state & TCL_EXCEPTION) { return -1; @@ -2536,14 +2349,7 @@ CreateSocket( */ if (async) { -#ifndef USE_FIONBIO - curState = fcntl(sock, F_GETFL); - SET_BITS(curState, O_NONBLOCK); - status = fcntl(sock, F_SETFL, curState); -#else /* USE_FIONBIO */ - curState = 1; - status = ioctl(sock, FIONBIO, &curState); -#endif /* !USE_FIONBIO */ + status = TclUnixSetBlockingMode(sock, TCL_MODE_NONBLOCKING); } else { status = 0; } @@ -2565,14 +2371,7 @@ CreateSocket( */ if (async) { -#ifndef USE_FIONBIO - curState = fcntl(sock, F_GETFL); - CLEAR_BITS(curState, O_NONBLOCK); - status = fcntl(sock, F_SETFL, curState); -#else /* USE_FIONBIO */ - curState = 0; - status = ioctl(sock, FIONBIO, &curState); -#endif /* !USE_FIONBIO */ + status = TclUnixSetBlockingMode(sock, TCL_MODE_BLOCKING); } } } |