From: Thorsten Haude Date: 2006-07-07T06:58:05+09:00 Subject: ruby-termios --U+BazGySraz5kW0T Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Hi, I wrote a program on Linux using ruby-termios which was supposed to run on Solaris 9. Short description: It doesn't. Long description: I use ruby-termios to change some terminal settings for my simple user interface, a menu in this case. It looks like this: def fetch letter =3D nil print @data['text'] menuMode { letter =3D $stdin.readchar.chr until @data['options'].include?(letter.upcase) do letter =3D $stdin.readchar.chr end } return letter end In this part, @data['text'] contains a menu text, @data['options'] is a list of valid characters. Here is the termios part of the code: def menuMode term =3D Termios::getattr($stdin) oldterm =3D term term.c_lflag &=3D ~(Termios::ECHO | Termios::ICANON) =20 Termios::setattr($stdin, Termios::TCSANOW, term) yield Termios::setattr($stdin, Termios::TCSANOW, oldterm) Termios::flush($stdin, Termios::TCIOFLUSH) end The result on Linux is what I expected: I get the characters one by one and can work on them before they are displayed or in any buffer I care for. Some strange things happen on Solaris: First of all, my debugging shows that something changes the termios flags where I don't expect it: def menuMode term =3D Termios::getattr($stdin) oldterm =3D term @logger.debug("c_lflag is #{term.c_lflag}") term.c_lflag &=3D ~(Termios::ECHO | Termios::ICANON) =20 Termios::setattr($stdin, Termios::TCSANOW, term) yield @logger.debug("c_lflag is #{oldterm.c_lflag}") Termios::setattr($stdin, Termios::TCSANOW, oldterm) Termios::flush($stdin, Termios::TCIOFLUSH) end Here is a fragment from the logfile: D, [2006-06-13T15:45:23.732487 #18771] DEBUG -- : c_lflag is 35387 D, [2006-06-13T15:45:29.987362 #18771] DEBUG -- : c_lflag is 35377 Why are the two flags different? Second, some buffering is going on. If I enter a character, the program blocks at the readchar. If I run this version of fetch() 1 def fetch 2 letter =3D nil =20 3 print @data['text'] 4 menuMode { 5 @logger.debug("Enter yielded block") 6 letter =3D $stdin.readchar.chr 7 @logger.debug("Read in letter '#{letter}'") =20 8 until @data['options'].include?(letter.upcase) do 9 @logger.debug("Enter loop block") 10 letter =3D $stdin.readchar.chr 11 @logger.debug("Read in letter '#{letter}'") 12 end 13 } =20 14 return letter 15 end =2E..the program blocks at lines 6 and 10 until I enter four characters. Th= en all input is passed to the program, so for an invalid character the result looks like this: D, [2006-06-13T15:55:09.230396 #19028] DEBUG -- : Enter yielded block D, [2006-06-13T15:55:13.383131 #19028] DEBUG -- : Read in letter 't' D, [2006-06-13T15:55:13.383816 #19028] DEBUG -- : Enter loop block D, [2006-06-13T15:55:13.384062 #19028] DEBUG -- : Read in letter 't' D, [2006-06-13T15:55:13.384284 #19028] DEBUG -- : Enter loop block D, [2006-06-13T15:55:13.384498 #19028] DEBUG -- : Read in letter 't' D, [2006-06-13T15:55:13.384710 #19028] DEBUG -- : Enter loop block D, [2006-06-13T15:55:13.384918 #19028] DEBUG -- : Read in letter 't' D, [2006-06-13T15:55:13.385132 #19028] DEBUG -- : Enter loop block For valid character this means that the first chracter picks a menu option and the next three characters are entered in whatever is behind that menu option. Nearly unusable and pretty dangerous. At the moment I don't know where to look next. It may be some simple omission, but I can't find it, so any ideas are appreciated. Please let me know if you need any other information, the debugging is a bit awkward, but I didn't dare to call the debugger with broken terminal. Thanks in advance! Thorsten Radiohead: Subterranean Homesick Alien --=20 Be alert - Some terrorists look normal. --U+BazGySraz5kW0T Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.1 (GNU/Linux) iD8DBQFErYbWW/x2JEBlodoRAjPnAKD0nWr7sPGACxHOMS4QJW2fckUzQwCeMEPH BpZGNyBoabchkmV03OIo570= =GQJr -----END PGP SIGNATURE----- --U+BazGySraz5kW0T--