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 に近いことは難しくないはずである。