1

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 ?

Vahagn
  • 4,670
  • 9
  • 43
  • 72

2 Answers2

3

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
schlenk
  • 7,002
  • 1
  • 25
  • 29
  • The problem is this. An input is available at `stdin`, and I want to read that input. I can read it line by line with `gets` command, but the last `gets` will hang and wait for input to be entered. At the code above it is the same situation. – Vahagn Jan 05 '12 at 19:12
  • 2
    No, the important part is the 'fconfigure -blocking false'. – schlenk Jan 05 '12 at 19:54
  • I don't think there's any circumstance under which `gets` succeeds with a negative value yet both `eof` and `fblocked` are false. The other problem cases I think are either handled directly in the IO library or reflected out as errors from `gets`. – Donal Fellows Jan 05 '12 at 20:17
  • OK. If `fconfigure -blocking false` then `gets` will not hang. But in this case, if inputs doesn't end with newline character, then the last part of the input (the part from last newline up to the end of the input) will not be read. And this yields to another problem: http://stackoverflow.com/questions/8750139/how-to-check-if-stdin-buffer-is-empty-at-tcl – Vahagn Jan 05 '12 at 21:35
0

If you look at the answer to this question you can see how to use fconfigure to put the channel into non-blocking mode. There is a lot more detailed information on this Tcl manual, you need to look at the fconfigure manual page together with the vwait manual page.

Community
  • 1
  • 1
Jackson
  • 5,627
  • 2
  • 29
  • 48