summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-01 15:13:46 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-01 15:13:46 (GMT)
commitd3c1978e070d0b1a990192e884cde57de81c43cb (patch)
treefb22b91d4f6acc638d2a4d80366274d61b9bb7c9 /generic/tclIO.c
parent19292d74bf125d60197fb9390b46ebb213e6d895 (diff)
parentabd9269a041e4bf2bf41d48bab0035e0be511cd3 (diff)
downloadtcl-d3c1978e070d0b1a990192e884cde57de81c43cb.zip
tcl-d3c1978e070d0b1a990192e884cde57de81c43cb.tar.gz
tcl-d3c1978e070d0b1a990192e884cde57de81c43cb.tar.bz2
merge trunk
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c35
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;
+ }
}
/*