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)
commit7526dfb7b5a0389d1442df96f1cfb2b7173649ed (patch)
treefb22b91d4f6acc638d2a4d80366274d61b9bb7c9 /generic/tclIO.c
parenta2fb498f19ef2cc63056bb932b942f0c1c407e93 (diff)
parent09c394df7d97291aecb28a07a6c5de3f0814a341 (diff)
downloadtcl-7526dfb7b5a0389d1442df96f1cfb2b7173649ed.zip
tcl-7526dfb7b5a0389d1442df96f1cfb2b7173649ed.tar.gz
tcl-7526dfb7b5a0389d1442df96f1cfb2b7173649ed.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;
+ }
}
/*