also, try the highline gem for help in dealing with input in general

Timeout:timeout creates a new thread with a time limit.  Is would not
be to hard to hack it up to make a way to be able to keep reseting that
timer if you didn't want the overhead of continually creating new
threads.
One approach would be to implement a rescue and then retry if you have
received input.  Here is my quick attempt.  The thread which calls
timeout is responsible to keep setting Thread.current[:timeout] = false
whenever it receives input

  def timeout(sec, exception=Error)
    return yield if sec == nil or sec.zero?
    raise ThreadError, "timeout within critical session" if
Thread.critical
    begin
      x = Thread.current
      y = Thread.start {
        begin
          until x[:timeout]
            x[:timeout] = true
            sleep sec
          end
          x.raise exception, "execution expired" if x.alive?
        end
      }
      yield sec
      #    return true
    ensure
      y.kill if y and y.alive?
    end
  end


Thread.abort_on_exception = true