summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog17
-rw-r--r--generic/tclIO.c6
-rw-r--r--generic/tclInt.h4
-rw-r--r--unix/tclUnixChan.c118
-rw-r--r--win/tclWinChan.c103
5 files changed, 222 insertions, 26 deletions
diff --git a/ChangeLog b/ChangeLog
index 92dd6de..44b0223 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+ * generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel):
+ Invoke TclpCutFileChannel and TclpSpliceFileChannel.
+ * generic/tclInt.h: Declare TclpCutFileChannel
+ and TclpSpliceFileChannel.
+ * unix/tclUnixChan.c (FileCloseProc, TclpOpenFileChannel,
+ Tcl_MakeFileChannel, TclpCutFileChannel,
+ TclpSpliceFileChannel): Implement thread load data
+ cut and splice for file channels. This avoids
+ an invalid memory ref when compiled with -DDEPRECATED.
+ * win/tclWinChan.c (FileCloseProc, TclpCutFileChannel,
+ TclpSpliceFileChannel): Implement thread load data
+ cut and splice for file channels. This avoids
+ an invalid memory ref that was showing up in the
+ thread extension.
+
+2003-01-25 Mo DeJong <mdejong@users.sourceforge.net>
+
* win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings):
* win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings):
* win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings):
diff --git a/generic/tclIO.c b/generic/tclIO.c
index e1298d5..5e2338d 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.58 2003/01/24 11:59:29 vincentdarley Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.59 2003/01/26 05:59:37 mdejong Exp $
*/
#include "tclInt.h"
@@ -2409,6 +2409,8 @@ Tcl_CutChannel(chan)
}
statePtr->nextCSPtr = (ChannelState *) NULL;
+
+ TclpCutFileChannel(chan);
}
/*
@@ -2460,6 +2462,8 @@ Tcl_SpliceChannel(chan)
*/
statePtr->managingThread = Tcl_GetCurrentThread ();
+
+ TclpSpliceFileChannel(chan);
}
/*
diff --git a/generic/tclInt.h b/generic/tclInt.h
index ff49a21..62a2cc3 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -12,7 +12,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclInt.h,v 1.115 2003/01/17 14:19:49 vincentdarley Exp $
+ * RCS: @(#) $Id: tclInt.h,v 1.116 2003/01/26 05:59:37 mdejong Exp $
*/
#ifndef _TCLINT
@@ -1777,6 +1777,8 @@ EXTERN int TclpObjStat _ANSI_ARGS_((Tcl_Obj *pathPtr, Tcl_StatBuf *buf));
EXTERN Tcl_Channel TclpOpenFileChannel _ANSI_ARGS_((Tcl_Interp *interp,
Tcl_Obj *pathPtr, int mode,
int permissions));
+EXTERN void TclpCutFileChannel _ANSI_ARGS_((Tcl_Channel chan));
+EXTERN void TclpSpliceFileChannel _ANSI_ARGS_((Tcl_Channel chan));
EXTERN void TclpPanic _ANSI_ARGS_(TCL_VARARGS(CONST char *,
format));
EXTERN char * TclpReadlink _ANSI_ARGS_((CONST char *fileName,
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index 4838c55..79dad86 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -10,11 +10,12 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixChan.c,v 1.40 2002/11/07 02:13:37 mdejong Exp $
+ * RCS: @(#) $Id: tclUnixChan.c,v 1.41 2003/01/26 05:59:37 mdejong Exp $
*/
#include "tclInt.h" /* Internal definitions for Tcl. */
#include "tclPort.h" /* Portability features for Tcl. */
+#include "tclIO.h" /* To get Channel type declaration. */
/*
* sys/ioctl.h has already been included by tclPort.h. Including termios.h
@@ -555,15 +556,6 @@ FileCloseProc(instanceData, interp)
errorCode = errno;
}
}
-#ifdef DEPRECATED
- for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
- nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
- if ((*nextPtrPtr) == fsPtr) {
- (*nextPtrPtr) = fsPtr->nextPtr;
- break;
- }
- }
-#endif /* DEPRECATED */
ckfree((char *) fsPtr);
return errorCode;
}
@@ -1834,8 +1826,10 @@ TclpOpenFileChannel(interp, pathPtr, mode, permissions)
}
#ifdef DEPRECATED
- fsPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = fsPtr;
+ if (channelTypePtr == &fileChannelType) {
+ fsPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fsPtr;
+ }
#endif /* DEPRECATED */
fsPtr->validMask = channelPermissions | TCL_EXCEPTION;
fsPtr->fd = fd;
@@ -1933,8 +1927,10 @@ Tcl_MakeFileChannel(handle, mode)
}
#ifdef DEPRECATED
- fsPtr->nextPtr = tsdPtr->firstFilePtr;
- tsdPtr->firstFilePtr = fsPtr;
+ if (channelTypePtr == &fileChannelType) {
+ fsPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fsPtr;
+ }
#endif /* DEPRECATED */
fsPtr->fd = fd;
fsPtr->validMask = mode | TCL_EXCEPTION;
@@ -3243,3 +3239,97 @@ TclUnixWaitForFile(fd, mask, timeout)
}
return result;
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpCutFileChannel --
+ *
+ * Remove any thread local refs to this channel. See
+ * Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpCutFileChannel(chan)
+ Tcl_Channel chan; /* The channel being removed. Must
+ * not be referenced in any
+ * interpreter. */
+{
+#ifdef DEPRECATED
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ Channel *chanPtr = (Channel *) chan;
+ FileState *fsPtr;
+ FileState **nextPtrPtr;
+ int removed = 0;
+
+ if (chanPtr->typePtr != &fileChannelType)
+ return;
+
+ fsPtr = (FileState *) chanPtr->instanceData;
+
+ for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
+ nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
+ if ((*nextPtrPtr) == fsPtr) {
+ (*nextPtrPtr) = fsPtr->nextPtr;
+ removed = 1;
+ break;
+ }
+ }
+
+ /*
+ * This could happen if the channel was created in one thread
+ * and then moved to another without updating the thread
+ * local data in each thread.
+ */
+
+ if (!removed)
+ panic("file info ptr not on thread channel list");
+
+#endif /* DEPRECATED */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpSpliceFileChannel --
+ *
+ * Insert thread local ref for this channel.
+ * Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpSpliceFileChannel(chan)
+ Tcl_Channel chan; /* The channel being removed. Must
+ * not be referenced in any
+ * interpreter. */
+{
+#ifdef DEPRECATED
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ Channel *chanPtr = (Channel *) chan;
+ FileState *fsPtr;
+
+ if (chanPtr->typePtr != &fileChannelType)
+ return;
+
+ fsPtr = (FileState *) chanPtr->instanceData;
+
+ fsPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = fsPtr;
+#endif /* DEPRECATED */
+}
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index c377245..c6640f1 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -9,10 +9,11 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclWinChan.c,v 1.29 2003/01/25 14:11:32 mdejong Exp $
+ * RCS: @(#) $Id: tclWinChan.c,v 1.30 2003/01/26 05:59:38 mdejong Exp $
*/
#include "tclWinInt.h"
+#include "tclIO.h"
/*
* State flags used in the info structures below.
@@ -389,9 +390,7 @@ FileCloseProc(instanceData, interp)
Tcl_Interp *interp; /* Not used. */
{
FileInfo *fileInfoPtr = (FileInfo *) instanceData;
- FileInfo **nextPtrPtr;
int errorCode = 0;
- ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
/*
* Remove the file from the watch list.
@@ -414,13 +413,7 @@ FileCloseProc(instanceData, interp)
errorCode = errno;
}
}
- for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
- nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
- if ((*nextPtrPtr) == fileInfoPtr) {
- (*nextPtrPtr) = fileInfoPtr->nextPtr;
- break;
- }
- }
+
ckfree((char *)fileInfoPtr);
return errorCode;
}
@@ -1345,3 +1338,93 @@ TclWinFlushDirtyChannels ()
}
}
}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpCutFileChannel --
+ *
+ * Remove any thread local refs to this channel. See
+ * Tcl_CutChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpCutFileChannel(chan)
+ Tcl_Channel chan; /* The channel being removed. Must
+ * not be referenced in any
+ * interpreter. */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ Channel *chanPtr = (Channel *) chan;
+ FileInfo *infoPtr;
+ FileInfo **nextPtrPtr;
+ int removed = 0;
+
+ if (chanPtr->typePtr != &fileChannelType)
+ return;
+
+ infoPtr = (FileInfo *) chanPtr->instanceData;
+
+ for (nextPtrPtr = &(tsdPtr->firstFilePtr); (*nextPtrPtr) != NULL;
+ nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {
+ if ((*nextPtrPtr) == infoPtr) {
+ (*nextPtrPtr) = infoPtr->nextPtr;
+ removed = 1;
+ break;
+ }
+ }
+
+ /*
+ * This could happen if the channel was created in one thread
+ * and then moved to another without updating the thread
+ * local data in each thread.
+ */
+
+ if (!removed)
+ panic("file info ptr not on thread channel list");
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpSpliceFileChannel --
+ *
+ * Insert thread local ref for this channel.
+ * Tcl_SpliceChannel for more info.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Changes thread local list of valid channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpSpliceFileChannel(chan)
+ Tcl_Channel chan; /* The channel being removed. Must
+ * not be referenced in any
+ * interpreter. */
+{
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ Channel *chanPtr = (Channel *) chan;
+ FileInfo *infoPtr;
+
+ if (chanPtr->typePtr != &fileChannelType)
+ return;
+
+ infoPtr = (FileInfo *) chanPtr->instanceData;
+
+ infoPtr->nextPtr = tsdPtr->firstFilePtr;
+ tsdPtr->firstFilePtr = infoPtr;
+}