From: Hal Fulton Date: 2004-05-28T00:50:39+09:00 Subject: Re: pty: I/O buffer problems??? David L Hawley wrote: > Hal, > > I'm guessing here, but I think you should read all data from the port > before calling select() again. That makes sense I suppose, but how do I know when there is no more? I don't want to block. And anyway: I thought when I read a single character, it would definitely be removed from the buffer. It seems not? I tried getc first, then sysread(1). Hal > Dave > > On Thu, 27 May 2004 17:26:52 +0900, Hal Fulton > wrote: > >> Once upon a time, Hal was coding at 3 in the morning. >> >> There was too much blood in his caffeine stream. >> >> He wrote a little program to open a pty to an interactive program -- >> ftp, in the case shown below. >> >> He noticed that when he sent a command, it was echoed back, even if he >> set noecho on the tty. He decided not to worry about this. >> >> But then he noticed that characters were being retrieved over and over, >> as though the buffer were not being emptied or something. >> >> Then he got tired of posting in second person. >> >> So anyway: I open ftp via PTY, and I send it an "open" command. (I >> picked that one randomly.) I watch the characters I get back, and I >> write them out as a "dumped" (readable) string. >> >> Of course, I do a break to kill the program after a few seconds, as >> there is no clean way to terminate this little piece of code. The >> 'ensure' clause closes my files. >> >> Here's what I get in "mylog" (excuse any linewrap): >> >> got: "\r\rftp> \rftp> " >> got: "\rftp> o\rftp> o\rftp> op\rftp> op\rftp> ope\rftp> ope\rftp> >> open\rftp> open\r\n(to) " >> >> Notice the weird way the "open" is built up a char at a time. >> >> Code is shown below. >> >> What is going on here??? >> >> Thanks for any help... >> >> Hal >> >> >> >> require 'pty' >> >> def converse(input,logfile) >> log = File.open(logfile,"w") >> dlog = File.open("debug.log","w") >> STDOUT.sync = true >> loop do >> waiting = "" >> while select([input],nil,nil,0) >> ch = input.sysread(1) >> # STDOUT.putc(ch) >> waiting << ch >> dlog.puts "w #{ch.dump}" >> end >> log.puts("got: #{waiting.dump}") if waiting!="" >> end >> ensure >> log.close >> dlog.close >> end >> >> >> PTY.spawn("/usr/bin/ftp") do |rd,wr,pid| >> begin >> wr.puts "open" >> converse(rd,"mylog") >> rescue PTY::ChildExited >> end >> end >> >> >> >> >> >> > > >