diff options
author | dgp <dgp@users.sourceforge.net> | 2014-05-01 15:13:46 (GMT) |
---|---|---|
committer | dgp <dgp@users.sourceforge.net> | 2014-05-01 15:13:46 (GMT) |
commit | d3c1978e070d0b1a990192e884cde57de81c43cb (patch) | |
tree | fb22b91d4f6acc638d2a4d80366274d61b9bb7c9 /generic/tclIO.c | |
parent | 19292d74bf125d60197fb9390b46ebb213e6d895 (diff) | |
parent | abd9269a041e4bf2bf41d48bab0035e0be511cd3 (diff) | |
download | tcl-d3c1978e070d0b1a990192e884cde57de81c43cb.zip tcl-d3c1978e070d0b1a990192e884cde57de81c43cb.tar.gz tcl-d3c1978e070d0b1a990192e884cde57de81c43cb.tar.bz2 |
merge trunk
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 35 |
1 files changed, 27 insertions, 8 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 0087526..776ff12 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -164,6 +164,7 @@ typedef struct CloseCallback { static ChannelBuffer * AllocChannelBuffer(int length); static void PreserveChannelBuffer(ChannelBuffer *bufPtr); static void ReleaseChannelBuffer(ChannelBuffer *bufPtr); +static int IsShared(ChannelBuffer *bufPtr); static void ChannelTimerProc(ClientData clientData); static int CheckChannelErrors(ChannelState *statePtr, int direction); @@ -2311,6 +2312,13 @@ ReleaseChannelBuffer( } ckfree(bufPtr); } + +static int +IsShared( + ChannelBuffer *bufPtr) +{ + return bufPtr->refCount > 1; +} /* *---------------------------------------------------------------------- @@ -2341,6 +2349,9 @@ RecycleBuffer( /* * Do we have to free the buffer to the OS? */ + if (IsShared(bufPtr)) { + mustDiscard = 1; + } if (1 || mustDiscard) { ReleaseChannelBuffer(bufPtr); @@ -4576,12 +4587,12 @@ Tcl_GetsObj( chanPtr = statePtr->topChanPtr; */ bufPtr = statePtr->inQueueHead; - if (bufPtr == NULL) { - Tcl_Panic("Tcl_GetsObj: restore reached with bufPtr==NULL"); + if (bufPtr != NULL) { + bufPtr->nextRemoved = oldRemoved; + bufPtr = bufPtr->nextPtr; } - bufPtr->nextRemoved = oldRemoved; - for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) { + for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) { bufPtr->nextRemoved = BUFFER_PADDING; } CommonGetsCleanup(chanPtr); @@ -4722,6 +4733,9 @@ TclGetsObjBinary( goto restore; } bufPtr = statePtr->inQueueTail; + if (bufPtr == NULL) { + goto restore; + } } dst = (unsigned char *) RemovePoint(bufPtr); @@ -4834,12 +4848,12 @@ TclGetsObjBinary( restore: bufPtr = statePtr->inQueueHead; - if (bufPtr == NULL) { - Tcl_Panic("TclGetsObjBinary: restore reached with bufPtr==NULL"); + if (bufPtr) { + bufPtr->nextRemoved = oldRemoved; + bufPtr = bufPtr->nextPtr; } - bufPtr->nextRemoved = oldRemoved; - for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) { + for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) { bufPtr->nextRemoved = BUFFER_PADDING; } CommonGetsCleanup(chanPtr); @@ -4994,6 +5008,11 @@ FilterInputBytes( } bufPtr = statePtr->inQueueTail; gsPtr->bufPtr = bufPtr; + if (bufPtr == NULL) { + gsPtr->charsWrote = 0; + gsPtr->rawRead = 0; + return -1; + } } /* |