summaryrefslogtreecommitdiffstats
path: root/generic
diff options
context:
space:
mode:
authordgp <dgp@users.sourceforge.net>2001-01-30 17:32:06 (GMT)
committerdgp <dgp@users.sourceforge.net>2001-01-30 17:32:06 (GMT)
commitdf71cf45613c6413eeb9e17cacd5f241e74fd84b (patch)
tree010382a4601a659b623c45b45d3f5502ffb4f210 /generic
parent23ad38a8fe16319656b29d3d8171ac25653e0525 (diff)
downloadtcl-df71cf45613c6413eeb9e17cacd5f241e74fd84b.zip
tcl-df71cf45613c6413eeb9e17cacd5f241e74fd84b.tar.gz
tcl-df71cf45613c6413eeb9e17cacd5f241e74fd84b.tar.bz2
2000-01-30 Don Porter <dgp@users.sourceforge.net>
* generic/tclIO.c (CopyData): Moved code that updates the count of how many bytes are left to copy. Corrects bug that when writing occurs in the background, the copy loop could be escaped without updating the count, causing CopyData() to try to copy more bytes than the toRead value originally passed to TclCopyChannel(), leading to hangs and misreporting of number of bytes copied. [Bug 118203, Patch 103432]
Diffstat (limited to 'generic')
-rw-r--r--generic/tclIO.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 3e68249..1718d15 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.27 2000/10/28 00:29:20 hobbs Exp $
+ * RCS: @(#) $Id: tclIO.c,v 1.28 2001/01/30 17:32:06 dgp Exp $
*/
#include "tclInt.h"
@@ -7081,6 +7081,18 @@ CopyData(csPtr, mask)
}
/*
+ * Update the current byte count. Do it now so the count is
+ * valid before a return or break takes us out of the loop.
+ * The invariant at the top of the loop should be that
+ * csPtr->toRead holds the number of bytes left to copy.
+ */
+
+ if (csPtr->toRead != -1) {
+ csPtr->toRead -= size;
+ }
+ csPtr->total += size;
+
+ /*
* Check to see if the write is happening in the background. If so,
* stop copying and wait for the channel to become writable again.
*/
@@ -7088,7 +7100,7 @@ CopyData(csPtr, mask)
if (outStatePtr->flags & BG_FLUSH_SCHEDULED) {
if (!(mask & TCL_WRITABLE)) {
if (mask & TCL_READABLE) {
- Tcl_DeleteChannelHandler(outChan, CopyEventProc,
+ Tcl_DeleteChannelHandler(inChan, CopyEventProc,
(ClientData) csPtr);
}
Tcl_CreateChannelHandler(outChan, TCL_WRITABLE,
@@ -7098,15 +7110,6 @@ CopyData(csPtr, mask)
}
/*
- * Update the current byte count if we care.
- */
-
- if (csPtr->toRead != -1) {
- csPtr->toRead -= size;
- }
- csPtr->total += size;
-
- /*
* For background copies, we only do one buffer per invocation so
* we don't starve the rest of the system.
*/