diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2010-03-20 15:39:46 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2010-03-20 15:39:46 (GMT) |
commit | 981ede1b28ef6c7040d9526a568faf7d7e6f73de (patch) | |
tree | 916de8cf08cd2e2b07d6c7faf71f6d89064d6233 /generic/tclIO.c | |
parent | ebf2f83895304cba3d46bd0714bc6e1cf38fbe83 (diff) | |
download | tcl-981ede1b28ef6c7040d9526a568faf7d7e6f73de.zip tcl-981ede1b28ef6c7040d9526a568faf7d7e6f73de.tar.gz tcl-981ede1b28ef6c7040d9526a568faf7d7e6f73de.tar.bz2 |
Allow [fcopy] to move more than 2GB per call. Frederic Bonnet identified issue.
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r-- | generic/tclIO.c | 86 |
1 files changed, 48 insertions, 38 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c index bc94bb6..2ec35cc 100644 --- a/generic/tclIO.c +++ b/generic/tclIO.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclIO.c,v 1.173 2010/03/17 16:35:42 andreas_kupries Exp $ + * RCS: @(#) $Id: tclIO.c,v 1.174 2010/03/20 15:39:46 dkf Exp $ */ #include "tclInt.h" @@ -231,7 +231,7 @@ static const Tcl_ObjType tclChannelType = { #define SET_CHANNELINTERP(objPtr, storePtr) \ ((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (storePtr)) -#define BUSY_STATE(st,fl) \ +#define BUSY_STATE(st, fl) \ ((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \ (((st)->csPtrW) && ((fl) & TCL_WRITABLE))) @@ -1726,9 +1726,9 @@ Tcl_UnstackChannel( if (chanPtr->downChanPtr != NULL) { /* * Instead of manipulating the per-thread / per-interp list/hashtable - * of registered channels we wind down the state of the transformation, - * and then restore the state of underlying channel into the old - * structure. + * of registered channels we wind down the state of the + * transformation, and then restore the state of underlying channel + * into the old structure. */ Channel *downChanPtr = chanPtr->downChanPtr; @@ -2653,7 +2653,7 @@ CloseChannel( if (statePtr->chanMsg != NULL) { if (interp != NULL) { - Tcl_SetChannelErrorInterp(interp,statePtr->chanMsg); + Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg); } TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; @@ -2709,7 +2709,7 @@ CloseChannel( statePtr->chanMsg = NULL; } if (interp) { - Tcl_SetChannelErrorInterp(interp,statePtr->unreportedMsg); + Tcl_SetChannelErrorInterp(interp, statePtr->unreportedMsg); } } if (errorCode == 0) { @@ -3051,7 +3051,7 @@ Tcl_Close( if (statePtr->chanMsg != NULL) { if (interp != NULL) { - Tcl_SetChannelErrorInterp(interp,statePtr->chanMsg); + Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg); } TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; @@ -3412,7 +3412,7 @@ CloseChannelPart( if (statePtr->chanMsg != NULL) { if (interp != NULL) { - Tcl_SetChannelErrorInterp(interp,statePtr->chanMsg); + Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg); } TclDecrRefCount(statePtr->chanMsg); statePtr->chanMsg = NULL; @@ -3446,7 +3446,7 @@ CloseChannelPart( statePtr->chanMsg = NULL; } if (interp) { - Tcl_SetChannelErrorInterp(interp,statePtr->unreportedMsg); + Tcl_SetChannelErrorInterp(interp, statePtr->unreportedMsg); } } if (errorCode == 0) { @@ -6697,10 +6697,10 @@ GetInput( #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING /* - * [SF Tcl Bug 943274]. Better emulation of non-blocking channels for - * channels without BlockModeProc, by keeping track of true fileevents - * generated by the OS == Data waiting and reading if and only if we are - * sure to have data. + * [Bug 943274]: Better emulation of non-blocking channels for channels + * without BlockModeProc, by keeping track of true fileevents generated by + * the OS == Data waiting and reading if and only if we are sure to have + * data. */ if (GotFlag(statePtr, CHANNEL_NONBLOCKING) && @@ -6735,8 +6735,7 @@ GetInput( #ifdef TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING if (nread <= toRead) { /* - * [SF Tcl Bug 943274] We have read the available data, clear - * flag. + * [Bug 943274]: We have read the available data, clear flag. */ ResetFlag(statePtr, CHANNEL_HAS_MORE_DATA); @@ -7207,7 +7206,7 @@ CheckChannelErrors( * retrieving and transforming the data to copy. */ - if (BUSY_STATE(statePtr,flags) && ((flags & CHANNEL_RAW_MODE) == 0)) { + if (BUSY_STATE(statePtr, flags) && ((flags & CHANNEL_RAW_MODE) == 0)) { Tcl_SetErrno(EBUSY); return -1; } @@ -7865,12 +7864,10 @@ Tcl_SetChannelOption( (strncmp(newValue, "none", len) == 0)) { ResetFlag(statePtr, CHANNEL_LINEBUFFERED); SetFlag(statePtr, CHANNEL_UNBUFFERED); - } else { - if (interp) { - Tcl_AppendResult(interp, "bad value for -buffering: " - "must be one of full, line, or none", NULL); - return TCL_ERROR; - } + } else if (interp) { + Tcl_AppendResult(interp, "bad value for -buffering: " + "must be one of full, line, or none", NULL); + return TCL_ERROR; } return TCL_OK; } else if (HaveOpt(7, "-buffersize")) { @@ -8937,13 +8934,25 @@ Tcl_FileEventObjCmd( */ int -TclCopyChannel( +TclCopyChannelOld( Tcl_Interp *interp, /* Current interpreter. */ Tcl_Channel inChan, /* Channel to read from. */ Tcl_Channel outChan, /* Channel to write to. */ int toRead, /* Amount of data to copy, or -1 for all. */ Tcl_Obj *cmdPtr) /* Pointer to script to execute or NULL. */ { + return TclCopyChannel(interp, inChan, outChan, (Tcl_WideInt) toRead, + cmdPtr); +} + +int +TclCopyChannel( + 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. */ +{ Channel *inPtr = (Channel *) inChan; Channel *outPtr = (Channel *) outChan; ChannelState *inStatePtr, *outStatePtr; @@ -8954,14 +8963,14 @@ TclCopyChannel( inStatePtr = inPtr->state; outStatePtr = outPtr->state; - if (BUSY_STATE(inStatePtr,TCL_READABLE)) { + if (BUSY_STATE(inStatePtr, TCL_READABLE)) { if (interp) { Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(inChan), "\" is busy", NULL); } return TCL_ERROR; } - if (BUSY_STATE(outStatePtr,TCL_WRITABLE)) { + if (BUSY_STATE(outStatePtr, TCL_WRITABLE)) { if (interp) { Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(outChan), "\" is busy", NULL); @@ -9013,7 +9022,7 @@ TclCopyChannel( csPtr->readFlags = readFlags; csPtr->writeFlags = writeFlags; csPtr->toRead = toRead; - csPtr->total = 0; + csPtr->total = (Tcl_WideInt) 0; csPtr->interp = interp; if (cmdPtr) { Tcl_IncrRefCount(cmdPtr); @@ -9056,7 +9065,8 @@ CopyData( Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL; Tcl_Channel inChan, outChan; ChannelState *inStatePtr, *outStatePtr; - int result = TCL_OK, size, total, sizeb; + int result = TCL_OK, size, sizeb; + Tcl_WideInt total; const char *buffer; int inBinary, outBinary, sameEncoding; /* Encoding control */ @@ -9086,7 +9096,7 @@ CopyData( Tcl_IncrRefCount(bufObj); } - while (csPtr->toRead != 0) { + while (csPtr->toRead != (Tcl_WideInt) 0) { /* * Check for unreported background errors. */ @@ -9117,17 +9127,18 @@ CopyData( * Read up to bufSize bytes. */ - if ((csPtr->toRead == -1) || (csPtr->toRead > csPtr->bufSize)) { + if ((csPtr->toRead == (Tcl_WideInt) -1) + || (csPtr->toRead > (Tcl_WideInt) csPtr->bufSize)) { sizeb = csPtr->bufSize; } else { - sizeb = csPtr->toRead; + sizeb = (int) csPtr->toRead; } if (inBinary || sameEncoding) { size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb); } else { size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb, - 0 /* No append */); + 0 /* No append */); } underflow = (size >= 0) && (size < sizeb); /* Input underflow */ } @@ -9161,7 +9172,7 @@ CopyData( break; } if (((!Tcl_Eof(inChan)) || (cmdPtr && (mask == 0))) && - !(mask & TCL_READABLE)) { + !(mask & TCL_READABLE)) { if (mask & TCL_WRITABLE) { Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr); } @@ -9315,7 +9326,7 @@ CopyData( StopCopy(csPtr); Tcl_Preserve(interp); - Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(total)); + Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewWideIntObj(total)); if (errObj) { Tcl_ListObjAppendElement(interp, cmdPtr, errObj); } @@ -9346,9 +9357,8 @@ CopyData( * * DoRead -- * - * Reads a given number of bytes from a channel. - * - * No encoding conversions are applied to the bytes being read. + * Reads a given number of bytes from a channel. No encoding conversions + * are applied to the bytes being read. * * Results: * The number of characters read, or -1 on error. Use Tcl_GetErrno() to @@ -11273,7 +11283,7 @@ DumpFlags( char buf[20]; int i = 0; -#define ChanFlag(chr,bit) (buf[i++] = ((flags & (bit)) ? (chr) : '_')) +#define ChanFlag(chr, bit) (buf[i++] = ((flags & (bit)) ? (chr) : '_')) ChanFlag('r', TCL_READABLE); ChanFlag('w', TCL_WRITABLE); |