diff options
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 207 |
1 files changed, 133 insertions, 74 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index 5bd0e2a..e213e72 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -64,9 +64,9 @@ static int CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr, int errorCode, int flags); static int CloseWrite(Tcl_Interp *interp, Channel *chanPtr); static void CommonGetsCleanup(Channel *chanPtr); -static int CopyAndTranslateBuffer(ChannelState *statePtr, - char *result, int space); -static int CopyBuffer(Channel *chanPtr, char *result, int space); +static TCL_SIZE_T CopyAndTranslateBuffer(ChannelState *statePtr, + char *result, TCL_SIZE_T space); +static TCL_SIZE_T CopyBuffer(Channel *chanPtr, char *result, TCL_SIZE_T space); static int CopyData(CopyState *csPtr, int mask); static void CopyEventProc(ClientData clientData, int mask); static void CreateScriptRecord(Tcl_Interp *interp, @@ -79,9 +79,9 @@ static int DetachChannel(Tcl_Interp *interp, Tcl_Channel chan); static void DiscardInputQueued(ChannelState *statePtr, int discardSavedBuffers); static void DiscardOutputQueued(ChannelState *chanPtr); -static int DoRead(Channel *chanPtr, char *srcPtr, int slen, int allowShortReads); -static int DoWrite(Channel *chanPtr, const char *src, int srcLen); -static int DoReadChars(Channel *chan, Tcl_Obj *objPtr, int toRead, +static TCL_SIZE_T DoRead(Channel *chanPtr, char *srcPtr, TCL_SIZE_T slen, int allowShortReads); +static TCL_SIZE_T DoWrite(Channel *chanPtr, const char *src, TCL_SIZE_T srcLen); +static TCL_SIZE_T DoReadChars(Channel *chan, Tcl_Obj *objPtr, TCL_SIZE_T toRead, int appendFlag); static int DoWriteChars(Channel *chan, const char *src, int len); static int FilterInputBytes(Channel *chanPtr, @@ -1035,7 +1035,7 @@ Tcl_UnregisterChannel( if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" - " of channel", -1)); + " of channel", TCL_NOSIZE)); } return TCL_ERROR; } @@ -2328,7 +2328,7 @@ CheckForDeadChannel( Tcl_SetErrno(EINVAL); if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "unable to access channel: invalid channel", -1)); + "unable to access channel: invalid channel", TCL_NOSIZE)); } return 1; } @@ -2523,7 +2523,7 @@ FlushChannel( if (interp != NULL && !TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) { Tcl_SetObjResult(interp, - Tcl_NewStringObj(Tcl_PosixError(interp), -1)); + Tcl_NewStringObj(Tcl_PosixError(interp), TCL_NOSIZE)); } /* @@ -3062,7 +3062,7 @@ Tcl_Close( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" - " of channel", -1)); + " of channel", TCL_NOSIZE)); } return TCL_ERROR; } @@ -3163,7 +3163,7 @@ Tcl_Close( Tcl_SetErrno(stickyError); if (interp != NULL) { Tcl_SetObjResult(interp, - Tcl_NewStringObj(Tcl_PosixError(interp), -1)); + Tcl_NewStringObj(Tcl_PosixError(interp), TCL_NOSIZE)); } flushcode = -1; } @@ -3232,7 +3232,7 @@ Tcl_CloseEx( if (chanPtr != statePtr->topChanPtr) { Tcl_SetObjResult(interp, Tcl_NewStringObj( - "half-close not applicable to stack of transformations", -1)); + "half-close not applicable to stack of transformations", TCL_NOSIZE)); return TCL_ERROR; } @@ -3265,7 +3265,7 @@ Tcl_CloseEx( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "illegal recursive call to close through close-handler" - " of channel", -1)); + " of channel", TCL_NOSIZE)); } return TCL_ERROR; } @@ -5520,7 +5520,7 @@ Tcl_ReadRaw( Channel *chanPtr = (Channel *) chan; ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int nread, result, copied, copiedNow; + TCL_SIZE_T nread, result, copied, copiedNow; /* * The check below does too much because it will reject a call to this @@ -5672,7 +5672,7 @@ Tcl_ReadChars( Tcl_Channel chan, /* The channel to read. */ Tcl_Obj *objPtr, /* Input data is stored in this object. */ int toRead, /* Maximum number of characters to store, or - * -1 to read all available data (up to EOF or + * TCL_NOSIZE to read all available data (up to EOF or * when channel blocks). */ int appendFlag) /* If non-zero, data read from the channel * will be appended to the object. Otherwise, @@ -5699,7 +5699,7 @@ Tcl_ReadChars( return -1; } - return DoReadChars(chanPtr, objPtr, toRead, appendFlag); + return (int) DoReadChars(chanPtr, objPtr, toRead, appendFlag); } /* *--------------------------------------------------------------------------- @@ -5714,7 +5714,7 @@ Tcl_ReadChars( * object. * * Results: - * The number of characters read, or -1 on error. Use Tcl_GetErrno() to + * The number of characters read, or TCL_NOSIZE on error. Use Tcl_GetErrno() to * retrieve the error code for the error that occurred. * * Side effects: @@ -5723,11 +5723,11 @@ Tcl_ReadChars( *--------------------------------------------------------------------------- */ -static int +static TCL_SIZE_T DoReadChars( Channel *chanPtr, /* The channel to read. */ Tcl_Obj *objPtr, /* Input data is stored in this object. */ - int toRead, /* Maximum number of characters to store, or + TCL_SIZE_T toRead, /* Maximum number of characters to store, or * -1 to read all available data (up to EOF or * when channel blocks). */ int appendFlag) /* If non-zero, data read from the channel @@ -5738,7 +5738,8 @@ DoReadChars( ChannelState *statePtr = chanPtr->state; /* State info for channel */ ChannelBuffer *bufPtr; - int offset, factor, copied, copiedNow, result; + TCL_SIZE_T offset, factor, copied, copiedNow; + int result; Tcl_Encoding encoding; #define UTF_EXPANSION_FACTOR 1024 @@ -6812,10 +6813,10 @@ GetInput( *---------------------------------------------------------------------- */ -Tcl_WideInt +TCL_SIZE_T Tcl_Seek( Tcl_Channel chan, /* The channel on which to seek. */ - Tcl_WideInt offset, /* Offset to seek to. */ + TCL_SIZE_T offset, /* Offset to seek to. */ int mode) /* Relative to which location to seek? */ { Channel *chanPtr = (Channel *) chan; @@ -6825,13 +6826,13 @@ Tcl_Seek( int inputBuffered, outputBuffered; /* # bytes held in buffers. */ int result; /* Of device driver operations. */ - Tcl_WideInt curPos; /* Position on the device. */ + TCL_SIZE_T curPos; /* Position on the device. */ int wasAsync; /* Was the channel nonblocking before the seek * operation? If so, must restore to * non-blocking mode after the seek. */ if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) { - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -6842,7 +6843,7 @@ Tcl_Seek( */ if (CheckForDeadChannel(NULL, statePtr)) { - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -6858,7 +6859,7 @@ Tcl_Seek( if (chanPtr->typePtr->seekProc == NULL) { Tcl_SetErrno(EINVAL); - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -6871,7 +6872,7 @@ Tcl_Seek( if ((inputBuffered != 0) && (outputBuffered != 0)) { Tcl_SetErrno(EFAULT); - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -6976,7 +6977,7 @@ Tcl_Seek( * channel. * * Results: - * A nonnegative integer on success, -1 on failure. If failed, use + * A nonnegative integer on success, TCL_NOSIZE on failure. If failed, use * Tcl_GetErrno() to retrieve the POSIX error code for the error that * occurred. * @@ -6986,7 +6987,7 @@ Tcl_Seek( *---------------------------------------------------------------------- */ -Tcl_WideInt +TCL_SIZE_T Tcl_Tell( Tcl_Channel chan) /* The channel to return pos for. */ { @@ -6994,13 +6995,13 @@ Tcl_Tell( /* The real IO channel. */ ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int inputBuffered, outputBuffered; + TCL_SIZE_T inputBuffered, outputBuffered; /* # bytes held in buffers. */ int result; /* Of calling device driver. */ - Tcl_WideInt curPos; /* Position on device. */ + TCL_SIZE_T curPos; /* Position on device. */ if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) { - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -7011,7 +7012,7 @@ Tcl_Tell( */ if (CheckForDeadChannel(NULL, statePtr)) { - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -7027,7 +7028,7 @@ Tcl_Tell( if (chanPtr->typePtr->seekProc == NULL) { Tcl_SetErrno(EINVAL); - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } /* @@ -7044,10 +7045,10 @@ Tcl_Tell( * wideSeekProc if that is available and non-NULL... */ - curPos = ChanSeek(chanPtr, Tcl_LongAsWide(0), SEEK_CUR, &result); - if (curPos == Tcl_LongAsWide(-1)) { + curPos = ChanSeek(chanPtr, 0, SEEK_CUR, &result); + if (curPos == TCL_NOSIZE) { Tcl_SetErrno(result); - return Tcl_LongAsWide(-1); + return TCL_NOSIZE; } if (inputBuffered != 0) { @@ -7059,6 +7060,52 @@ Tcl_Tell( /* *--------------------------------------------------------------------------- * + * Tcl_SeekOld, Tcl_TellOld -- + * + * Backward-compatability versions of the seek/tell interface which used + * 64-bit offsets. This interface is not documented or expected + * to be supported indefinitely. + * + * Results: + * As for Tcl_Seek and Tcl_Tell respectively, except expanded to + * 64-bits even on platforms which support only 32-bits. + * + * Side effects: + * As for Tcl_Seek and Tcl_Tell respectively. + * + *--------------------------------------------------------------------------- + */ + +Tcl_WideInt +Tcl_SeekOld( + Tcl_Channel chan, /* The channel on which to seek. */ + Tcl_WideInt offset, /* Offset to seek to. */ + int mode) /* Relative to which location to seek? */ +{ + TCL_SIZE_T wResult; + + wResult = Tcl_Seek(chan, (TCL_SIZE_T) offset, mode); + if (wResult == TCL_NOSIZE) { + return -1; + } + return (Tcl_WideInt) wResult; +} + +Tcl_WideInt +Tcl_TellOld( + Tcl_Channel chan) /* The channel to return pos for. */ +{ + TCL_SIZE_T wResult = Tcl_Tell(chan); + + if (wResult == TCL_NOSIZE) { + return -1; + } + return (Tcl_WideInt) wResult; +} + +/* + *--------------------------------------------------------------------------- + * * Tcl_TruncateChannel -- * * Truncate a channel to the given length. @@ -7520,10 +7567,10 @@ Tcl_BadChannelOption( Tcl_Obj *errObj; Tcl_DStringInit(&ds); - Tcl_DStringAppend(&ds, genericopt, -1); + Tcl_DStringAppend(&ds, genericopt, TCL_NOSIZE); if (optionList && (*optionList)) { TclDStringAppendLiteral(&ds, " "); - Tcl_DStringAppend(&ds, optionList, -1); + Tcl_DStringAppend(&ds, optionList, TCL_NOSIZE); } if (Tcl_SplitList(interp, Tcl_DStringValue(&ds), &argc, &argv) != TCL_OK) { @@ -7817,7 +7864,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unable to set channel options: background copy in" - " progress", -1)); + " progress", TCL_NOSIZE)); } return TCL_ERROR; } @@ -7868,7 +7915,7 @@ Tcl_SetChannelOption( } else if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -buffering: must be one of" - " full, line, or none", -1)); + " full, line, or none", TCL_NOSIZE)); return TCL_ERROR; } return TCL_OK; @@ -7925,7 +7972,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -eofchar: must be non-NUL ASCII" - " character", -1)); + " character", TCL_NOSIZE)); } ckfree(argv); return TCL_ERROR; @@ -7940,7 +7987,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -eofchar: should be a list of zero," - " one, or two elements", -1)); + " one, or two elements", TCL_NOSIZE)); } ckfree(argv); return TCL_ERROR; @@ -7974,7 +8021,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be a one or two" - " element list", -1)); + " element list", TCL_NOSIZE)); } ckfree(argv); return TCL_ERROR; @@ -8004,7 +8051,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " - "auto, binary, cr, lf, crlf, or platform", -1)); + "auto, binary, cr, lf, crlf, or platform", TCL_NOSIZE)); } ckfree(argv); return TCL_ERROR; @@ -8054,7 +8101,7 @@ Tcl_SetChannelOption( if (interp) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "bad value for -translation: must be one of " - "auto, binary, cr, lf, crlf, or platform", -1)); + "auto, binary, cr, lf, crlf, or platform", TCL_NOSIZE)); } ckfree(argv); return TCL_ERROR; @@ -8965,13 +9012,25 @@ ZeroTransferTimerProc( */ int -TclCopyChannel( +TclCopyChannelOld( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Channel inChan, /* Channel to read from. */ Tcl_Channel outChan, /* Channel to write to. */ Tcl_WideInt toRead, /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr) /* Pointer to script to execute or NULL. */ { + return TclCopyChannelOld(interp, inChan, outChan, (TCL_SIZE_T) toRead, + cmdPtr); +} + +int +TclCopyChannel( + Tcl_Interp *interp, /* Current interpreter. */ + Tcl_Channel inChan, /* Channel to read from. */ + Tcl_Channel outChan, /* Channel to write to. */ + TCL_SIZE_T toRead, /* Amount of data to copy, or TCL_NO_SIZE for all. */ + Tcl_Obj *cmdPtr) /* Pointer to script to execute or NULL. */ +{ Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; ChannelState *inStatePtr, *outStatePtr; @@ -9041,7 +9100,7 @@ TclCopyChannel( csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; - csPtr->total = (Tcl_WideInt) 0; + csPtr->total = 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); @@ -9094,8 +9153,8 @@ CopyData( Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL; Tcl_Channel inChan, outChan; ChannelState *inStatePtr, *outStatePtr; - int result = TCL_OK, size, sizeb; - Tcl_WideInt total; + int result = TCL_OK; + TCL_SIZE_T size, sizeb, total; const char *buffer; int inBinary, outBinary, sameEncoding; /* Encoding control */ @@ -9125,7 +9184,7 @@ CopyData( Tcl_IncrRefCount(bufObj); } - while (csPtr->toRead != (Tcl_WideInt) 0) { + while (csPtr->toRead != 0) { /* * Check for unreported background errors. */ @@ -9156,11 +9215,11 @@ CopyData( * Read up to bufSize bytes. */ - if ((csPtr->toRead == (Tcl_WideInt) -1) - || (csPtr->toRead > (Tcl_WideInt) csPtr->bufSize)) { + if ((csPtr->toRead == TCL_NOSIZE) + || (csPtr->toRead > csPtr->bufSize)) { sizeb = csPtr->bufSize; } else { - sizeb = (int) csPtr->toRead; + sizeb = csPtr->toRead; } if (inBinary || sameEncoding) { @@ -9273,7 +9332,7 @@ CopyData( * of bytes left to copy. */ - if (csPtr->toRead != -1) { + if (csPtr->toRead != TCL_NOSIZE) { csPtr->toRead -= size; } csPtr->total += size; @@ -9391,7 +9450,7 @@ CopyData( * are applied to the bytes being read. * * Results: - * The number of characters read, or -1 on error. Use Tcl_GetErrno() to + * The number of characters read, or TCL_NOSIZE on error. Use Tcl_GetErrno() to * retrieve the error code for the error that occurred. * * Side effects: @@ -9400,18 +9459,18 @@ CopyData( *---------------------------------------------------------------------- */ -static int +static TCL_SIZE_T DoRead( Channel *chanPtr, /* The channel from which to read. */ char *bufPtr, /* Where to store input read. */ - int toRead, /* Maximum number of bytes to read. */ + TCL_SIZE_T toRead, /* Maximum number of bytes to read. */ int allowShortReads) /* Allow half-blocking (pipes,sockets) */ { ChannelState *statePtr = chanPtr->state; /* State info for channel */ - int copied; /* How many characters were copied into the + TCL_SIZE_T copied; /* How many characters were copied into the * result string? */ - int copiedNow; /* How many characters were copied from the + TCL_SIZE_T copiedNow; /* How many characters were copied from the * current input buffer? */ int result; /* Of calling GetInput. */ @@ -9442,7 +9501,7 @@ DoRead( result = GetInput(chanPtr); if (result != 0) { if (result != EAGAIN) { - copied = -1; + copied = TCL_NOSIZE; } goto done; } @@ -9483,19 +9542,19 @@ DoRead( *---------------------------------------------------------------------- */ -static int +static TCL_SIZE_T CopyAndTranslateBuffer( ChannelState *statePtr, /* Channel state from which to read input. */ char *result, /* Where to store the copied input. */ - int space) /* How many bytes are available in result to + TCL_SIZE_T space) /* How many bytes are available in result to * store the copied input? */ { ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ - int bytesInBuffer; /* How many bytes are available to be copied + TCL_SIZE_T bytesInBuffer; /* How many bytes are available to be copied * in the current input buffer? */ - int copied; /* How many characters were already copied + TCL_SIZE_T copied; /* How many characters were already copied * into the destination space? */ - int i; /* Iterates over the copied input looking for + TCL_SIZE_T i; /* Iterates over the copied input looking for * the input eofChar. */ /* @@ -9525,7 +9584,7 @@ CopyAndTranslateBuffer( if (bytesInBuffer < space) { space = bytesInBuffer; } - memcpy(result, RemovePoint(bufPtr), (size_t) space); + memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; break; @@ -9708,17 +9767,17 @@ CopyAndTranslateBuffer( *---------------------------------------------------------------------- */ -static int +static TCL_SIZE_T CopyBuffer( Channel *chanPtr, /* Channel from which to read input. */ char *result, /* Where to store the copied input. */ - int space) /* How many bytes are available in result to + TCL_SIZE_T space) /* How many bytes are available in result to * store the copied input? */ { ChannelBuffer *bufPtr; /* The buffer from which to copy bytes. */ - int bytesInBuffer; /* How many bytes are available to be copied + TCL_SIZE_T bytesInBuffer; /* How many bytes are available to be copied * in the current input buffer? */ - int copied; /* How many characters were already copied + TCL_SIZE_T copied; /* How many characters were already copied * into the destination space? */ /* @@ -9752,7 +9811,7 @@ CopyBuffer( space = bytesInBuffer; } - memcpy(result, RemovePoint(bufPtr), (size_t) space); + memcpy(result, RemovePoint(bufPtr), space); bufPtr->nextRemoved += space; copied = space; @@ -10212,7 +10271,7 @@ Tcl_GetChannelNamesEx( && (pattern[2] == 'd'))) { if ((Tcl_FindHashEntry(hTblPtr, pattern) != NULL) && (Tcl_ListObjAppendElement(interp, resultPtr, - Tcl_NewStringObj(pattern, -1)) != TCL_OK)) { + Tcl_NewStringObj(pattern, TCL_NOSIZE)) != TCL_OK)) { goto error; } goto done; @@ -10239,7 +10298,7 @@ Tcl_GetChannelNamesEx( if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) && (Tcl_ListObjAppendElement(interp, resultPtr, - Tcl_NewStringObj(name, -1)) != TCL_OK)) { + Tcl_NewStringObj(name, TCL_NOSIZE)) != TCL_OK)) { error: TclDecrRefCount(resultPtr); return TCL_ERROR; |