diff options
-rw-r--r-- | generic/tcl.decls | 6 | ||||
-rw-r--r-- | generic/tcl.h | 4 | ||||
-rw-r--r-- | generic/tclDecls.h | 20 | ||||
-rw-r--r-- | generic/tclIO.c | 130 | ||||
-rw-r--r-- | generic/tclIOGT.c | 66 | ||||
-rw-r--r-- | generic/tclIORChan.c | 25 | ||||
-rw-r--r-- | generic/tclIORTrans.c | 56 | ||||
-rw-r--r-- | generic/tclStubInit.c | 3 | ||||
-rw-r--r-- | generic/tclZipfs.c | 21 | ||||
-rw-r--r-- | generic/tclZlib.c | 13 | ||||
-rw-r--r-- | unix/tclUnixChan.c | 34 | ||||
-rw-r--r-- | unix/tclUnixSock.c | 4 | ||||
-rw-r--r-- | win/tclWinChan.c | 22 | ||||
-rw-r--r-- | win/tclWinConsole.c | 13 | ||||
-rw-r--r-- | win/tclWinSerial.c | 16 | ||||
-rw-r--r-- | win/tclWinSock.c | 4 |
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. */ |