有馬です。

とみたまさひろ <tommy / tmtm.org> wrote

| # select で [[f], nil, nil] は返らないんじゃないかと…。[[f], [], []] の
| # 間違い?

そのとおりです。[[f], [], []] でした。

| linux 2.2 で試してみたところ特に問題ないようです。

sysread を使って以下を書いてみたところ、1バイト欠けてしまいます。

--
require "socket"

gs = TCPServer.open(9000)
socks = [gs]
addr = gs.addr
addr.shift
printf("server is on %d\n", addr.join(":"))

while TRUE
  nsock = select(socks)
  next if nsock == nil
  for s in nsock[0]
    if s == gs
      ss = s.accept
      socks.push(ss)
      print(ss, " is accepted\n")
    end
  end
  break if socks.size == 2
end

si = socks[1]
so = socks[1]
socks.delete(gs)

$stdout.sync = true
so.sync = true

fg = false

while socks.size > 0
  nsock = select(socks, nil, nil, 1)
  print (if fg then "*" else "-" end)
  next if nsock == nil
  reads, writes, excepts = nsock
p nsock
  while ns = reads.shift
    if ns == si
      if ns.eof?
        socks.delete(ns)
        break
      end
      str = ns.sysread(10)
p str
      case str.upcase
      when /START/
        fg = true
        so.write str + "\n"
      when /STOP/
        fg = false
        so.write str + "\n"
      when /QUIT/
        ns.close
        socks.delete(ns)
        break
      else
        so.write str + "\n"
      end
    end
  end
  break if not excepts.empty?
end
--
require "socket"

port = if ARGV.size > 0 then ARGV.shift else 9000 end
print port, "\n"
s = TCPSocket.open("localhost", port)

$stdout.sync = true

th = Thread.start do
  while str = s.gets
    break if str == nil
    print str
  end
  print "shut"
end

socks = [s]
loop do
  str = gets #.chomp
  break if /!/ =~ str
  nsock = select(socks, nil, socks, 0)
  if nsock
    reads, writes, excepts = nsock
    break if s.eof?
    if not reads.empty?
      str = s.gets
      break if str == nil
    end
    break if not excepts.empty?
  end
  s.write(str)
end
s.close
--

--
 有馬 康弘 <fit0298 / fitec.co.jp>