From: Adam Shelly Date: 2007-10-04T15:34:08+09:00 Subject: Re: Non-blocking 'gets' ? On 10/3/07, Stephen Ware wrote: > Is there a way to perform a non-blocking gets or getc? As in a method > that reads a character from stdin if there is one in the buffer or > returns nil otherwise? If I was programming a Windows console app in C, I would use kbhit() to check if there was a character in the buffer. So I decided this was a good time to try writing my first ruby c extension. on Windows, save and complie conio.c into conio.dll, and then the following example should work. -Adam --- test_conio.rb --- require 'conio' #background work: Thread.new { print('.') or sleep(1) while true } #check for input in this thread Thread.new do while 1 while !CONIO::kbhit?; end #--wait for key, nonblocking #s = STDIN::getc #--this blocks until return pressed s = CONIO::getch #--this doesn't p "#{s} (#{s.chr})" exit if s==?q end end #do some foreground work puts("waiting") or sleep(10) while 1 --- ---conio.c--- /* conio.c -- Windows conio functions 3 Oct 2007, Adam Shelly Ruby license applies */ #include "ruby.h" #include static VALUE c_kbhit(VALUE self) { return _kbhit()? Qtrue : Qfalse; } static VALUE c_getch(VALUE self) { int n = _getch(); return INT2FIX(n); } static VALUE c_ungetch(VALUE self, VALUE cv) { int c = FIX2INT(cv); int n = _ungetch(c); return INT2FIX(n); } VALUE mConio; __declspec( dllexport ) void Init_conio() { mConio = rb_define_module("CONIO"); rb_define_module_function(mConio, "kbhit?", c_kbhit, 0); rb_define_module_function(mConio, "getch", c_getch, 0); rb_define_module_function(mConio, "ungetch", c_ungetch, 1); }