Version 1 of fileevent

Updated 2001-06-22 20:10:25

http://www.purl.org/tcl/home/man/tcl8.4/TclCmd/fileevent.htm

This command is used to create file event handlers. A file event handler is a binding between a channel and a script, such that the script is evaluated whenever the channel becomes readable or writable. File event handlers are most commonly used to allow data to be received from another process on an event-driven basis, so that the receiver can continue to interact with the user while waiting for the data to arrive. (from fileevent manpage)


From a post by Paul Duffin: If you want a seperate fileevent for stderr and stdout then you will have to use some form of pipe which you can fake by using [open |] on a simple cat.exe file. e.g.

        set pipe [open |cat.exe r+]
        fileevent readable $pipe .stderr.processing.

        set process [open "|process.exe 2>@$pipe" r+]
        fileevent readable $process .stdout.processing.

NB: On *n*x machines, just say cat. On Windows machines, you have no cat.exe by default, but a number of helpful toolsets provide it, for instance the Cygnus suite. (RS)


Can one use a similar trick to put input into 'process.exe', when it asks for it on stdin? If that isn't possible, what if I know that process.exe is going to ask me for me for some specific pieces of information (say, 'name <return> password <return>'). Could I pass that in with 'fileevent writable'? -- Vince. No--if I [CL] understand the question correctly. However, exec does support [exec $myprog << $text], which might be what you're after. It's a great convenience, worth learning, in any case. RS: ... and if you want to send something to a process's stdin, depending on a prompt from that, it looks very much like a job for Expect...


Kevin Kenny wrote in the comp.lang.tcl newsgroup:

The usual pattern for reading asynchronously from a pipe is something like:

 proc isReadable { f } {
    # The channel is readable; try to read it.
    set status [catch { gets $f line } result]
    if { $status != 0 } {
        # Error on the channel
        puts "error reading $f: $result"
        set ::DONE 2
    } elseif { $result >= 0 } {
        # Successfully read the channel
        puts "got: $line"
    } elseif { [eof $f] } {
        # End of file on the channel
        puts "end of file"
        set ::DONE 1
    } elseif { [fblocked $f] } {
        # Read blocked.  Just return
    } else {
        # Something else
        puts "can't happen"
        set ::DONE 3
    }
 }
 # Open a pipe
 set fid [open "|ls"]

 # Set up to deliver file events on the pipe
 fconfigure $fid -blocking false
 fileevent $fid readable [list isReadable $fid]

 # Launch the event loop and wait for the file events to finish
 vwait ::DONE

 # Close the pipe
 close $fid

client/server with fileevent is an example showing asynchronous read/write communication over a pipe with fileevent, in a single script.


Tcl syntax help - Arts and crafts of Tcl-Tk programming