summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--generic/tcl.decls6
-rw-r--r--generic/tcl.h4
-rw-r--r--generic/tclDecls.h20
-rw-r--r--generic/tclIO.c130
-rw-r--r--generic/tclIOGT.c66
-rw-r--r--generic/tclIORChan.c25
-rw-r--r--generic/tclIORTrans.c56
-rw-r--r--generic/tclStubInit.c3
-rw-r--r--generic/tclZipfs.c21
-rw-r--r--generic/tclZlib.c13
-rw-r--r--unix/tclUnixChan.c34
-rw-r--r--unix/tclUnixSock.c4
-rw-r--r--win/tclWinChan.c22
-rw-r--r--win/tclWinConsole.c13
-rw-r--r--win/tclWinSerial.c16
-rw-r--r--win/tclWinSock.c4
16 files changed, 306 insertions, 131 deletions
diff --git a/generic/tcl.decls b/generic/tcl.decls
index 928f8d3..8837dfd 100644
--- a/generic/tcl.decls
+++ b/generic/tcl.decls
@@ -299,7 +299,7 @@ declare 79 {
declare 80 {
void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc, ClientData clientData)
}
-declare 81 {
+declare 81 {deprecated {Use Tcl_CloseEx}} {
int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan)
}
declare 82 {
@@ -1415,7 +1415,7 @@ declare 400 {
Tcl_DriverBlockModeProc *Tcl_ChannelBlockModeProc(
const Tcl_ChannelType *chanTypePtr)
}
-declare 401 {
+declare 401 {deprecated {Use Tcl_ChannelClose2Proc}} {
Tcl_DriverCloseProc *Tcl_ChannelCloseProc(
const Tcl_ChannelType *chanTypePtr)
}
@@ -1431,7 +1431,7 @@ declare 404 {
Tcl_DriverOutputProc *Tcl_ChannelOutputProc(
const Tcl_ChannelType *chanTypePtr)
}
-declare 405 {
+declare 405 {deprecated {Use Tcl_ChannelWideSeekProc}} {
Tcl_DriverSeekProc *Tcl_ChannelSeekProc(
const Tcl_ChannelType *chanTypePtr)
}
diff --git a/generic/tcl.h b/generic/tcl.h
index 9768778..369a894 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -1400,10 +1400,12 @@ typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, ClientData clientData);
* Channel version tag. This was introduced in 8.3.2/8.4.
*/
+#ifndef TCL_NO_DEPRECATED
#define TCL_CHANNEL_VERSION_1 ((Tcl_ChannelTypeVersion) 0x1)
#define TCL_CHANNEL_VERSION_2 ((Tcl_ChannelTypeVersion) 0x2)
#define TCL_CHANNEL_VERSION_3 ((Tcl_ChannelTypeVersion) 0x3)
#define TCL_CHANNEL_VERSION_4 ((Tcl_ChannelTypeVersion) 0x4)
+#endif
#define TCL_CHANNEL_VERSION_5 ((Tcl_ChannelTypeVersion) 0x5)
/*
@@ -1472,7 +1474,7 @@ typedef struct Tcl_ChannelType {
/* Version of the channel type. */
Tcl_DriverCloseProc *closeProc;
/* Function to call to close the channel, or
- * TCL_CLOSE2PROC if the close2Proc should be
+ * NULL or TCL_CLOSE2PROC if the close2Proc should be
* used instead. */
Tcl_DriverInputProc *inputProc;
/* Function to call for input on channel. */
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
index 3387164..ccea15d 100644
--- a/generic/tclDecls.h
+++ b/generic/tclDecls.h
@@ -288,7 +288,8 @@ EXTERN void Tcl_CallWhenDeleted(Tcl_Interp *interp,
EXTERN void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc,
ClientData clientData);
/* 81 */
-EXTERN int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan);
+TCL_DEPRECATED("Use Tcl_CloseEx")
+int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan);
/* 82 */
EXTERN int Tcl_CommandComplete(const char *cmd);
/* 83 */
@@ -1206,7 +1207,8 @@ EXTERN Tcl_ChannelTypeVersion Tcl_ChannelVersion(
EXTERN Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(
const Tcl_ChannelType *chanTypePtr);
/* 401 */
-EXTERN Tcl_DriverCloseProc * Tcl_ChannelCloseProc(
+TCL_DEPRECATED("Use Tcl_ChannelClose2Proc")
+Tcl_DriverCloseProc * Tcl_ChannelCloseProc(
const Tcl_ChannelType *chanTypePtr);
/* 402 */
EXTERN Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(
@@ -1218,7 +1220,8 @@ EXTERN Tcl_DriverInputProc * Tcl_ChannelInputProc(
EXTERN Tcl_DriverOutputProc * Tcl_ChannelOutputProc(
const Tcl_ChannelType *chanTypePtr);
/* 405 */
-EXTERN Tcl_DriverSeekProc * Tcl_ChannelSeekProc(
+TCL_DEPRECATED("Use Tcl_ChannelWideSeekProc")
+Tcl_DriverSeekProc * Tcl_ChannelSeekProc(
const Tcl_ChannelType *chanTypePtr);
/* 406 */
EXTERN Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(
@@ -2027,7 +2030,7 @@ typedef struct TclStubs {
int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */
void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 79 */
void (*tcl_CancelIdleCall) (Tcl_IdleProc *idleProc, ClientData clientData); /* 80 */
- int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */
+ TCL_DEPRECATED_API("Use Tcl_CloseEx") int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */
int (*tcl_CommandComplete) (const char *cmd); /* 82 */
char * (*tcl_Concat) (int argc, const char *const *argv); /* 83 */
int (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */
@@ -2355,11 +2358,11 @@ typedef struct TclStubs {
const char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */
Tcl_ChannelTypeVersion (*tcl_ChannelVersion) (const Tcl_ChannelType *chanTypePtr); /* 399 */
Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) (const Tcl_ChannelType *chanTypePtr); /* 400 */
- Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) (const Tcl_ChannelType *chanTypePtr); /* 401 */
+ TCL_DEPRECATED_API("Use Tcl_ChannelClose2Proc") Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) (const Tcl_ChannelType *chanTypePtr); /* 401 */
Tcl_DriverClose2Proc * (*tcl_ChannelClose2Proc) (const Tcl_ChannelType *chanTypePtr); /* 402 */
Tcl_DriverInputProc * (*tcl_ChannelInputProc) (const Tcl_ChannelType *chanTypePtr); /* 403 */
Tcl_DriverOutputProc * (*tcl_ChannelOutputProc) (const Tcl_ChannelType *chanTypePtr); /* 404 */
- Tcl_DriverSeekProc * (*tcl_ChannelSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 405 */
+ TCL_DEPRECATED_API("Use Tcl_ChannelWideSeekProc") Tcl_DriverSeekProc * (*tcl_ChannelSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 405 */
Tcl_DriverSetOptionProc * (*tcl_ChannelSetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 406 */
Tcl_DriverGetOptionProc * (*tcl_ChannelGetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 407 */
Tcl_DriverWatchProc * (*tcl_ChannelWatchProc) (const Tcl_ChannelType *chanTypePtr); /* 408 */
@@ -4171,4 +4174,9 @@ extern const TclStubs *tclStubsPtr;
#define Tcl_GlobalEvalObj(interp, objPtr) \
Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL)
+#if defined(TCL_NO_DEPRECATED) && defined(USE_TCL_STUBS)
+#undef Tcl_Close
+#define Tcl_Close(interp, chan) Tcl_CloseEx(interp, chan, 0)
+#endif
+
#endif /* _TCLDECLS */
diff --git a/generic/tclIO.c b/generic/tclIO.c
index f8bd819..4bb3b00 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -374,11 +374,12 @@ ChanClose(
Channel *chanPtr,
Tcl_Interp *interp)
{
- if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
+#ifndef TCL_NO_DEPRECATED
+ if ((chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) && (chanPtr->typePtr->closeProc != NULL)) {
return chanPtr->typePtr->closeProc(chanPtr->instanceData, interp);
- } else {
- return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, 0);
}
+#endif
+ return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, 0);
}
static inline int
@@ -490,18 +491,23 @@ ChanSeek(
* type and non-NULL.
*/
- if (Tcl_ChannelWideSeekProc(chanPtr->typePtr) != NULL) {
- return Tcl_ChannelWideSeekProc(chanPtr->typePtr)(chanPtr->instanceData,
- offset, mode, errnoPtr);
- }
+ if (Tcl_ChannelWideSeekProc(chanPtr->typePtr) == NULL) {
+#ifndef TCL_NO_DEPRECATED
+ if (offset<LONG_MIN || offset>LONG_MAX) {
+ *errnoPtr = EOVERFLOW;
+ return -1;
+ }
- if (offset<LONG_MIN || offset>LONG_MAX) {
- *errnoPtr = EOVERFLOW;
+ return Tcl_ChannelSeekProc(chanPtr->typePtr)(chanPtr->instanceData,
+ offset, mode, errnoPtr);
+#else
+ *errnoPtr = EINVAL;
return -1;
+#endif
}
- return Tcl_ChannelSeekProc(chanPtr->typePtr)(chanPtr->instanceData,
- offset, mode, errnoPtr);
+ return Tcl_ChannelWideSeekProc(chanPtr->typePtr)(chanPtr->instanceData,
+ offset, mode, errnoPtr);
}
static inline void
@@ -1626,9 +1632,18 @@ Tcl_CreateChannel(
assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *));
assert(typePtr->typeName != NULL);
- if (NULL == typePtr->closeProc) {
- Tcl_Panic("channel type %s must define closeProc", typePtr->typeName);
+#ifndef TCL_NO_DEPRECATED
+ if (((NULL == typePtr->closeProc) || (TCL_CLOSE2PROC == typePtr->closeProc)) && (typePtr->close2Proc == NULL)) {
+ Tcl_Panic("channel type %s must define closeProc or close2Proc", typePtr->typeName);
+ }
+#else
+ if (Tcl_ChannelVersion(typePtr) < TCL_CHANNEL_VERSION_5) {
+ Tcl_Panic("channel type %s must be version TCL_CHANNEL_VERSION_5", typePtr->typeName);
+ }
+ if (typePtr->close2Proc == NULL) {
+ Tcl_Panic("channel type %s must define close2Proc", typePtr->typeName);
}
+#endif
if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) {
Tcl_Panic("channel type %s must define inputProc when used for reader channel", typePtr->typeName);
}
@@ -1638,9 +1653,11 @@ Tcl_CreateChannel(
if (NULL == typePtr->watchProc) {
Tcl_Panic("channel type %s must define watchProc", typePtr->typeName);
}
- if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) {
+#ifndef TCL_NO_DEPRECATED
+ if ((NULL != typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) {
Tcl_Panic("channel type %s must define seekProc if defining wideSeekProc", typePtr->typeName);
}
+#endif
/*
* JH: We could subsequently memset these to 0 to avoid the numerous
@@ -3382,7 +3399,7 @@ Tcl_Close(
* channel. */
Channel *chanPtr; /* The real IO channel. */
ChannelState *statePtr; /* State of real IO channel. */
- int result; /* Of calling FlushChannel. */
+ int result = 0; /* Of calling FlushChannel. */
int flushcode;
int stickyError;
@@ -3483,12 +3500,14 @@ Tcl_Close(
* it anymore and this will help avoid deadlocks on some channel types.
*/
- if (chanPtr->typePtr->closeProc == TCL_CLOSE2PROC) {
- result = chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp,
- TCL_CLOSE_READ);
- } else {
- result = 0;
+#ifndef TCL_NO_DEPRECATED
+ if ((chanPtr->typePtr->closeProc == TCL_CLOSE2PROC) || (chanPtr->typePtr->closeProc == NULL)) {
+ /* If this half-close fails, just continue the full close */
+ (void)chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, TCL_CLOSE_READ);
}
+#else
+ (void)chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, TCL_CLOSE_READ);
+#endif
/*
* The call to FlushChannel will flush any queued output and invoke the
@@ -3548,19 +3567,17 @@ Tcl_Close(
*
* Tcl_CloseEx --
*
- * Closes one side of a channel, read or write.
+ * Closes one side of a channel, read or write, close all.
*
* Results:
* A standard Tcl result.
*
* Side effects:
- * Closes one direction of the channel.
+ * Closes one direction of the channel, or do a full close.
*
* NOTE:
* Tcl_CloseEx closes the specified direction of the channel as far as
- * the user is concerned. The channel keeps existing however. You cannot
- * calls this function to close the last possible direction of the
- * channel. Use Tcl_Close for that.
+ * the user is concerned. If flags = 0, this is equivalent to Tcl_Close.
*
*----------------------------------------------------------------------
*/
@@ -3580,18 +3597,26 @@ Tcl_CloseEx(
return TCL_OK;
}
- /* TODO: assert flags validity ? */
-
chanPtr = (Channel *) chan;
statePtr = chanPtr->state;
+ if ((flags & (TCL_READABLE | TCL_WRITABLE)) == 0) {
+ return Tcl_Close(interp, chan);
+ }
+ if ((flags & (TCL_READABLE | TCL_WRITABLE)) == (TCL_READABLE | TCL_WRITABLE)) {
+ Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+ "double-close of channels not supported by %ss",
+ chanPtr->typePtr->typeName));
+ return TCL_ERROR;
+ }
+
/*
* Does the channel support half-close anyway? Error if not.
*/
if (!chanPtr->typePtr->close2Proc) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "half-close of channels not supported by %ss",
+ "half-close of channels not supported by %ss",
chanPtr->typePtr->typeName));
return TCL_ERROR;
}
@@ -4213,12 +4238,15 @@ WillWrite(
{
int inputBuffered;
- if ((Tcl_ChannelSeekProc(chanPtr->typePtr) != NULL) &&
- ((inputBuffered = Tcl_InputBuffered((Tcl_Channel) chanPtr)) > 0)){
- int ignore;
+ if (((Tcl_ChannelWideSeekProc(chanPtr->typePtr) != NULL)
+#ifndef TCL_NO_DEPRECATED
+ || (Tcl_ChannelSeekProc(chanPtr->typePtr) != NULL)
+#endif
+ ) && ((inputBuffered = Tcl_InputBuffered((Tcl_Channel) chanPtr)) > 0)){
+ int ignore;
- DiscardInputQueued(chanPtr->state, 0);
- ChanSeek(chanPtr, -inputBuffered, SEEK_CUR, &ignore);
+ DiscardInputQueued(chanPtr->state, 0);
+ ChanSeek(chanPtr, -inputBuffered, SEEK_CUR, &ignore);
}
}
@@ -4235,8 +4263,11 @@ WillRead(
Tcl_SetErrno(EINVAL);
return -1;
}
- if ((Tcl_ChannelSeekProc(chanPtr->typePtr) != NULL)
- && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) {
+ if (((Tcl_ChannelWideSeekProc(chanPtr->typePtr) != NULL)
+#ifndef TCL_NO_DEPRECATED
+ || (Tcl_ChannelSeekProc(chanPtr->typePtr) != NULL)
+#endif
+ ) && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) {
/*
* CAVEAT - The assumption here is that FlushChannel() will push out
* the bytes of any writes that are in progress. Since this is a
@@ -6996,7 +7027,11 @@ Tcl_Seek(
* defined. This means that the channel does not support seeking.
*/
- if (Tcl_ChannelSeekProc(chanPtr->typePtr) == NULL) {
+ if ((Tcl_ChannelWideSeekProc(chanPtr->typePtr) == NULL)
+#ifndef TCL_NO_DEPRECATED
+ && (Tcl_ChannelSeekProc(chanPtr->typePtr) == NULL)
+#endif
+ ) {
Tcl_SetErrno(EINVAL);
return -1;
}
@@ -7160,7 +7195,11 @@ Tcl_Tell(
* defined. This means that the channel does not support seeking.
*/
- if (Tcl_ChannelSeekProc(chanPtr->typePtr) == NULL) {
+ if ((Tcl_ChannelWideSeekProc(chanPtr->typePtr) == NULL)
+#ifndef TCL_NO_DEPRECATED
+ && (Tcl_ChannelSeekProc(chanPtr->typePtr) == NULL)
+#endif
+ ) {
Tcl_SetErrno(EINVAL);
return -1;
}
@@ -10499,6 +10538,7 @@ Tcl_ChannelVersion(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if ((chanTypePtr->version < TCL_CHANNEL_VERSION_2)
|| (chanTypePtr->version > TCL_CHANNEL_VERSION_5)) {
/*
@@ -10507,6 +10547,7 @@ Tcl_ChannelVersion(
*/
return TCL_CHANNEL_VERSION_1;
}
+#endif
return chanTypePtr->version;
}
@@ -10530,13 +10571,14 @@ Tcl_ChannelBlockModeProc(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if (Tcl_ChannelVersion(chanTypePtr) < TCL_CHANNEL_VERSION_2) {
/*
* The v1 structure had the blockModeProc in a different place.
*/
return (Tcl_DriverBlockModeProc *) chanTypePtr->version;
}
-
+#endif
return chanTypePtr->blockModeProc;
}
@@ -10556,6 +10598,7 @@ Tcl_ChannelBlockModeProc(
*----------------------------------------------------------------------
*/
+#ifndef TCL_NO_DEPRECATED
Tcl_DriverCloseProc *
Tcl_ChannelCloseProc(
const Tcl_ChannelType *chanTypePtr)
@@ -10563,6 +10606,7 @@ Tcl_ChannelCloseProc(
{
return chanTypePtr->closeProc;
}
+#endif
/*
*----------------------------------------------------------------------
@@ -10652,6 +10696,7 @@ Tcl_ChannelOutputProc(
*----------------------------------------------------------------------
*/
+#ifndef TCL_NO_DEPRECATED
Tcl_DriverSeekProc *
Tcl_ChannelSeekProc(
const Tcl_ChannelType *chanTypePtr)
@@ -10659,6 +10704,7 @@ Tcl_ChannelSeekProc(
{
return chanTypePtr->seekProc;
}
+#endif
/*
*----------------------------------------------------------------------
@@ -10777,9 +10823,11 @@ Tcl_ChannelFlushProc(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if (Tcl_ChannelVersion(chanTypePtr) < TCL_CHANNEL_VERSION_2) {
return NULL;
}
+#endif
return chanTypePtr->flushProc;
}
@@ -10804,9 +10852,11 @@ Tcl_ChannelHandlerProc(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if (Tcl_ChannelVersion(chanTypePtr) < TCL_CHANNEL_VERSION_2) {
return NULL;
}
+#endif
return chanTypePtr->handlerProc;
}
@@ -10831,9 +10881,11 @@ Tcl_ChannelWideSeekProc(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if (Tcl_ChannelVersion(chanTypePtr) < TCL_CHANNEL_VERSION_3) {
return NULL;
}
+#endif
return chanTypePtr->wideSeekProc;
}
@@ -10859,9 +10911,11 @@ Tcl_ChannelThreadActionProc(
const Tcl_ChannelType *chanTypePtr)
/* Pointer to channel type. */
{
+#ifndef TCL_NO_DEPRECATED
if (Tcl_ChannelVersion(chanTypePtr) < TCL_CHANNEL_VERSION_4) {
return NULL;
}
+#endif
return chanTypePtr->threadActionProc;
}
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
index 3dac585..3d0782c 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -22,13 +22,15 @@
static int TransformBlockModeProc(ClientData instanceData,
int mode);
static int TransformCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int TransformInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCodePtr);
static int TransformOutputProc(ClientData instanceData,
const char *buf, int toWrite, int *errorCodePtr);
+#ifndef TCL_NO_DEPRECATED
static int TransformSeekProc(ClientData instanceData, long offset,
int mode, int *errorCodePtr);
+#endif
static int TransformSetOptionProc(ClientData instanceData,
Tcl_Interp *interp, const char *optionName,
const char *value);
@@ -119,15 +121,19 @@ static inline void ResultAdd(ResultBuffer *r, unsigned char *buf,
static const Tcl_ChannelType transformChannelType = {
"transform", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- TransformCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
TransformInputProc, /* Input proc. */
TransformOutputProc, /* Output proc. */
+#ifndef TCL_NO_DEPRECATED
TransformSeekProc, /* Seek proc. */
+#else
+ NULL, /* Seek proc. */
+#endif
TransformSetOptionProc, /* Set option proc. */
TransformGetOptionProc, /* Get option proc. */
TransformWatchProc, /* Initialize notifier. */
TransformGetFileHandleProc, /* Get OS handles out of channel. */
- NULL, /* close2proc */
+ TransformCloseProc, /* close2proc */
TransformBlockModeProc, /* Set blocking/nonblocking mode.*/
NULL, /* Flush proc. */
TransformNotifyProc, /* Handling of events bubbling up. */
@@ -533,10 +539,15 @@ TransformBlockModeProc(
static int
TransformCloseProc(
ClientData instanceData,
- Tcl_Interp *interp)
+ Tcl_Interp *interp,
+ int flags)
{
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
/*
* Important: In this procedure 'dataPtr->self' already points to the
* underlying channel.
@@ -828,6 +839,7 @@ TransformOutputProc(
*----------------------------------------------------------------------
*/
+#ifndef TCL_NO_DEPRECATED
static int
TransformSeekProc(
ClientData instanceData, /* The channel to manipulate. */
@@ -874,6 +886,7 @@ TransformSeekProc(
return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset, mode,
errorCodePtr);
}
+#endif
/*
*----------------------------------------------------------------------
@@ -905,7 +918,9 @@ TransformWideSeekProc(
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
const Tcl_ChannelType *parentType = Tcl_GetChannelType(parent);
+#ifndef TCL_NO_DEPRECATED
Tcl_DriverSeekProc *parentSeekProc = Tcl_ChannelSeekProc(parentType);
+#endif
Tcl_DriverWideSeekProc *parentWideSeekProc =
Tcl_ChannelWideSeekProc(parentType);
ClientData parentData = Tcl_GetChannelInstanceData(parent);
@@ -918,9 +933,14 @@ TransformWideSeekProc(
if (parentWideSeekProc != NULL) {
return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
+#ifndef TCL_NO_DEPRECATED
+ } else if (parentSeekProc) {
+ return parentSeekProc(parentData, 0, mode, errorCodePtr);
+#endif
+ } else {
+ *errorCodePtr = EINVAL;
+ return -1;
}
-
- return parentSeekProc(parentData, 0, mode, errorCodePtr);
}
/*
@@ -948,25 +968,29 @@ TransformWideSeekProc(
* If we have a wide seek capability, we should stick with that.
*/
- if (parentWideSeekProc != NULL) {
- return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
- }
+ if (parentWideSeekProc == NULL) {
+ /*
+ * We're transferring to narrow seeks at this point; this is a bit complex
+ * because we have to check whether the seek is possible first (i.e.
+ * whether we are losing information in truncating the bits of the
+ * offset). Luckily, there's a defined error for what happens when trying
+ * to go out of the representable range.
+ */
- /*
- * We're transferring to narrow seeks at this point; this is a bit complex
- * because we have to check whether the seek is possible first (i.e.
- * whether we are losing information in truncating the bits of the
- * offset). Luckily, there's a defined error for what happens when trying
- * to go out of the representable range.
- */
+#ifndef TCL_NO_DEPRECATED
+ if (offset<LONG_MIN || offset>LONG_MAX) {
+ *errorCodePtr = EOVERFLOW;
+ return -1;
+ }
- if (offset<LONG_MIN || offset>LONG_MAX) {
- *errorCodePtr = EOVERFLOW;
+ return parentSeekProc(parentData, offset,
+ mode, errorCodePtr);
+#else
+ *errorCodePtr = EINVAL;
return -1;
+#endif
}
-
- return parentSeekProc(parentData, offset,
- mode, errorCodePtr);
+ return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
}
/*
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
index ee47ab3..fd338e4 100644
--- a/generic/tclIORChan.c
+++ b/generic/tclIORChan.c
@@ -32,7 +32,7 @@
*/
static int ReflectClose(ClientData clientData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int ReflectInput(ClientData clientData, char *buf,
int toRead, int *errorCodePtr);
static int ReflectOutput(ClientData clientData, const char *buf,
@@ -46,8 +46,10 @@ static int ReflectEventDelete(Tcl_Event *ev, ClientData cd);
#endif
static Tcl_WideInt ReflectSeekWide(ClientData clientData,
Tcl_WideInt offset, int mode, int *errorCodePtr);
+#ifndef TCL_NO_DEPRECATED
static int ReflectSeek(ClientData clientData, long offset,
int mode, int *errorCodePtr);
+#endif
static int ReflectGetOption(ClientData clientData,
Tcl_Interp *interp, const char *optionName,
Tcl_DString *dsPtr);
@@ -65,15 +67,19 @@ static void TimerRunWrite(ClientData clientData);
static const Tcl_ChannelType tclRChannelType = {
"tclrchannel", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- ReflectClose, /* Close channel, clean instance data */
+ TCL_CLOSE2PROC, /* Close channel, clean instance data */
ReflectInput, /* Handle read request */
ReflectOutput, /* Handle write request */
+#ifndef TCL_NO_DEPRECATED
ReflectSeek, /* Move location of access point. NULL'able */
+#else
+ NULL,
+#endif
ReflectSetOption, /* Set options. NULL'able */
ReflectGetOption, /* Get options. NULL'able */
ReflectWatch, /* Initialize notifier */
NULL, /* Get OS handle from the channel. NULL'able */
- NULL, /* No close2 support. NULL'able */
+ ReflectClose, /* No close2 support. NULL'able */
ReflectBlock, /* Set blocking/nonblocking. NULL'able */
NULL, /* Flush channel. Not used by core. NULL'able */
NULL, /* Handle events. NULL'able */
@@ -81,7 +87,7 @@ static const Tcl_ChannelType tclRChannelType = {
#if TCL_THREADS
ReflectThread, /* thread action, tracking owner */
#else
- NULL, /* thread action */
+ (void *)-1, /* thread action */
#endif
NULL /* truncate */
};
@@ -697,7 +703,9 @@ TclChanCreateObjCmd(
clonePtr->blockModeProc = NULL;
}
if (!(methods & FLAG(METH_SEEK))) {
+#ifndef TCL_NO_DEPRECATED
clonePtr->seekProc = NULL;
+#endif
clonePtr->wideSeekProc = NULL;
}
@@ -1153,7 +1161,8 @@ TclChanCaughtErrorBypass(
static int
ReflectClose(
ClientData clientData,
- Tcl_Interp *interp)
+ Tcl_Interp *interp,
+ int flags)
{
ReflectedChannel *rcPtr = (ReflectedChannel *)clientData;
int result; /* Result code for 'close' */
@@ -1163,6 +1172,10 @@ ReflectClose(
Tcl_HashEntry *hPtr; /* Entry in the above map */
const Tcl_ChannelType *tctPtr;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
if (TclInThreadExit()) {
/*
* This call comes from TclFinalizeIOSystem. There are no
@@ -1617,6 +1630,7 @@ ReflectSeekWide(
goto stop;
}
+#ifndef TCL_NO_DEPRECATED
static int
ReflectSeek(
ClientData clientData,
@@ -1634,6 +1648,7 @@ ReflectSeek(
return ReflectSeekWide(clientData, offset, seekMode,
errorCodePtr);
}
+#endif
/*
*----------------------------------------------------------------------
diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c
index 5ef409e..82fce33 100644
--- a/generic/tclIORTrans.c
+++ b/generic/tclIORTrans.c
@@ -32,7 +32,7 @@
*/
static int ReflectClose(ClientData clientData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int ReflectInput(ClientData clientData, char *buf,
int toRead, int *errorCodePtr);
static int ReflectOutput(ClientData clientData, const char *buf,
@@ -41,8 +41,10 @@ static void ReflectWatch(ClientData clientData, int mask);
static int ReflectBlock(ClientData clientData, int mode);
static Tcl_WideInt ReflectSeekWide(ClientData clientData,
Tcl_WideInt offset, int mode, int *errorCodePtr);
+#ifndef TCL_NO_DEPRECATED
static int ReflectSeek(ClientData clientData, long offset,
int mode, int *errorCodePtr);
+#endif
static int ReflectGetOption(ClientData clientData,
Tcl_Interp *interp, const char *optionName,
Tcl_DString *dsPtr);
@@ -60,15 +62,19 @@ static int ReflectNotify(ClientData clientData, int mask);
static const Tcl_ChannelType tclRTransformType = {
"tclrtransform", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel. */
- ReflectClose, /* Close channel, clean instance data. */
+ TCL_CLOSE2PROC, /* Close channel, clean instance data. */
ReflectInput, /* Handle read request. */
ReflectOutput, /* Handle write request. */
+#ifndef TCL_NO_DEPRECATED
ReflectSeek, /* Move location of access point. */
+#else
+ NULL, /* Move location of access point. */
+#endif
ReflectSetOption, /* Set options. */
ReflectGetOption, /* Get options. */
ReflectWatch, /* Initialize notifier. */
ReflectHandle, /* Get OS handle from the channel. */
- NULL, /* No close2 support. NULL'able. */
+ ReflectClose, /* No close2 support. NULL'able. */
ReflectBlock, /* Set blocking/nonblocking. */
NULL, /* Flush channel. Not used by core.
* NULL'able. */
@@ -881,7 +887,8 @@ UnmarshallErrorResult(
static int
ReflectClose(
ClientData clientData,
- Tcl_Interp *interp)
+ Tcl_Interp *interp,
+ int flags)
{
ReflectedTransform *rtPtr = (ReflectedTransform *)clientData;
int errorCode, errorCodeSet = 0;
@@ -892,6 +899,10 @@ ReflectClose(
* in this interp. */
Tcl_HashEntry *hPtr; /* Entry in the above map */
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
if (TclInThreadExit()) {
/*
* This call comes from TclFinalizeIOSystem. There are no
@@ -1329,18 +1340,6 @@ ReflectSeekWide(
Channel *parent = (Channel *) rtPtr->parent;
Tcl_WideInt curPos; /* Position on the device. */
- Tcl_DriverSeekProc *seekProc =
- Tcl_ChannelSeekProc(Tcl_GetChannelType(rtPtr->parent));
-
- /*
- * Fail if the parent channel is not seekable.
- */
-
- if (seekProc == NULL) {
- Tcl_SetErrno(EINVAL);
- return -1;
- }
-
/*
* Check if we can leave out involving the Tcl level, i.e. transformation
* handler. This is true for tell requests, and transformations which
@@ -1384,16 +1383,23 @@ ReflectSeekWide(
* non-NULL...
*/
- if (Tcl_ChannelWideSeekProc(parent->typePtr) != NULL) {
- curPos = Tcl_ChannelWideSeekProc(parent->typePtr)(parent->instanceData, offset,
- seekMode, errorCodePtr);
- } else if (offset < LONG_MIN || offset > LONG_MAX) {
- *errorCodePtr = EOVERFLOW;
+ if (Tcl_ChannelWideSeekProc(parent->typePtr) == NULL) {
+#ifndef TCL_NO_DEPRECATED
+ if (offset < LONG_MIN || offset > LONG_MAX) {
+ *errorCodePtr = EOVERFLOW;
+ curPos = -1;
+ } else {
+ curPos = Tcl_ChannelSeekProc(parent->typePtr)(
+ parent->instanceData, offset, seekMode,
+ errorCodePtr);
+ }
+#else
+ *errorCodePtr = EINVAL;
curPos = -1;
+#endif
} else {
- curPos = Tcl_ChannelSeekProc(parent->typePtr)(
- parent->instanceData, offset, seekMode,
- errorCodePtr);
+ curPos = Tcl_ChannelWideSeekProc(parent->typePtr)(parent->instanceData, offset,
+ seekMode, errorCodePtr);
}
if (curPos == -1) {
Tcl_SetErrno(*errorCodePtr);
@@ -1404,6 +1410,7 @@ ReflectSeekWide(
return curPos;
}
+#ifndef TCL_NO_DEPRECATED
static int
ReflectSeek(
ClientData clientData,
@@ -1421,6 +1428,7 @@ ReflectSeek(
return ReflectSeekWide(clientData, offset, seekMode,
errorCodePtr);
}
+#endif
/*
*----------------------------------------------------------------------
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
index f30f2d8..784d165 100644
--- a/generic/tclStubInit.c
+++ b/generic/tclStubInit.c
@@ -256,6 +256,9 @@ mp_err TclBN_mp_mul_d(const mp_int *a, unsigned int b, mp_int *c) {
# define Tcl_DbNewLongObj 0
# define Tcl_BackgroundError 0
# define Tcl_FreeResult 0
+# define Tcl_ChannelSeekProc 0
+# define Tcl_ChannelCloseProc 0
+# define Tcl_Close 0
#else
mp_err TclBN_mp_div_3(const mp_int *a, mp_int *c, unsigned int *d) {
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index ae0c0c5..7fae81e 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -385,13 +385,15 @@ static int ZipFSLoadFile(Tcl_Interp *interp, Tcl_Obj *path,
static void ZipfsExitHandler(ClientData clientData);
static void ZipfsSetup(void);
static int ZipChannelClose(void *instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int ZipChannelGetFile(void *instanceData,
int direction, void **handlePtr);
static int ZipChannelRead(void *instanceData, char *buf,
int toRead, int *errloc);
+#ifndef TCL_NO_DEPRECATED
static int ZipChannelSeek(void *instanceData, long offset,
int mode, int *errloc);
+#endif
static Tcl_WideInt ZipChannelWideSeek(void *instanceData, Tcl_WideInt offset,
int mode, int *errloc);
static void ZipChannelWatchChannel(void *instanceData,
@@ -444,15 +446,19 @@ static const Tcl_Filesystem zipfsFilesystem = {
static Tcl_ChannelType ZipChannelType = {
"zip", /* Type name. */
TCL_CHANNEL_VERSION_5,
- ZipChannelClose, /* Close channel, clean instance data */
+ TCL_CLOSE2PROC, /* Close channel, clean instance data */
ZipChannelRead, /* Handle read request */
ZipChannelWrite, /* Handle write request */
+#ifndef TCL_NO_DEPRECATED
ZipChannelSeek, /* Move location of access point, NULL'able */
+#else
+ NULL, /* Move location of access point, NULL'able */
+#endif
NULL, /* Set options, NULL'able */
NULL, /* Get options, NULL'able */
ZipChannelWatchChannel, /* Initialize notifier */
ZipChannelGetFile, /* Get OS handle from the channel */
- NULL, /* 2nd version of close channel, NULL'able */
+ ZipChannelClose, /* 2nd version of close channel, NULL'able */
NULL, /* Set blocking mode for raw channel, NULL'able */
NULL, /* Function to flush channel, NULL'able */
NULL, /* Function to handle event, NULL'able */
@@ -3338,11 +3344,16 @@ ZipFSTclLibraryObjCmd(
static int
ZipChannelClose(
void *instanceData,
- Tcl_Interp *dummy) /* Current interpreter. */
+ Tcl_Interp *dummy, /* Current interpreter. */
+ int flags)
{
ZipChannel *info = (ZipChannel *)instanceData;
(void)dummy;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
if (info->iscompr && info->ubuf) {
ckfree(info->ubuf);
info->ubuf = NULL;
@@ -3569,6 +3580,7 @@ ZipChannelWideSeek(
return info->numRead;
}
+#ifndef TCL_NO_DEPRECATED
static int
ZipChannelSeek(
void *instanceData,
@@ -3578,6 +3590,7 @@ ZipChannelSeek(
{
return ZipChannelWideSeek(instanceData, offset, mode, errloc);
}
+#endif
/*
*-------------------------------------------------------------------------
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
index 23cea39..ac69511 100644
--- a/generic/tclZlib.c
+++ b/generic/tclZlib.c
@@ -160,7 +160,7 @@ typedef struct {
static Tcl_CmdDeleteProc ZlibStreamCmdDelete;
static Tcl_DriverBlockModeProc ZlibTransformBlockMode;
-static Tcl_DriverCloseProc ZlibTransformClose;
+static Tcl_DriverClose2Proc ZlibTransformClose;
static Tcl_DriverGetHandleProc ZlibTransformGetHandle;
static Tcl_DriverGetOptionProc ZlibTransformGetOption;
static Tcl_DriverHandlerProc ZlibTransformEventHandler;
@@ -205,7 +205,7 @@ static void ZlibTransformTimerRun(void *clientData);
static const Tcl_ChannelType zlibChannelType = {
"zlib",
TCL_CHANNEL_VERSION_5,
- ZlibTransformClose,
+ TCL_CLOSE2PROC,
ZlibTransformInput,
ZlibTransformOutput,
NULL, /* seekProc */
@@ -213,7 +213,7 @@ static const Tcl_ChannelType zlibChannelType = {
ZlibTransformGetOption,
ZlibTransformWatch,
ZlibTransformGetHandle,
- NULL, /* close2Proc */
+ ZlibTransformClose, /* close2Proc */
ZlibTransformBlockMode,
NULL, /* flushProc */
ZlibTransformEventHandler,
@@ -2896,11 +2896,16 @@ ZlibStreamHeaderCmd(
static int
ZlibTransformClose(
void *instanceData,
- Tcl_Interp *interp)
+ Tcl_Interp *interp,
+ int flags)
{
ZlibChannelData *cd = (ZlibChannelData *)instanceData;
int e, written, result = TCL_OK;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
/*
* Delete the support timer.
*/
diff --git a/unix/tclUnixChan.c b/unix/tclUnixChan.c
index 2dc5f46..a377419 100644
--- a/unix/tclUnixChan.c
+++ b/unix/tclUnixChan.c
@@ -121,7 +121,7 @@ typedef struct {
static int FileBlockModeProc(void *instanceData, int mode);
static int FileCloseProc(void *instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int FileGetHandleProc(void *instanceData,
int direction, void **handlePtr);
static int FileInputProc(void *instanceData, char *buf,
@@ -137,7 +137,7 @@ static Tcl_WideInt FileWideSeekProc(void *instanceData,
static void FileWatchProc(void *instanceData, int mask);
#ifdef SUPPORTS_TTY
static int TtyCloseProc(void *instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static void TtyGetAttributes(int fd, TtyAttrs *ttyPtr);
static int TtyGetOptionProc(void *instanceData,
Tcl_Interp *interp, const char *optionName,
@@ -161,15 +161,19 @@ static int TtySetOptionProc(void *instanceData,
static const Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- FileCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
+#ifndef TCL_NO_DEPRECATED
FileSeekProc, /* Seek proc. */
+#else
+ NULL,
+#endif
NULL, /* Set option proc. */
NULL, /* Get option proc. */
FileWatchProc, /* Initialize notifier. */
FileGetHandleProc, /* Get OS handles out of channel. */
- NULL, /* close2proc. */
+ FileCloseProc, /* close2proc. */
FileBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
@@ -187,7 +191,7 @@ static const Tcl_ChannelType fileChannelType = {
static const Tcl_ChannelType ttyChannelType = {
"tty", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- TtyCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
NULL, /* Seek proc. */
@@ -195,7 +199,7 @@ static const Tcl_ChannelType ttyChannelType = {
TtyGetOptionProc, /* Get option proc. */
FileWatchProc, /* Initialize notifier. */
FileGetHandleProc, /* Get OS handles out of channel. */
- NULL, /* close2proc. */
+ TtyCloseProc, /* close2proc. */
FileBlockModeProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
@@ -353,12 +357,17 @@ FileOutputProc(
static int
FileCloseProc(
void *instanceData, /* File state. */
- Tcl_Interp *dummy) /* For error reporting - unused. */
+ Tcl_Interp *dummy, /* For error reporting - unused. */
+ int flags)
{
FileState *fsPtr = (FileState *)instanceData;
int errorCode = 0;
(void)dummy;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
Tcl_DeleteFileHandler(fsPtr->fd);
/*
@@ -379,10 +388,14 @@ FileCloseProc(
static int
TtyCloseProc(
void *instanceData,
- Tcl_Interp *interp)
+ Tcl_Interp *interp,
+ int flags)
{
TtyState *ttyPtr = (TtyState*)instanceData;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
/*
* If we've been asked by the user to drain or flush, do so now.
*/
@@ -411,7 +424,7 @@ TtyCloseProc(
* Delegate to close for files.
*/
- return FileCloseProc(instanceData, interp);
+ return FileCloseProc(instanceData, interp, flags);
}
#endif /* SUPPORTS_TTY */
@@ -433,7 +446,7 @@ TtyCloseProc(
*
*----------------------------------------------------------------------
*/
-
+#ifndef TCL_NO_DEPRECATED
static int
FileSeekProc(
void *instanceData, /* File state. */
@@ -474,6 +487,7 @@ FileSeekProc(
}
return (int) newLoc;
}
+#endif
/*
*----------------------------------------------------------------------
diff --git a/unix/tclUnixSock.c b/unix/tclUnixSock.c
index 31095bd..a9b8685 100644
--- a/unix/tclUnixSock.c
+++ b/unix/tclUnixSock.c
@@ -157,7 +157,11 @@ static void WrapNotify(void *clientData, int mask);
static const Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
+#ifndef TCL_NO_DEPRECATED
TcpCloseProc, /* Close proc. */
+#else
+ TCL_CLOSE2PROC, /* Close proc. */
+#endif
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */
diff --git a/win/tclWinChan.c b/win/tclWinChan.c
index d8c734c..7ffd6b5 100644
--- a/win/tclWinChan.c
+++ b/win/tclWinChan.c
@@ -76,7 +76,7 @@ static int FileBlockProc(ClientData instanceData, int mode);
static void FileChannelExitHandler(ClientData clientData);
static void FileCheckProc(ClientData clientData, int flags);
static int FileCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int FileEventProc(Tcl_Event *evPtr, int flags);
static int FileGetHandleProc(ClientData instanceData,
int direction, ClientData *handlePtr);
@@ -85,8 +85,10 @@ static int FileInputProc(ClientData instanceData, char *buf,
int toRead, int *errorCode);
static int FileOutputProc(ClientData instanceData,
const char *buf, int toWrite, int *errorCode);
+#ifndef TCL_NO_DEPRECATED
static int FileSeekProc(ClientData instanceData, long offset,
int mode, int *errorCode);
+#endif
static Tcl_WideInt FileWideSeekProc(ClientData instanceData,
Tcl_WideInt offset, int mode, int *errorCode);
static void FileSetupProc(ClientData clientData, int flags);
@@ -105,15 +107,19 @@ static int NativeIsComPort(const WCHAR *nativeName);
static const Tcl_ChannelType fileChannelType = {
"file", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- FileCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
FileInputProc, /* Input proc. */
FileOutputProc, /* Output proc. */
+#ifndef TCL_NO_DEPRECATED
FileSeekProc, /* Seek proc. */
+#else
+ NULL,
+#endif
NULL, /* Set option proc. */
NULL, /* Get option proc. */
FileWatchProc, /* Set up the notifier to watch the channel. */
FileGetHandleProc, /* Get an OS handle from channel. */
- NULL, /* close2proc. */
+ FileCloseProc, /* close2proc. */
FileBlockProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
@@ -390,7 +396,8 @@ FileBlockProc(
static int
FileCloseProc(
ClientData instanceData, /* Pointer to FileInfo structure. */
- Tcl_Interp *dummy) /* Not used. */
+ Tcl_Interp *dummy, /* Not used. */
+ int flags)
{
FileInfo *fileInfoPtr = (FileInfo *)instanceData;
FileInfo *infoPtr;
@@ -398,6 +405,10 @@ FileCloseProc(
int errorCode = 0;
(void)dummy;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
/*
* Remove the file from the watch list.
*/
@@ -460,7 +471,7 @@ FileCloseProc(
*
*----------------------------------------------------------------------
*/
-
+#ifndef TCL_NO_DEPRECATED
static int
FileSeekProc(
ClientData instanceData, /* File state. */
@@ -520,6 +531,7 @@ FileSeekProc(
}
return (int) newPos;
}
+#endif
/*
*----------------------------------------------------------------------
diff --git a/win/tclWinConsole.c b/win/tclWinConsole.c
index 9ba2ea0..4c1aec0 100644
--- a/win/tclWinConsole.c
+++ b/win/tclWinConsole.c
@@ -142,7 +142,7 @@ static int ConsoleBlockModeProc(ClientData instanceData,
int mode);
static void ConsoleCheckProc(ClientData clientData, int flags);
static int ConsoleCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int ConsoleEventProc(Tcl_Event *evPtr, int flags);
static void ConsoleExitHandler(ClientData clientData);
static int ConsoleGetHandleProc(ClientData instanceData,
@@ -180,7 +180,7 @@ static BOOL WriteConsoleBytes(HANDLE hConsole,
static const Tcl_ChannelType consoleChannelType = {
"console", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- ConsoleCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
ConsoleInputProc, /* Input proc. */
ConsoleOutputProc, /* Output proc. */
NULL, /* Seek proc. */
@@ -188,7 +188,7 @@ static const Tcl_ChannelType consoleChannelType = {
ConsoleGetOptionProc, /* Get option proc. */
ConsoleWatchProc, /* Set up notifier to watch the channel. */
ConsoleGetHandleProc, /* Get an OS handle from channel. */
- NULL, /* close2proc. */
+ ConsoleCloseProc, /* close2proc. */
ConsoleBlockModeProc, /* Set blocking or non-blocking mode. */
NULL, /* Flush proc. */
NULL, /* Handler proc. */
@@ -537,7 +537,8 @@ ConsoleBlockModeProc(
static int
ConsoleCloseProc(
ClientData instanceData, /* Pointer to ConsoleInfo structure. */
- Tcl_Interp *dummy) /* For error reporting. */
+ Tcl_Interp *dummy, /* For error reporting. */
+ int flags)
{
ConsoleInfo *consolePtr = (ConsoleInfo *)instanceData;
int errorCode = 0;
@@ -545,6 +546,10 @@ ConsoleCloseProc(
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
(void)dummy;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
/*
* Clean up the background thread if necessary. Note that this must be
* done before we can close the file, since the thread may be blocking
diff --git a/win/tclWinSerial.c b/win/tclWinSerial.c
index a63fd8e..7884453 100644
--- a/win/tclWinSerial.c
+++ b/win/tclWinSerial.c
@@ -168,7 +168,7 @@ static COMMTIMEOUTS no_timeout = {
static int SerialBlockProc(ClientData instanceData, int mode);
static void SerialCheckProc(ClientData clientData, int flags);
static int SerialCloseProc(ClientData instanceData,
- Tcl_Interp *interp);
+ Tcl_Interp *interp, int flags);
static int SerialEventProc(Tcl_Event *evPtr, int flags);
static void SerialExitHandler(ClientData clientData);
static int SerialGetHandleProc(ClientData instanceData,
@@ -204,7 +204,7 @@ static int SerialBlockingWrite(SerialInfo *infoPtr, LPVOID buf,
static const Tcl_ChannelType serialChannelType = {
"serial", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
- SerialCloseProc, /* Close proc. */
+ TCL_CLOSE2PROC, /* Close proc. */
SerialInputProc, /* Input proc. */
SerialOutputProc, /* Output proc. */
NULL, /* Seek proc. */
@@ -212,7 +212,7 @@ static const Tcl_ChannelType serialChannelType = {
SerialGetOptionProc, /* Get option proc. */
SerialWatchProc, /* Set up notifier to watch the channel. */
SerialGetHandleProc, /* Get an OS handle from channel. */
- NULL, /* close2proc. */
+ SerialCloseProc, /* close2proc. */
SerialBlockProc, /* Set blocking or non-blocking mode.*/
NULL, /* flush proc. */
NULL, /* handler proc. */
@@ -606,15 +606,19 @@ SerialBlockProc(
static int
SerialCloseProc(
ClientData instanceData, /* Pointer to SerialInfo structure. */
- Tcl_Interp *dummy) /* For error reporting. */
+ Tcl_Interp *dummy, /* For error reporting. */
+ int flags)
{
SerialInfo *serialPtr = (SerialInfo *) instanceData;
- int errorCode, result = 0;
+ int errorCode = 0, result = 0;
SerialInfo *infoPtr, **nextPtrPtr;
ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
(void)dummy;
- errorCode = 0;
+ if ((flags & (TCL_CLOSE_READ | TCL_CLOSE_WRITE)) != 0) {
+ return EINVAL;
+ }
+
if (serialPtr->validMask & TCL_READABLE) {
PurgeComm(serialPtr->handle, PURGE_RXABORT | PURGE_RXCLEAR);
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index 846f2e1..ad9ed72 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -280,7 +280,11 @@ static Tcl_DriverGetHandleProc TcpGetHandleProc;
static const Tcl_ChannelType tcpChannelType = {
"tcp", /* Type name. */
TCL_CHANNEL_VERSION_5, /* v5 channel */
+#ifndef TCL_NO_DEPRECATED
TcpCloseProc, /* Close proc. */
+#else
+ TCL_CLOSE2PROC, /* Close proc. */
+#endif
TcpInputProc, /* Input proc. */
TcpOutputProc, /* Output proc. */
NULL, /* Seek proc. */