Search code examples
tclstdingetsreadable

How to check if stdin is readable in TCL?


With the following command you can register some callback for stdin:

fileevent stdin readable thatCallback

This means that during the execution of the update command it will evaluate thatCallback time after time while there is input available at stdin.

How can I check if input is available at stdin ?


Solution

  • You simply read/gets from stdin inside your callback. Basically the pattern goes like this snippet from the fileevent example from Kevin Kenny:

    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