From: <no...@so...> - 2001-01-26 01:48:35
|
Bug #118203, was updated on 2000-Oct-25 17:54 Here is a current snapshot of the bug. Project: Tcl Category: Other IO Status: Open Resolution: None Bug Group: 8.4a2 Priority: 7 Submitted by: nobody Assigned to : dgp Summary: fcopy -command, which is supposed to run in the background, Details: OriginalBugID: 2457 Bug Version: 8.1.1 SubmitDate: '1999-07-28' LastModified: '2000-04-03' Severity: SER Status: Closed Submitter: techsupp ChangedBy: hobbs OS: Windows 95 Machine: X86 FixedDate: '2000-10-25' ClosedDate: '2000-04-03' Name: Keith Lea ObservedBehavior: I use [fcopy] with the -command option to set up a callback loop for an FTP client I am developing. However, when uploading ([fcopy]ing from a file to a socket) the fcopy hangs the application and says the number of bytes transferred is lower than the actual amount sent (verified by looking on the server's side). Is there an associated script to verify this? Also, try 8.2 first with Win95, where the underlying file event stuff was revamped. -- 04/03/2000 hobbs Follow-Ups: Date: 2001-Jan-25 17:48 By: dgp Comment: I've re-opened this [fcopy] bug since it is the same one that broke tclhttpd3.2.1 and the TCT's TIP drafting and archive service. Here are three scripts that demonstrate the bug. First a server program: # FILE: server.tcl proc connect {socket ip port} { set pipe [open [list | [info nameofexecutable] cgi.tcl 2>@ stderr] r+] fconfigure $pipe -blocking 0 fileevent $socket readable [list startcopy $pipe $socket] } proc startcopy {pipe socket} { if {[gets $socket size] < 0} { if {[eof $socket]} {exit} # Not EOF; assume blocked - wait and try again return } # Force input buffer bigger than whole message # (bigger than output channel flush threshold) fconfigure $socket -buffersize [expr {$size + 1}] fileevent $socket readable {} puts stderr "server: copying $size bytes to cgi..." fcopy $socket $pipe -size $size -command [list donecopy $size] } proc donecopy {size written {msg {}}} { puts stderr "server: copied $written bytes to cgi." if {$size != $written} { puts stderr "server: bytes written ($written) != bytes read ($size)" } if {[string length $msg]} { puts stderr "Copy error: $msg" } set ::done 1 } socket -server connect 5000 vwait done The server program spawns a "CGI" process: # FILE: cgi.tcl puts stderr "cgi: reading data..." set data [read stdin] puts stderr "cgi: received [string length $data] bytes" And there is a client program: # FILE client.tcl # # Create message longer than CGI pipe flush threshold: set data a #set exp 13 ;# Liunx - flush threshold is 4096 set exp 15 ;# Solaris - flush threshold is 16384 while {[incr exp -1]} { set data $data$data } append data b ;# Exceed threshold by 1 set s [socket localhost 5000] fconfigure $s -buffering none puts $s [string length $data] puts -nonewline $s $data flush $s # Wait as many milliseconds as caller asks after [lindex $argv 0] First start the server in one shell window: $ tclsh server.tcl Then start the client in another shell window. The client takes an argument -- the number of milliseconds to wait between sending data to the server and exiting (closing the connection). $ tclsh client.tcl 0 Back in the server window, see these messages: server: copying 4097 bytes to cgi... cgi: reading data... server: copied 0 bytes to cgi. server: bytes written (0) != bytes read (4097) cgi: received 4097 bytes Note that the server believes it sent 0 bytes on to the cgi process, though the cgi process knows it received all 4097 bytes. Try it again, this time with a delay in the client: $ tclsh client.tcl 10000 Server messages: server: copying 4097 bytes to cgi... cgi: reading data... <10 second delay> server: copied 0 bytes to cgi. server: bytes written (0) != bytes read (4097) cgi: received 4097 bytes The server is still confused about how many bytes it copied over to the cgi process, plus it hangs the whole time the client program keeps the socket connection open. Imagine the trouble when client.tcl is replaced with a web browser that does not close its connection after sending POST data! This is why I saw Netscape 4.74 spinning its wheel each time I tried to submit new TIP revisions! The problem can be tracked to bad management of the count of the number of bytes copied in the CopyData() routine in generic/tclIO.c. A patch correcting the problem is on the way. This bug dates back all the way to Tcl 8.0, as long as [fcopy] has been around. In particular, it is in both 8.3.2 and 8.4a2. The next releases of both 8.3 and 8.4 ought to include the fix. ------------------------------------------------------- For detailed info, follow this link: http://sourceforge.net/bugs/?func=detailbug&bug_id=118203&group_id=10894 |