Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcl/tcl/ChangeLog,v
retrieving revision 1.364
diff -u -r1.364 ChangeLog
--- ChangeLog	2001/01/19 14:28:26	1.364
+++ ChangeLog	2001/01/30 17:30:31
@@ -1,3 +1,12 @@
+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]
+
 2000-01-18  Andreas Kupries  <a.kupries@westend.com>
 
 	* Everything below belongs together, it fixes bug #123153.
Index: generic/tclIO.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclIO.c,v
retrieving revision 1.27
diff -u -r1.27 tclIO.c
--- generic/tclIO.c	2000/10/28 00:29:20	1.27
+++ generic/tclIO.c	2001/01/30 17:30:32
@@ -7081,6 +7081,18 @@
 	}
 
 	/*
+	 * 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 @@
 	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,
@@ -7096,15 +7108,6 @@
 	    }
 	    return TCL_OK;
 	}
-
-	/*
-	 * 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
