From: <no...@so...> - 2001-12-13 01:18:46
|
Bugs item #439114, was opened at 2001-07-06 09:52 You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=110894&aid=439114&group_id=10894 Category: 24. Channel System Group: 8.4a3 Status: Open Resolution: None Priority: 5 Submitted By: Christopher Nelson (chris_nelson) >Assigned to: Andreas Kupries (andreas_kupries) Summary: Channel buffering affects [close] status Initial Comment: When running a child process on a open pipe, the buffering of the channel appears to affect the [catch] of the [close] of the channel on [eof]. I'll attach a script which reproduce this problem. A C program which can be used to demonstrate it is: #include <stdio.h> int main(int argc,char **argv) { fprintf(stderr, "child.c : About To Exit NonZero...\n"); exit(33); } When run in Tcl 8.2, the parent process correctly gets the child's exit status. When run in Tcl, the child process appears to always succeed. urchin{53}hyper/v5.0.3/eofError > /usr/local/bin/tclsh8.2 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 9311 33 PtiExec(FioStatus):1 % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 9312 33 PtiExec(FioStatus):1 % urchin{54}hyper/v5.0.3/eofError > /usr/local/bin/tclsh8.4 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 9316 33 PtiExec(FioStatus):1 % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 0 from catch of close errorCode:CHILDSTATUS 9316 33 PtiExec(FioStatus):0 ---------------------------------------------------------------------- Comment By: Christopher Nelson (chris_nelson) Date: 2001-07-13 08:19 Message: Logged In: YES user_id=107514 OK. The problem seems to be in PipeCloseProc which says: if (pipePtr->isNonBlocking || TclInExit()) { /* * If the channel is non-blocking or Tcl is being cleaned up, just * detach the children PIDs, reap them (important if we are in a * dynamic load module), and discard the errorFile. */ Tcl_DetachPids(pipePtr->numPids, pipePtr->pidPtr); Tcl_ReapDetachedProcs(); if (pipePtr->errorFile) { TclpCloseFile(pipePtr->errorFile); } } else { /* * Wrap the error file into a channel and give it to the cleanup * routine. */ if (pipePtr->errorFile) { errChan = Tcl_MakeFileChannel( (ClientData) GetFd(pipePtr->errorFile), TCL_READABLE); } else { errChan = NULL; } result = TclCleanupChildren(interp, pipePtr->numPids, pipePtr->pidPtr, errChan); } The first clause isn't specific enough, we only want to discard or ignore the child's status if the child is still running. If the pipe is nonblocking BUT the child is done, we _can_ (and should!) get the child's exit status. I'm looking into how to determine if the child is done or not. ---------------------------------------------------------------------- Comment By: Christopher Nelson (chris_nelson) Date: 2001-07-13 06:55 Message: Logged In: YES user_id=107514 I guess I _was_ seeing aborts but I was ignoring them and could get rid of them by removing an unnecessary command: fconfigure stdout -buffering none -blocking 0 -translation binary I see that dropping the child status showed up in 8.2.3 and that I should look at tclUnixPipe.c. Thanks. ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2001-07-12 15:38 Message: Logged In: YES user_id=80530 OK, the particular change between 8.2.2 and 8.3.3 releases that changed the behavior is that noted in the Changelog: 1999-11-29 Jeff Hobbs <ho...@sc...> * unix/tclUnixPipe.c: fixed PipeBlockModeProc to properly set isNonBlocking flag on pipe. [Bug: 1356 710] removed spurious fcntl call from PipeBlockModeProc You can restore the 8.2.2 behavior by commenting out line 836 of revision 1.12 of unix/tclUnixPipe.c . Just tested that on the HEAD revision. That's just information, not a recommendation. FYI, Bugs 1356 and 710 are now known as Bugs 218588 and 218492, respectively. ---------------------------------------------------------------------- Comment By: Don Porter (dgp) Date: 2001-07-12 15:16 Message: Logged In: YES user_id=80530 Thanks for including the test scripts. They help a lot. Now the bad news. Your test scripts fail on all releases of Tcl that I've tested: $ tclsh7.6 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:$::errorCode can't wait for variable "::PtiExec(FioDone)": would wait forever % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:$::errorCode can't wait for variable "::PtiExec(FioDone)": would wait forever % exit $ tclsh8.0 % info patch 8.0.5 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 16053 33 PtiExec(FioStatus):1 % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 16054 33 PtiExec(FioStatus):1 % Blocking channel driver did not block on input Abort $ tclsh8.1 % info patch 8.1.1 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 16057 33 PtiExec(FioStatus):1 % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 16058 33 PtiExec(FioStatus):1 % $ Note that the script aborts tclsh8.1, but there is no panic message this time. This same behavior is also observed in 8.2.0 and 8.2.1 and 8.2.2. Then in 8.2.3: $ tclsh8.2 % info patch 8.2.3 % source t.tcl % works child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 1 from catch of close errorCode:CHILDSTATUS 25060 33 PtiExec(FioStatus):1 % fails child.c : About To Exit NonZero... <<>>Got EOF on file3 Set FioStatus to 0 from catch of close errorCode:CHILDSTATUS 25060 33 PtiExec(FioStatus):0 % $ Now the [close] doesn't throw an error, which seems to be the bug you are reporting, so that misbehavior first showed up in Tcl 8.2.3, but notice the tclsh still aborts! That behavior is also exhbited by 8.3.3 and 8.4a3, and I'm assuming also all the 8.3.x and 8.4ax releases. Except for the aborting, that's what you report for 8.4a3 as well. You don't see aborts? So, anyway, I'd look into the changes between 8.2.2 and 8.2.3 for the cause of the change in behavior of [close], but I don't see any version of Tcl (on Solaris 8) for which your scripts will work. ---------------------------------------------------------------------- You can respond by visiting: http://sourceforge.net/tracker/?func=detail&atid=110894&aid=439114&group_id=10894 |