クライアント
telnet -u が便利…だと思ったら MacOSX と FreeBSD には telnet -u あるんだけど、手元の Linux には無いみたいで困る。 unixclient では作れないかなぁ…と思ったので Ruby でサックリと。
require 'socket' sock = UNIXSocket.open(ARGV[0]) inputs = [STDIN, sock] while true i, o, e = IO.select(inputs) i.each do |input| if input == STDIN c = STDIN.getc if c sock.putc(c) sock.flush else sock.close_write inputs = [sock] end elsif input == sock c = sock.getc if c STDOUT.putc(c) else exit end end end end
ucspi-unix には unixcat ってのがついていて、それで良さげに思えるんだけど、中身見ると
exec unixclient "$1" sh -c 'exec cat <&6'
とかいう shell script (unixclient は unixserver のクライアントバージョンで、指定したプログラムと fd 6 と 7 を使ってやりとりする) で、これは unix domain socket の吐いた内容の出力はできるけど入力はできないと思う。入力をやるなら、
cat >&7 cat <&6
とかを実行させればいい気がするんだけど、なんにせよこれらだと接続終了時に終了しない。これはたぶんサーバ側の cat が終わってないからで、一個目の cat が終了した後に終わらない理由は書き込み側の終了を伝えてないからだと思う。 7 を閉じちゃえばいいようにも思えるんだけど、これ socket だから 6 も 7 も同じファイルディスクリプタで書き込み側とかの区別がなくて、閉じちゃえば接続が切れてしまって今度は受信ができない。 shell から shutdown(fd, SHUT_WR); 的なことができるといいんだけど。
このへんの事情は TCP socket も同じで、よくわからんけど、読み書きを一つのファイルディスクリプタでやるっていう設計のせいなのかなぁ。 TODO: Plan9 とかどうやってるんだろう。