Attachment "unixchantype.patch" to
ticket [219137ffff]
added by
dkf
2001-06-06 19:51:49.
Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.457
diff -u -r1.457 ChangeLog
--- ChangeLog 2001/06/04 01:25:04 1.457
+++ ChangeLog 2001/06/06 12:47:14
@@ -1,3 +1,12 @@
+2001-06-06 Donal K. Fellows <[email protected]>
+
+ * unix/tclUnixChan.c (TtyInit,TclpOpenFileChannel,
+ Tcl_MakeFileChannel,TclpGetDefaultStdChannel): Alterations so that
+ the standard channels - stdin, stdout and stderr - have the
+ correct type and fconfigure options. This required making the
+ initialisation of serial lines a little more sophisticated to
+ make the console behave correctly in interactive mode...
+
2001-06-03 Jeff Hobbs <[email protected]>
* generic/tclUtil.c (Tcl_DStringAppendElement): patch to save an
Index: unix/tclUnixChan.c
===================================================================
RCS file: /cvsroot/tcl/tcl/unix/tclUnixChan.c,v
retrieving revision 1.19
diff -u -r1.19 tclUnixChan.c
--- unix/tclUnixChan.c 2000/10/28 00:29:58 1.19
+++ unix/tclUnixChan.c 2001/06/06 12:47:14
@@ -217,7 +217,7 @@
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 @@
* 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 @@
translation = "auto crlf";
channelTypePtr = &ttyChannelType;
- fsPtr = TtyInit(fd);
+ fsPtr = TtyInit(fd, 1);
} else
#endif /* SUPPORTS_TTY */
{
@@ -1428,17 +1435,18 @@
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.
* If the fd is used, but the mode doesn't match, return NULL.
@@ -1453,7 +1461,24 @@
}
#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 @@
#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 @@
* 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;
}