Hi there,

I am making a multi-user, telnet based, bbs. At work I use Linux Ruby,
at home a Win32 port. (http://rubyinstaller.rubyforge.org/wiki/wiki.pl)

Now a multi-user server can be done in threads, but since I want to keep
it simple and avoid dead-locks and starvation problems, I decided not to
use threads. (I also read that threads can block the whole program if
they get stuck in system calls. That's not something I want.)

Instead I want to use a select, which is thankfully support in Ruby.
However a read to a socket which has data open always seems to block,
unless I specifically read what is available. Since I cannot know how
much data is waiting for me, I really need to do a non-blocking read. In
Linux it works, in Windows the fcntl call is not supported. :( As far as
I searched and tried, there is no other way to read data without blocking.

This guy

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/3155

seems to have made a fix some time ago. Can I ask why it is not in the
standard distribution? On that note, can somebody point me to a binary
win32 distribution that _does_ have this patch incorporated?

One last thing. I ran the example below on both Linux and Win32.
Normally stdout buffering is done up until a '\n' after which output is
flushed (ANSI C, both on Linux and Win32). This behaviour is seen on the
Linux Ruby port, but not under Win32 where I had to put in
'STDOUT.sync=true'. Can this be considered a bug?

I'm using:
ruby 1.8.2 (2004-12-25) [i386-mswin32]
ruby 1.8.2 (2004-12-25) [i686-linux]



Server example, works on Linux, not on Win32:

# socket example - server side
# usage: ruby svr.rb

require "socket"
require "fcntl"

gs = TCPserver.open(0)
addr = gs.addr
addr.shift
printf("server is on %s\n", addr.join(":"))
socks = [gs]

loop do
   nsock = select(socks);
   next if nsock == nil
   for s in nsock[0]
     if s == gs
       ns = s.accept
       ns.fcntl(Fcntl::F_SETFL, Fcntl::O_NONBLOCK)
       socks.push(ns)
       print(s, " is accepted\n")
     else
       if s.eof?
         print(s, " is gone\n")
         s.close
         socks.delete(s)
       else
         print "[" + s.read + "]\n"
       end
     end
   end
end