diff options
-rw-r--r-- | generic/tclIO.c | 5 | ||||
-rw-r--r-- | generic/tclIOCmd.c | 3 | ||||
-rw-r--r-- | generic/tclIORChan.c | 31 |
3 files changed, 28 insertions, 11 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index dd4d489..d69a3d9 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -2612,6 +2612,7 @@ FlushChannel( if (errorCode == EINTR) { errorCode = 0; + ReleaseChannelBuffer(bufPtr); continue; } @@ -2633,6 +2634,7 @@ FlushChannel( UpdateInterest(chanPtr); } errorCode = 0; + ReleaseChannelBuffer(bufPtr); break; } @@ -2694,6 +2696,7 @@ FlushChannel( */ DiscardOutputQueued(statePtr); + ReleaseChannelBuffer(bufPtr); continue; } else { wroteSome = 1; @@ -4031,6 +4034,7 @@ WillRead( { if (chanPtr->typePtr == NULL) { /* Prevent read attempts on a closed channel */ + DiscardInputQueued(chanPtr->state, 0); Tcl_SetErrno(EINVAL); return -1; } @@ -4211,6 +4215,7 @@ Write( if (IsBufferFull(bufPtr)) { if (FlushChannel(NULL, chanPtr, 0) != 0) { + ReleaseChannelBuffer(bufPtr); return -1; } flushed += statePtr->bufSize; diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c index 14910d7..084cefb 100644 --- a/generic/tclIOCmd.c +++ b/generic/tclIOCmd.c @@ -349,7 +349,8 @@ Tcl_GetsObjCmd( if (objc == 3) { if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr, TCL_LEAVE_ERR_MSG) == NULL) { - return TCL_ERROR; + code = TCL_ERROR; + goto done; } Tcl_SetObjResult(interp, Tcl_NewIntObj(lineLen)); } else { diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c index 94428bb..12fa4a0 100644 --- a/generic/tclIORChan.c +++ b/generic/tclIORChan.c @@ -1111,6 +1111,7 @@ ReflectClose( ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in * this interp */ Tcl_HashEntry *hPtr; /* Entry in the above map */ + Tcl_ChannelType *tctPtr; if (TclInThreadExit()) { /* @@ -1149,6 +1150,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); return EOK; } @@ -1213,6 +1219,11 @@ ReflectClose( } #endif + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); #ifdef TCL_THREADS } @@ -2170,14 +2181,6 @@ FreeReflectedChannel( { Channel *chanPtr = (Channel *) rcPtr->chan; - if (chanPtr->typePtr != &tclRChannelType) { - /* - * Delete a cloned ChannelType structure. - */ - - ckfree(chanPtr->typePtr); - chanPtr->typePtr = NULL; - } Tcl_Release(chanPtr); Tcl_DecrRefCount(rcPtr->name); Tcl_DecrRefCount(rcPtr->methods); @@ -2873,11 +2876,13 @@ ForwardProc( * call upon for the driver. */ - case ForwardedClose: + case ForwardedClose: { /* * No parameters/results. */ + Tcl_ChannelType *tctPtr; + if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) { ForwardSetObjError(paramPtr, resObj); } @@ -2902,8 +2907,14 @@ ForwardProc( Tcl_GetChannelName(rcPtr->chan)); Tcl_DeleteHashEntry(hPtr); - Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); + tctPtr = ((Channel *)rcPtr->chan)->typePtr; + if (tctPtr && tctPtr != &tclRChannelType) { + ckfree((char *)tctPtr); + ((Channel *)rcPtr->chan)->typePtr = NULL; + } + Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel); break; + } case ForwardedInput: { Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead); |