summaryrefslogtreecommitdiffstats
path: root/generic/tclIOGT.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclIOGT.c')
-rw-r--r--generic/tclIOGT.c110
1 files changed, 16 insertions, 94 deletions
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
index 5f0f55e..e9c4fae 100644
--- a/generic/tclIOGT.c
+++ b/generic/tclIOGT.c
@@ -22,13 +22,11 @@
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);
-static int TransformSeekProc(ClientData instanceData, long offset,
- int mode, int *errorCodePtr);
static int TransformSetOptionProc(ClientData instanceData,
Tcl_Interp *interp, const char *optionName,
const char *value);
@@ -119,15 +117,15 @@ 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. */
+ NULL, /* Close proc. */
TransformInputProc, /* Input proc. */
TransformOutputProc, /* Output proc. */
- TransformSeekProc, /* Seek proc. */
+ NULL, /* Seek proc. */
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 +531,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.
@@ -811,73 +814,6 @@ TransformOutputProc(
/*
*----------------------------------------------------------------------
*
- * TransformSeekProc --
- *
- * This procedure is called by the generic IO level to move the access
- * point in a channel.
- *
- * Side effects:
- * Moves the location at which the channel will be accessed in future
- * operations. Flushes all transformation buffers, then forwards it to
- * the underlying channel.
- *
- * Result:
- * -1 if failed, the new position if successful. An output argument
- * contains the POSIX error code if an error occurred, or zero.
- *
- *----------------------------------------------------------------------
- */
-
-static int
-TransformSeekProc(
- ClientData instanceData, /* The channel to manipulate. */
- long offset, /* Size of movement. */
- int mode, /* How to move. */
- int *errorCodePtr) /* Location of error flag. */
-{
- TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
- Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
- const Tcl_ChannelType *parentType = Tcl_GetChannelType(parent);
- Tcl_DriverSeekProc *parentSeekProc = Tcl_ChannelSeekProc(parentType);
-
- if ((offset == 0) && (mode == SEEK_CUR)) {
- /*
- * This is no seek but a request to tell the caller the current
- * location. Simply pass the request down.
- */
-
- return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset,
- mode, errorCodePtr);
- }
-
- /*
- * It is a real request to change the position. Flush all data waiting for
- * output and discard everything in the input buffers. Then pass the
- * request down, unchanged.
- */
-
- PreserveData(dataPtr);
- if (dataPtr->mode & TCL_WRITABLE) {
- ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
- P_NO_PRESERVE);
- }
-
- if (dataPtr->mode & TCL_READABLE) {
- ExecuteCallback(dataPtr, NULL, A_CLEAR_READ, NULL, 0, TRANSMIT_DONT,
- P_NO_PRESERVE);
- ResultClear(&dataPtr->result);
- dataPtr->readIsFlushed = 0;
- dataPtr->eofPending = 0;
- }
- ReleaseData(dataPtr);
-
- return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset, mode,
- errorCodePtr);
-}
-
-/*
- *----------------------------------------------------------------------
- *
* TransformWideSeekProc --
*
* This procedure is called by the generic IO level to move the access
@@ -905,7 +841,6 @@ TransformWideSeekProc(
TransformChannelData *dataPtr = (TransformChannelData *)instanceData;
Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
const Tcl_ChannelType *parentType = Tcl_GetChannelType(parent);
- Tcl_DriverSeekProc *parentSeekProc = Tcl_ChannelSeekProc(parentType);
Tcl_DriverWideSeekProc *parentWideSeekProc =
Tcl_ChannelWideSeekProc(parentType);
ClientData parentData = Tcl_GetChannelInstanceData(parent);
@@ -918,9 +853,10 @@ TransformWideSeekProc(
if (parentWideSeekProc != NULL) {
return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
+ } else {
+ *errorCodePtr = EINVAL;
+ return -1;
}
-
- return parentSeekProc(parentData, 0, mode, errorCodePtr);
}
/*
@@ -948,25 +884,11 @@ TransformWideSeekProc(
* If we have a wide seek capability, we should stick with that.
*/
- if (parentWideSeekProc != NULL) {
- return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
- }
-
- /*
- * 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.
- */
-
- if (offset<LONG_MIN || offset>LONG_MAX) {
- *errorCodePtr = EOVERFLOW;
+ if (parentWideSeekProc == NULL) {
+ *errorCodePtr = EINVAL;
return -1;
}
-
- return parentSeekProc(parentData, offset,
- mode, errorCodePtr);
+ return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
}
/*