Lua とは、ちょっと癖のあるインタープリターであるが、コードも文法もコンパクトで、速度には定評がある(Python に比べて 10 倍ほど速い)ので一部には強い人気がある。移植性は非常に高い。殆どの OS で動いていると思ってよい。Plan9 にも僕の移植版がある。
Plan9 独自の関数を追加した Lua が 9Lua で、これも僕の移植版がある。
いずれも
http://p9.nyx.link/netlib/lua/
から手に入る。
a1
はファイルを読み取って、その内容を書きだすプロクラムである。chmod 755
a1
#!/bin/lua f=io.open(arg[1]) s = f:read("a") print(s) f:close()これで
a1 xxx
xxx
を読み取って表示してくれる。read("a")
の "a"
はファイルの全部を読み取るオプションである。この他に1行だけを読み取るオプションなどがある。
/net/dns
にリクエストを送る/net/dns
を読み取る
次のプログラムで動くはずであるが...
f = io.open("/net/dns","r+") f:write("amazon.com ip") f:seek("set",0) s = f:read("a") while s and #s>0 do print(s) s = f:read("a") end f:close()結果は
amazon.com ip 54.239.28.85amazon.com ip 205.251.242.103amazon.com ip 52.94.236.248となる。これは実は正しくない。正しくは
ndb/dnsquery
と同じamazon.com ip 54.239.28.85 amazon.com ip 205.251.242.103 amazon.com ip 52.94.236.248となるべきである。
なぜこのような問題が発生したが?
Lua で使われている読み取り関数が Plan9 の特殊な出力様式に対応していないからと考えられる。
どうやら名前付き pipe による Plan9 のデータベースの応答では、レコードの区切りに 文字が使われていないらしい。
9Lua は Plan9 の I/O 関数をサポートしている。これを使うと問題は解決する。
先のプログラムは次のようになる。
f = p9.open("/net/dns","rw") p9.write(f,"amazon.com ip") p9.seek(f,0,"set") s = p9.read(f) while s and #s>0 do print(s) s = p9.read(f) end p9.close(f)となる。
なお while
を使って読み取りが行われているのは、実際にはデータは1回で来る保証は無いからである。
次に Lua を使って通信がどのように行われるかを見る。
次は 192.168.0.7
の tcp 80 ポートにアクセスして
GET /
wget http://192.168.0.7:80
function test1() cfd = p9.open("/net/tcp/clone","rw") assert(cfd>0,"/net/tcp/clone not open") cn=p9.read(cfd) -- connection number in string. 18 print(cn) conreq = "connect 192.168.0.7!80" -- need IP n = p9.write(cfd, conreq) assert(n == #conreq, "connection request failed") data = "/net/tcp/"..cn.."/data" print("data",data) fd = p9.open(data,"rw") assert(fd, data.." not open") req = "GET /\r\n" -- GET request n = p9.write(fd,req) assert(n == #req, "write error: "..req) p9.seek(fd,0,"set") s = p9.read(fd) while s and #s>0 do print(s) -- OK s = p9.read(fd) end p9.close(fd) end test1()
注意しておくが、これで wget
と同じことが出来るわけではない。wget
並みのことが出来るためにはもっともっと多くのコードを追加しなくてはならない。
それでもこのプログラムには TCP 通信のエッセンスが含まれている。netcat
に近いことは難しくないはずである。