summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c53
1 files changed, 41 insertions, 12 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index f8e541d..088dca8 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclIO.c,v 1.111 2006/11/13 08:23:08 das Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.112 2006/11/13 17:51:34 dgp Exp $
*/
#include "tclInt.h"
@@ -48,6 +48,7 @@ typedef struct ThreadSpecificData {
int stdoutInitialized;
Tcl_Channel stderrChannel; /* Static variable for the stderr channel. */
int stderrInitialized;
+ Tcl_Encoding binaryEncoding;
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -69,8 +70,7 @@ static void CleanupChannelHandlers(Tcl_Interp *interp,
Channel *chanPtr);
static int CloseChannel(Tcl_Interp *interp, Channel *chanPtr,
int errorCode);
-static void CommonGetsCleanup(Channel *chanPtr,
- Tcl_Encoding encoding);
+static void CommonGetsCleanup(Channel *chanPtr);
static int CopyAndTranslateBuffer(ChannelState *statePtr,
char *result, int space);
static int CopyBuffer(Channel *chanPtr, char *result, int space);
@@ -95,6 +95,7 @@ static int FilterInputBytes(Channel *chanPtr,
GetsState *statePtr);
static int FlushChannel(Tcl_Interp *interp, Channel *chanPtr,
int calledFromAsyncFlush);
+static void FreeBinaryEncoding(ClientData clientData);
static Tcl_HashTable * GetChannelTable(Tcl_Interp *interp);
static int GetInput(Channel *chanPtr);
static int HaveVersion(Tcl_ChannelType *typePtr,
@@ -3813,7 +3814,15 @@ Tcl_GetsObj(
*/
if (encoding == NULL) {
- encoding = Tcl_GetEncoding(NULL, "iso8859-1");
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ if (tsdPtr->binaryEncoding == NULL) {
+ tsdPtr->binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
+ Tcl_CreateThreadExitHandler(FreeBinaryEncoding, NULL);
+ }
+ encoding = tsdPtr->binaryEncoding;
+ if (encoding == NULL) {
+ Tcl_Panic("attempted gets on binary channel where no iso8859-1 encoding available");
+ }
}
/*
@@ -3994,7 +4003,7 @@ Tcl_GetsObj(
*/
Tcl_SetObjLength(objPtr, oldLength);
- CommonGetsCleanup(chanPtr, encoding);
+ CommonGetsCleanup(chanPtr);
copiedTotal = -1;
goto done;
}
@@ -4029,7 +4038,7 @@ Tcl_GetsObj(
*/
Tcl_SetObjLength(objPtr, eol - objPtr->bytes);
- CommonGetsCleanup(chanPtr, encoding);
+ CommonGetsCleanup(chanPtr);
statePtr->flags &= ~CHANNEL_BLOCKED;
copiedTotal = gs.totalChars + gs.charsWrote - skip;
goto done;
@@ -4050,7 +4059,7 @@ Tcl_GetsObj(
for (bufPtr = bufPtr->nextPtr; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
bufPtr->nextRemoved = BUFFER_PADDING;
}
- CommonGetsCleanup(chanPtr, encoding);
+ CommonGetsCleanup(chanPtr);
statePtr->inputEncodingState = oldState;
statePtr->inputEncodingFlags = oldFlags;
@@ -4083,6 +4092,30 @@ Tcl_GetsObj(
/*
*---------------------------------------------------------------------------
*
+ * FreeBinaryEncoding --
+ * Frees any "iso8859-1" Tcl_Encoding created by [gets] on a binary
+ * channel in a thread as part of that thread's finalization.
+ *
+ * Results:
+ * None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+FreeBinaryEncoding(
+ ClientData dummy) /* Not used */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ if (tsdPtr->binaryEncoding != NULL) {
+ Tcl_FreeEncoding(tsdPtr->binaryEncoding);
+ tsdPtr->binaryEncoding = NULL;
+ }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
* FilterInputBytes --
*
* Helper function for Tcl_GetsObj. Produces UTF-8 characters from raw
@@ -4361,8 +4394,7 @@ PeekAhead(
static void
CommonGetsCleanup(
- Channel *chanPtr,
- Tcl_Encoding encoding)
+ Channel *chanPtr)
{
ChannelState *statePtr = chanPtr->state;
/* State info for channel */
@@ -4404,9 +4436,6 @@ CommonGetsCleanup(
bufPtr = nextPtr;
}
}
- if (statePtr->encoding == NULL) {
- Tcl_FreeEncoding(encoding);
- }
}
/*