summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-06 14:43:19 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-06 14:43:19 (GMT)
commit5684837e350796f98813f2dc9cfecabb7ea2fe09 (patch)
treed357243898e1785fc60d1870f031abb95432f31f
parentd9f128a5af6973fa48e8c0a801ca19c34cb67784 (diff)
parent0fc3bdcc7e6bd2903a1e84017073bf39dff8a3ad (diff)
downloadtcl-5684837e350796f98813f2dc9cfecabb7ea2fe09.zip
tcl-5684837e350796f98813f2dc9cfecabb7ea2fe09.tar.gz
tcl-5684837e350796f98813f2dc9cfecabb7ea2fe09.tar.bz2
Merge 8.5. New test iogt-2.5 panics.
-rw-r--r--generic/tclIOGT.c15
-rw-r--r--tests/iogt.test21
2 files changed, 33 insertions, 3 deletions
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
index 29996ea..6cc33eb 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -298,7 +298,6 @@ TclChannelTransform(
}
Tcl_DStringFree(&ds);
- dataPtr->self = chan;
dataPtr->watchMask = 0;
dataPtr->mode = mode;
dataPtr->timer = NULL;
@@ -317,6 +316,7 @@ TclChannelTransform(
ReleaseData(dataPtr);
return TCL_ERROR;
}
+ Tcl_Preserve(dataPtr->self);
/*
* At last initialize the transformation at the script level.
@@ -437,6 +437,9 @@ ExecuteCallback(
break;
case TRANSMIT_DOWN:
+ if (dataPtr->self == NULL) {
+ break;
+ }
resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
@@ -444,6 +447,9 @@ ExecuteCallback(
break;
case TRANSMIT_SELF:
+ if (dataPtr->self == NULL) {
+ break;
+ }
resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
@@ -579,6 +585,8 @@ TransformCloseProc(
* General cleanup.
*/
+ Tcl_Release(dataPtr->self);
+ dataPtr->self = NULL;
ReleaseData(dataPtr);
return TCL_OK;
}
@@ -614,7 +622,7 @@ TransformInputProc(
* Should assert(dataPtr->mode & TCL_READABLE);
*/
- if (toRead == 0) {
+ if (toRead == 0 || dataPtr->self == NULL) {
/*
* Catch a no-op.
*/
@@ -1084,6 +1092,9 @@ TransformWatchProc(
* unchanged.
*/
+ if (dataPtr->self == NULL) {
+ return;
+ }
downChan = Tcl_GetStackedChannel(dataPtr->self);
Tcl_GetChannelType(downChan)->watchProc(
diff --git a/tests/iogt.test b/tests/iogt.test
index ded8bb9..50034de 100644
--- a/tests/iogt.test
+++ b/tests/iogt.test
@@ -229,7 +229,17 @@ proc id_torture {chan op data} {
clear_read {;#ignore}
flush/write -
flush/read {}
- write -
+ write {
+ global level
+ if {$level} {
+ return
+ }
+ incr level
+ testchannel unstack $chan
+ testchannel transform $chan \
+ -command [namespace code [list id_torture $chan]]
+ return $data
+ }
read {
testchannel unstack $chan
testchannel transform $chan \
@@ -580,6 +590,15 @@ test iogt-2.4 {basic I/O, mixed trail} {testchannel} {
close $fh
set x
} {}
+test iogt-2.5 {basic I/O, mixed trail} {testchannel} {
+ set ::level 0
+ set fh [open $path(dummyout) w]
+ torture -attach $fh
+ puts -nonewline $fh abcdef
+ flush $fh
+ testchannel unstack $fh
+ close $fh
+} {}
test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
proc DoneCopy {n {err {}}} {