Ruby版cygterm
cygtermをRubyに移植してみました。TCP/IPのサーバの実装、仮想端末のサンプルとしてお手頃かと思います。
使い方。以下のプログラムをcygterm.rbwというファイル名で保存して、拡張子.rbwをcygwinのrubywコマンドに関連付けてください。あとはcygterm.rbwをダブルクリックすればOK。設定はプログラムを適当に書き換えてください。とりあえずデフォルトの場所にインストールしたTeraTermが起動するようにしています。
ファイル: cygterm.rbw
#!/usr/bin/env ruby class Telnet require 'socket' def initialize(port_range, command, args = '') ssock, port = setup_ssock(port_range) fork do exec(command, *(sprintf(args, ssock.addr[2], port)).split) end raise 'timeout.' unless select([ssock], [], [], 5) @sock = ssock.accept raise 'invalid peer.' unless @sock.peeraddr[3] == '127.0.0.1' end attr_reader :sock def setup_ssock(port_range) port_range.each do |port| begin return TCPServer.open('localhost', port), port rescue Errno::EADDRINUSE # ignore end end raise 'available port not found.' end private :setup_ssock end class Shell require 'pty' def initialize(env, command, args = '') ENV.update(env) @rpty, @wpty, pid = PTY.spawn(command + args) end attr_reader :rpty, :wpty end if $0 == __FILE__ telnet = Telnet.new(20000 ... 20040, 'C:/program files/ttermpro/ttermpro.exe', '%s %d /T=0 /KR=SJIS /KT=SJIS') shell = Shell.new({'TERM' => 'vt100'}, '/bin/zsh') begin loop do ios = select([telnet.sock, shell.rpty]) next unless ios ios[0].each do |io| out = (io == shell.rpty) ? telnet.sock : shell.wpty out.syswrite(io.sysread(1024)) end end rescue EOFError, PTY::ChildExited # ignore end end
BUGS: