From: <no...@so...> - 2001-05-22 01:57:18
|
Bugs item #419685, was updated on 2001-04-27 19:12 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=110894&aid=419685&group_id=10894 Category: Channel Types Group: 8.3.3 Status: Open Resolution: None Priority: 5 Submitted By: Michael Kraus (mmg_kraus) Assigned to: Andreas Kupries (andreas_kupries) Summary: Problem with [file channels] if std channels not available Initial Comment: This occurs whenever Tcl could not initialize the standard channels (e.g. when it's running as a Windows NT service). Without any other open channels, [file channels] returns an empty list, which is correct. As soon as the first channel (e.g. a socket) is opened, it is registered as stdin, the next one as stdout, the third one as stderr. [file channels] returns {stdin stdout stderr}. Any additional open channel is returned with its Tcl name, e.g. sock123. The problem is that I don't know how to prevent the first three sockets to be registered as the standard channels, and that [file channels sock*] does not return the list of all open sockets. (As a workaround, I create three dummy channels that do nothing.) The man page for TclGetStdChannel sort of talks about that behavior, but only if "one of the standard channels is set to NULL, either by calling Tcl_SetStdChannel with a null channel argument, or by calling Tcl_Close on the channel". Since I'm doing pure Tcl here, it's hard to figure out what happens internally. Is this really the desired behavior of Tcl? Looking at tclIO.c, I find that in Tcl_GetStdChannel() the statement "tsdPtr->stdinInitialized = 1" is done unconditionally, even when the preceeding "tsdPtr- >stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN)" returns NULL. This is the reason why, at the end of Tcl_CreateChannel(), the first programatically created channel is automatically registered as stdin, the next as stdout etc., even though these standard channels weren't really initialized (because they couldn't be obtained). This conflicts with the documentation, since neither Tcl_SetStdChannel() was called with NULL, nor was Tcl_Close() called. Proposed fix: In TclGetStdChannel(), do the "tsdPtr- >stdinInitialized = 1" only when TclpGetDefaultStdChannel(TCL_STDIN) returned != NULL (and similar for stdout and stderr). That is, move those lines down a bit into the already existing if() statements. Is this the right solution (or is there not even a problem ;-)? Diff for tclIO.c: 332d331 < tsdPtr->stdinInitialized = 1; 343a343 > tsdPtr->stdinInitialized = 1; 353d352 < tsdPtr->stdoutInitialized = 1; 354a354 > tsdPtr->stdoutInitialized = 1; 364d363 < tsdPtr->stderrInitialized = 1; 365a365 > tsdPtr->stderrInitialized = 1; ---------------------------------------------------------------------- >Comment By: Jeffrey Hobbs (hobbs) Date: 2001-05-21 18:57 Message: Logged In: YES user_id=72656 It is a standard convention that when the std channels are closed, the next following channels to be opened will be assumed as new std channels. The question here is really whether we are correctly handling the std channels when they aren't initially opened. I believe this would also affect Tcl when run as a unix daemon in certain cases, and the logic should be checked there. I guess it is plausible to argue that the behavior is still correct, and the docs need updating with "or the std channels were unable to be created at startup". However, I can see the aliasing behavior to be very disconcerting. My initial suggestion is that the valid way to work this would be: if {[llength [file channels std*]] != 3} { # create bogus channels to add up to 3 } ---------------------------------------------------------------------- Comment By: Michael Kraus (mmg_kraus) Date: 2001-05-02 19:34 Message: Logged In: YES user_id=206503 The patch works as expected (I tested this before I created this bug report and did it again today). I get my standard channels in a regular application (well, [gets stdin] in wish doesn't work with or without patch), and I get a clean [file channels] list when it runs as a service. I don't see why a standard channel is considered initialized when the function to obtain it returned NULL (essentially saying that I didn't get the standard channel). Guess it's just a little bug. ---------------------------------------------------------------------- Comment By: Andreas Kupries (andreas_kupries) Date: 2001-05-02 07:30 Message: Logged In: YES user_id=75003 Please test your patch with a local copy of the tcl core. I believe that with your patch an interpreter like tclsh or wish will not initiialize its standard channels at all, even if they are available. We have here an undocumented dependency between the tcl library and the application using it. The library expects that the first three channels opened by the application are the standard channels. This is true for tclsh and wish but obviously not for the NT service wrapper. Another workaround might be to define a "null" channel type and have the NT service wrapper create three such null channels. We should update the documentation too. ---------------------------------------------------------------------- You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=110894&aid=419685&group_id=10894 |