summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2014-05-08 03:28:56 (GMT)
committerdgp <dgp@users.sourceforge.net>2014-05-08 03:28:56 (GMT)
commit311f44633e3dab963b7705cd04ffa3a4b6c4dcce (patch)
tree691948500985fc43c2eee0e90a31e76c654c8e18 /generic
parent3f767c15a3a870d5692ae43cd6151fb86ffa2bf3 (diff)
parent5e1038193c820c5a5ae7b27886d8d3100e18ea49 (diff)
downloadtcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.zip
tcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.tar.gz
tcl-311f44633e3dab963b7705cd04ffa3a4b6c4dcce.tar.bz2
merge trunk
Diffstat (limited to 'generic')
-rw-r--r--generic/tcl.h8
-rw-r--r--generic/tclIO.c13
-rw-r--r--generic/tclIOCmd.c3
-rw-r--r--generic/tclIOGT.c15
-rw-r--r--generic/tclIORChan.c31
5 files changed, 55 insertions, 15 deletions
diff --git a/generic/tcl.h b/generic/tcl.h
index b93b3ac..e557290 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -2433,9 +2433,15 @@ EXTERN void Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
/*
* Include platform specific public function declarations that are accessible
- * via the stubs table.
+ * via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
+ * has effect on building it as a shared library). See ticket [3010352].
*/
+#if defined(BUILD_tcl)
+# undef TCLAPI
+# define TCLAPI MODULE_SCOPE
+#endif
+
#include "tclPlatDecls.h"
/*
diff --git a/generic/tclIO.c b/generic/tclIO.c
index d5d4086..c4d9171 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -2312,6 +2312,9 @@ static void
PreserveChannelBuffer(
ChannelBuffer *bufPtr)
{
+ if (bufPtr->refCount == 0) {
+ Tcl_Panic("Reuse of ChannelBuffer!");
+ }
bufPtr->refCount++;
}
@@ -2610,6 +2613,7 @@ FlushChannel(
if (errorCode == EINTR) {
errorCode = 0;
+ ReleaseChannelBuffer(bufPtr);
continue;
}
@@ -2631,6 +2635,7 @@ FlushChannel(
UpdateInterest(chanPtr);
}
errorCode = 0;
+ ReleaseChannelBuffer(bufPtr);
break;
}
@@ -2692,6 +2697,7 @@ FlushChannel(
*/
DiscardOutputQueued(statePtr);
+ ReleaseChannelBuffer(bufPtr);
continue;
} else {
wroteSome = 1;
@@ -2711,8 +2717,11 @@ FlushChannel(
statePtr->outQueueTail = NULL;
}
RecycleBuffer(statePtr, bufPtr, 0);
+ bufPtr = NULL;
+ }
+ if (bufPtr) {
+ ReleaseChannelBuffer(bufPtr);
}
- ReleaseChannelBuffer(bufPtr);
} /* Closes "while (1)". */
/*
@@ -4026,6 +4035,7 @@ WillRead(
{
if (chanPtr->typePtr == NULL) {
/* Prevent read attempts on a closed channel */
+ DiscardInputQueued(chanPtr->state, 0);
Tcl_SetErrno(EINVAL);
return -1;
}
@@ -4204,6 +4214,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/tclIOGT.c b/generic/tclIOGT.c
index 29996ea..6cc33eb 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -298,7 +298,6 @@ TclChannelTransform(
}
Tcl_DStringFree(&ds);
- dataPtr->self = chan;
dataPtr->watchMask = 0;
dataPtr->mode = mode;
dataPtr->timer = NULL;
@@ -317,6 +316,7 @@ TclChannelTransform(
ReleaseData(dataPtr);
return TCL_ERROR;
}
+ Tcl_Preserve(dataPtr->self);
/*
* At last initialize the transformation at the script level.
@@ -437,6 +437,9 @@ ExecuteCallback(
break;
case TRANSMIT_DOWN:
+ if (dataPtr->self == NULL) {
+ break;
+ }
resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
@@ -444,6 +447,9 @@ ExecuteCallback(
break;
case TRANSMIT_SELF:
+ if (dataPtr->self == NULL) {
+ break;
+ }
resObj = Tcl_GetObjResult(eval);
resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
@@ -579,6 +585,8 @@ TransformCloseProc(
* General cleanup.
*/
+ Tcl_Release(dataPtr->self);
+ dataPtr->self = NULL;
ReleaseData(dataPtr);
return TCL_OK;
}
@@ -614,7 +622,7 @@ TransformInputProc(
* Should assert(dataPtr->mode & TCL_READABLE);
*/
- if (toRead == 0) {
+ if (toRead == 0 || dataPtr->self == NULL) {
/*
* Catch a no-op.
*/
@@ -1084,6 +1092,9 @@ TransformWatchProc(
* unchanged.
*/
+ if (dataPtr->self == NULL) {
+ return;
+ }
downChan = Tcl_GetStackedChannel(dataPtr->self);
Tcl_GetChannelType(downChan)->watchProc(
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);