summaryrefslogtreecommitdiffstats
path: root/generic/tclIO.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclIO.c')
-rw-r--r--generic/tclIO.c207
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;