Tcl Source Code

Artifact [04f3b04f07]
Login

Artifact 04f3b04f07789e538f43b0a2df9998d4077bada0:

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;
 }