diff options
Diffstat (limited to 'unix')
-rw-r--r-- | unix/tclUnixChan.c | 87 |
1 files changed, 58 insertions, 29 deletions
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c index 1bf9d54..d31cc6c 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.19 2000/10/28 00:29:58 hobbs Exp $ + * RCS: @(#) $Id: tclUnixChan.c,v 1.20 2001/06/18 13:13:23 dkf Exp $ */ #include "tclInt.h" /* Internal definitions for Tcl. */ @@ -217,7 +217,7 @@ static void TtyGetAttributes _ANSI_ARGS_((int fd, static int TtyGetOptionProc _ANSI_ARGS_((ClientData instanceData, Tcl_Interp *interp, char *optionName, Tcl_DString *dsPtr)); -static FileState * TtyInit _ANSI_ARGS_((int fd)); +static FileState * TtyInit _ANSI_ARGS_((int fd, int initialize)); static int TtyParseMode _ANSI_ARGS_((Tcl_Interp *interp, CONST char *mode, int *speedPtr, int *parityPtr, int *dataPtr, int *stopPtr)); @@ -1201,54 +1201,61 @@ TtyParseMode(interp, mode, speedPtr, parityPtr, dataPtr, stopPtr) * Given file descriptor that refers to a serial port, * initialize the serial port to a set of sane values so that * Tcl can talk to a device located on the serial port. + * Note that no initialization happens if the initialize flag + * is not set; this is necessary for the correct handling of + * UNIX console TTYs at startup. * * Results: - * None. + * A pointer to a FileState suitable for use with Tcl_CreateChannel + * and the ttyChannelType structure. * * Side effects: * Serial device initialized to non-blocking raw mode, similar to - * sockets. All other modes can be simulated on top of this in Tcl. + * sockets (if initialize flag is non-zero.) All other modes can + * be simulated on top of this in Tcl. * *--------------------------------------------------------------------------- */ static FileState * -TtyInit(fd) +TtyInit(fd, initialize) int fd; /* Open file descriptor for serial port to * be initialized. */ + int initialize; { - IOSTATE iostate; TtyState *ttyPtr; ttyPtr = (TtyState *) ckalloc((unsigned) sizeof(TtyState)); GETIOSTATE(fd, &ttyPtr->savedState); - iostate = ttyPtr->savedState; + 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; + 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 - 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; + 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 */ #ifdef USE_SGTTY - iostate.sg_flags &= (EVENP | ODDP); - iostate.sg_flags |= RAW; + iostate.sg_flags &= (EVENP | ODDP); + iostate.sg_flags |= RAW; #endif /* USE_SGTTY */ - SETIOSTATE(fd, &iostate); + SETIOSTATE(fd, &iostate); + } return &ttyPtr->fs; } @@ -1354,7 +1361,7 @@ TclpOpenFileChannel(interp, fileName, modeString, permissions) translation = "auto crlf"; channelTypePtr = &ttyChannelType; - fsPtr = TtyInit(fd); + fsPtr = TtyInit(fd, 1); } else #endif /* SUPPORTS_TTY */ { @@ -1428,16 +1435,17 @@ Tcl_MakeFileChannel(handle, mode) FileState *fsPtr; char channelName[16 + TCL_INTEGER_SPACE]; int fd = (int) handle; + Tcl_ChannelType *channelTypePtr; #ifdef DEPRECATED ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey); #endif + int socketType = 0; + int argLength = sizeof(int); if (mode == 0) { return NULL; } - sprintf(channelName, "file%d", fd); - /* * Look to see if a channel with this fd and the same mode already exists. @@ -1453,7 +1461,24 @@ Tcl_MakeFileChannel(handle, mode) } #endif - fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState)); +#ifdef SUPPORTS_TTY + if (isatty(fd)) { + fsPtr = TtyInit(fd, 0); + channelTypePtr = &ttyChannelType; + sprintf(channelName, "serial%d", fd); + } else +#endif + if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (VOID *)&socketType, + &argLength) == 0 && socketType == SOCK_STREAM) { + /* + * The mode parameter gets lost here, unfortunately. + */ + return Tcl_MakeTcpClientChannel((ClientData) fd); + } else { + channelTypePtr = &fileChannelType; + fsPtr = (FileState *) ckalloc((unsigned) sizeof(FileState)); + sprintf(channelName, "file%d", fd); + } #ifdef DEPRECATED fsPtr->nextPtr = tsdPtr->firstFilePtr; @@ -1461,9 +1486,9 @@ Tcl_MakeFileChannel(handle, mode) #endif fsPtr->fd = fd; fsPtr->validMask = mode | TCL_EXCEPTION; - fsPtr->channel = Tcl_CreateChannel(&fileChannelType, channelName, + fsPtr->channel = Tcl_CreateChannel(channelTypePtr, channelName, (ClientData) fsPtr, mode); - + return fsPtr->channel; } @@ -2515,7 +2540,11 @@ TclpGetDefaultStdChannel(type) * Set up the normal channel options for stdio handles. */ - Tcl_SetChannelOption(NULL, channel, "-translation", "auto"); + if (Tcl_GetChannelType(channel) == &fileChannelType) { + Tcl_SetChannelOption(NULL, channel, "-translation", "auto"); + } else { + Tcl_SetChannelOption(NULL, channel, "-translation", "auto crlf"); + } Tcl_SetChannelOption(NULL, channel, "-buffering", bufMode); return channel; } |