|
2005-04-19
| ||
| 22:24 | • Closed ticket [1184104fff]: Child Process Wish.exe Refuses to Close STDIO Channels plus 8 other changes artifact: 411791628d user: dgp | |
| 15:17 | • Ticket [1184104fff]: 1 change artifact: 2d6acbfa3a user: dkf | |
|
2005-04-18
| ||
| 21:50 | • Ticket [1184104fff]: 4 changes artifact: 4eb84a76b6 user: dgp | |
|
2005-04-16
| ||
| 20:51 | • Ticket [1184104fff]: 4 changes artifact: 02b524aa1c user: m_schrumpf | |
| 11:35 | • Ticket [1184104fff]: 4 changes artifact: 190511e2d0 user: dgp | |
| 10:52 | • Ticket [1184104fff]: 4 changes artifact: 249a3a850b user: m_schrumpf | |
| 10:45 | • Ticket [1184104fff]: 4 changes artifact: bd5daf66af user: nobody | |
| 10:43 | • Ticket [1184104fff]: 4 changes artifact: fa269be522 user: nobody | |
| 01:20 | • New ticket [1184104fff]. artifact: 49d6f94c1a user: nobody | |
| Ticket UUID: | 1184104 | |||
| Title: | Child Process Wish.exe Refuses to Close STDIO Channels | |||
| Type: | Patch | Version: | None | |
| Submitter: | nobody | Created on: | 2005-04-16 01:20:43 | |
| Subsystem: | 54. [console] | Assigned To: | dgp | |
| Priority: | 5 Medium | Severity: | ||
| Status: | Closed | Last Modified: | 2005-04-19 22:24:07 | |
| Resolution: | Duplicate | Closed By: | dgp | |
| Closed on: | 2005-04-19 15:24:07 | |||
| Description: |
The problem lies in tkConsole/Tk_InitConsoleChannels() within ShouldUseConsoleChannel(). When wish.exe is started by double-clicking in Windows Explorer, or by typing "wish" on the command line, it is detached from the calling process' stdio channels. When ShouldUseConsoleChannel() is called, it returns 1, bailing out early at handle==INVALID_HANDLE_VALUE, ==0, or FILE_TYPE_UNKNOWN. However, if the parent process does NOT relinquish control of stdio channels, as with using CreateProcess() and inheritable pipes assigned to the child's stdio, then ShouldUseConsoleChannel() makes it all the way to the call to Tcl_GetStdChannel(), which increments the refCount. By the end of initialization, refCount is at 3. When [close] is called on a given channel, DetachChannel() decrements refCount to 2. CheckForStdChannelsBeingClosed() sees a refCount of 2, and refuses to set refCount to 0, [incorrectly] presuming that a second interp has the stdio channel open. The fix is to decrement the refCount immediately if Tcl_GetStdChannel() is reached. | |||
| User Comments: |
dgp added on 2005-04-19 22:24:07:
Logged In: YES user_id=80530 re-opened as Bug 1186042 dgp added on 2005-04-18 21:50:32: Logged In: YES user_id=80530 If you submit a new report while logged in, you'll be able to attach the patch. m_schrumpf added on 2005-04-16 20:51:24: Logged In: YES user_id=1260469 Define "start again." You want to close/abandon this report, and then I resubmit? dgp added on 2005-04-16 11:35:01: Logged In: YES user_id=80530 what a shame you weren't logged in when you posted the original report. Then you could have attached the file. Want to start again? m_schrumpf added on 2005-04-16 10:52:56: Logged In: YES user_id=1260469 (Sorry about the first, poorly-formatted pasted-in patch. That's what happens when you move a text file from Windows to Unix without checking the EOL characters.) nobody added on 2005-04-16 10:45:11: Logged In: NO
--- tkConsole.cMon Aug 05 00:30:38 2002
+++ tkConsole.cFri Apr 15 16:14:25 2005
@@ -12,6 +12,9 @@
*
* RCS: @(#) $Id: tkConsole.c,v 1.18 2002/08/05 04:30:38
dgp Exp $
*/
+
+#include "tclPort.h"
+#include "tclIO.h"
#include "tk.h"
#include <string.h>
@@ -115,6 +118,8 @@
int mode;
char *bufMode;
HANDLE handle;
+Tcl_Channel chan;
+ChannelState *statePtr;
switch (type) {
case TCL_STDIN:
@@ -186,9 +191,24 @@
}
} else if (fileType == FILE_TYPE_UNKNOWN) {
return 1;
- } else if (Tcl_GetStdChannel(type) == NULL) {
+} else if ((chan = Tcl_GetStdChannel(type)) == NULL) {
return 1;
}
+/*
+ * Tcl_GetStdChannel is only called if wish.exe was started
+ * from a parent process that grabs pipes to stdio channels
+ * (i.e. using CreateProcess() with inheritable pipes assigned
+ * to the child's stdio).
+ * A succesful call to Tcl_GetStdChannel increments refCount,
+ * which leaves the total count at 2 when calling
+ * CheckForStdChannelsBeingClosed(), preventing wish.exe from
+ * actually closing the IO handles when [close] is called on
+ * the last instance of a channel.
+ * Since the parent process is probably expecting these to be
+ * closed when wish.exe calls [close], decrement the count
here.
+ */
+statePtr = ((Channel *) (chan))->state;
+statePtr->refCount--;
return 0;
}
@@ -197,7 +217,7 @@
* Mac should always use a console channel, Unix should if
it's trying to
*/
-#define ShouldUseConsoleChannel(chan) (1)
+#define ShouldUseConsoleChannel(type) (1)
#endif
/*
nobody added on 2005-04-16 10:43:29: Logged In: NO
Patch file attachment didn't upload:
--- tkConsole.cMon Aug 05 00:30:38 2002
+++ tkConsole.cFri Apr 15 16:14:25 2005
@@ -12,6 +12,9 @@
*
* RCS: @(#) $Id: tkConsole.c,v 1.18 2002/08/05 04:30:38
dgp Exp $
*/
+
+#include "tclPort.h"
+#include "tclIO.h"
#include "tk.h"
#include <string.h>
@@ -115,6 +118,8 @@
int mode;
char *bufMode;
HANDLE handle;
+Tcl_Channel chan;
+ChannelState *statePtr;
switch (type) {
case TCL_STDIN:
@@ -186,9 +191,24 @@
}
} else if (fileType == FILE_TYPE_UNKNOWN) {
return 1;
- } else if (Tcl_GetStdChannel(type) == NULL) {
+} else if ((chan = Tcl_GetStdChannel(type)) == NULL) {
return 1;
}
+/*
+ * Tcl_GetStdChannel is only called if wish.exe was started
+ * from a parent process that grabs pipes to stdio channels
+ * (i.e. using CreateProcess() with inheritable pipes assigned
+ * to the child's stdio).
+ * A succesful call to Tcl_GetStdChannel increments refCount,
+ * which leaves the total count at 2 when calling
+ * CheckForStdChannelsBeingClosed(), preventing wish.exe from
+ * actually closing the IO handles when [close] is called on
+ * the last instance of a channel.
+ * Since the parent process is probably expecting these to be
+ * closed when wish.exe calls [close], decrement the count
here.
+ */
+statePtr = ((Channel *) (chan))->state;
+statePtr->refCount--;
return 0;
}
@@ -197,7 +217,7 @@
* Mac should always use a console channel, Unix should if
it's trying to
*/
-#define ShouldUseConsoleChannel(chan) (1)
+#define ShouldUseConsoleChannel(type) (1)
#endif
/*
| |||