From a8cd463081a31a16d36465ac7ef5bdee81bd256f Mon Sep 17 00:00:00 2001
From: Jeff Hobbs <hobbs@users.sourceforge.net>
Date: Fri, 26 May 2006 19:44:07 +0000
Subject: [PATCH] 	* generic/vfs.c (VfsOpenFileChannel): handle closing
 channels that 	were inherited as std channels. [Bug 1468291]

---
 ChangeLog     |  5 +++++
 generic/vfs.c | 25 ++++++++++++++++++++++---
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index be3ba22..c04a2ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2006-05-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/vfs.c (VfsOpenFileChannel): handle closing channels that
+	were inherited as std channels. [Bug 1468291]
+
 2006-03-12  Vince Darley <vincentdarley@sourceforge.net>
 
 	* library/ftpvfs.tcl: provide caching of listings to improve
diff --git a/generic/vfs.c b/generic/vfs.c
index 7db4160..c5285a2 100644
--- a/generic/vfs.c
+++ b/generic/vfs.c
@@ -1393,8 +1393,23 @@ VfsOpenFileChannel(cmdInterp, pathPtr, mode, permissions)
 	 * Tcl_DetachChannel to do this for us.  We must use the
 	 * correct interpreter.
 	 */
+	if (Tcl_IsStandardChannel(chan)) {
+	    /*
+	     * If we have somehow ended up with a VFS channel being a std
+	     * channel, it is likely auto-inherited, which we need to reverse.
+	     * [Bug 1468291]
+	     */
+	    if (chan == Tcl_GetStdChannel(TCL_STDIN)) {
+		Tcl_SetStdChannel(NULL, TCL_STDIN);
+	    } else if (chan == Tcl_GetStdChannel(TCL_STDOUT)) {
+		Tcl_SetStdChannel(NULL, TCL_STDOUT);
+	    } else if (chan == Tcl_GetStdChannel(TCL_STDERR)) {
+		Tcl_SetStdChannel(NULL, TCL_STDERR);
+	    }
+	    Tcl_UnregisterChannel(NULL, chan);
+	}
 	Tcl_DetachChannel(interp, chan);
-	
+
 	if (closeCallback != NULL) {
 	    VfsChannelCleanupInfo *channelRet = NULL;
 	    channelRet = (VfsChannelCleanupInfo*) 
@@ -1439,7 +1454,9 @@ VfsCloseProc(ClientData clientData) {
      * callback will fail, so we register the channel (this allows
      * the Tcl code to use the channel's string-name).
      */
-    Tcl_RegisterChannel(interp, chan);
+    if (!Tcl_IsStandardChannel(chan)) {
+	Tcl_RegisterChannel(interp, chan);
+    }
 
     if (!(Tcl_GetChannelMode(chan) & TCL_READABLE)) {
 	/* 
@@ -1465,7 +1482,9 @@ VfsCloseProc(ClientData clientData) {
      * already being closed.  So, we do the same trick as above to
      * unregister it without cleanup.
      */
-    Tcl_DetachChannel(interp, chan);
+    if (!Tcl_IsStandardChannel(chan)) {
+	Tcl_DetachChannel(interp, chan);
+    }
 
     Tcl_RestoreResult(interp, &savedResult);
     ckfree((char*)channelRet);
-- 
2.23.0