summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-01 14:52:13 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-01 14:52:13 (GMT)
commitab0e4b9897d95d1c3f643524a08c99425055ea5e (patch)
tree054b1a32984f0bd512dcdf3a4a778311fea392db /generic/tclIO.c
parenta777eef5bbacd8802c32ce467ee9bb989486f122 (diff)
parentcf5a2fcdb5b8dd834e530641922f7ba5c841553f (diff)
downloadtcl-ab0e4b9897d95d1c3f643524a08c99425055ea5e.zip
tcl-ab0e4b9897d95d1c3f643524a08c99425055ea5e.tar.gz
tcl-ab0e4b9897d95d1c3f643524a08c99425055ea5e.tar.bz2
merge 8.5
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c41
1 files changed, 31 insertions, 10 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index bffdae4..f4c8255 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -166,6 +166,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);
@@ -2239,6 +2240,13 @@ ReleaseChannelBuffer(
}
ckfree((char *) bufPtr);
}
+
+static int
+IsShared(
+ ChannelBuffer *bufPtr)
+{
+ return bufPtr->refCount > 1;
+}
/*
*----------------------------------------------------------------------
@@ -2269,6 +2277,9 @@ RecycleBuffer(
/*
* Do we have to free the buffer to the OS?
*/
+ if (IsShared(bufPtr)) {
+ mustDiscard = 1;
+ }
if (mustDiscard) {
ReleaseChannelBuffer(bufPtr);
@@ -3142,7 +3153,8 @@ Tcl_Close(
stickyError = 0;
- if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
+ if ((statePtr->encoding != NULL)
+ && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
&& (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
statePtr->outputEncodingFlags |= TCL_ENCODING_END;
if (WriteChars(chanPtr, "", 0) < 0) {
@@ -4149,12 +4161,12 @@ Tcl_GetsObj(
restore:
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);
@@ -4284,6 +4296,9 @@ TclGetsObjBinary(
goto restore;
}
bufPtr = statePtr->inQueueTail;
+ if (bufPtr == NULL) {
+ goto restore;
+ }
}
dst = (unsigned char *) RemovePoint(bufPtr);
@@ -4396,12 +4411,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);
@@ -4556,6 +4571,11 @@ FilterInputBytes(
}
bufPtr = statePtr->inQueueTail;
gsPtr->bufPtr = bufPtr;
+ if (bufPtr == NULL) {
+ gsPtr->charsWrote = 0;
+ gsPtr->rawRead = 0;
+ return -1;
+ }
}
/*
@@ -7247,7 +7267,8 @@ Tcl_SetChannelOption(
* iso2022, the terminated escape sequence must write to the buffer.
*/
- if ((statePtr->encoding != NULL) && (statePtr->curOutPtr != NULL)
+ if ((statePtr->encoding != NULL)
+ && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
&& (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
statePtr->outputEncodingFlags |= TCL_ENCODING_END;
WriteChars(chanPtr, "", 0);