From: Brian Candler Date: 2007-05-31T21:35:41+09:00 Subject: Re: Net::Telnet and EOF On Thu, May 31, 2007 at 12:27:24PM +0100, Brian Candler wrote: > I've noticed what appears to be an inconsistency in the behaviour of > Net::Telnet's waitfor() method. > > If a timeout occurs while waiting for a match, a TimeoutError is raised (and > any data received so far is lost). > > However, if the remote end disconnects while waiting for a match, no error > is generated, and the data received so far is returned. It explicitly > rescues EOFError to do this. > > This leads to difficult usage, because if you do > > @telnet.waitfor(/prompt/) > > and it returns, it could mean one of two things: either the string you were > waiting for was matched, or it wasn't matched and the far end disconnected. > The first is what you expect, and the second is likely to be an error > condition. > > So I find that every waitfor call has to be wrapped, e.g. > > res = @telnet.waitfor(/prompt/) > unless /prompt/ =~ res > raise EOFError # or handle this situation some other way > end And for that matter, IO#expect isn't much better behaved, in that it raises a NoMethodError. Here's a program which demonstrates both: ----- 8< ------------------------------------------------------------- require 'socket' server = TCPServer.new("127.0.0.1", nil) port = server.addr[1] st = Thread.new do while socket = server.accept Thread.new(socket) do |s| s.puts "abcde" s.close end end end # Version using Net::Telnet require 'net/telnet' client = Net::Telnet.new("Host"=>"127.0.0.1", "Port"=>port) res = client.waitfor(/f/) puts res # returns successfully, even though no match # Version using IO#expect require 'expect' client = TCPSocket.new("127.0.0.1", port) client.expect(/f/) # undefined method `chr' for nil:NilClass (NoMethodError) ----- 8< ------------------------------------------------------------- This was tested with 1.8.4 under Ubuntu 6.06, but IO#expect appears to be identical in trunk: http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ext/pty/lib/expect.rb?view=markup and Net::Telnet has only one minor change, to remove #{NULL} from the stream. Regards, Brian.