ずっと前から、コマンドラインやスクリプトで TCP 接続をしなければならなくて、かつ、telnet のおせっかいが邪魔なときには socket コマンドを使っている。
が、今日、EOF の伝播が甘いことでトラブルに出会ってしまった。
やっぱ netpipes かなぁ。でも hose はなんかオプションが必要だしなぁ。
標準入出力を close することが security hole につながる話がたしか以前あったはずだと思って探してみる。
そういえば、読み込み側が終了したのを検出して書き込み側に終了を伝えるというのは遅延無しに実現できるが、逆に、書き込み側が終了したのを検出するのは難しい。
読み込み側の終了は EOF (read が 0 を返す) ので即座に分かるが、書き込み側の終了は何か書いたときに EPIPE になって始めて分かるので、何も書くものがない限り分からない。
そこで、なんとなく、TCP で 0byte 書き込むとどうなるのかを試してみた。
% cat client.c #include <stdlib.h> #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> extern int h_errno; #include <arpa/inet.h> #include <netinet/in.h> #include <unistd.h> int main(int argc, char **argv) { int s; int ret; char *host = argv[1]; char *port = argv[2]; s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) { perror("socket"); exit(1); } struct sockaddr_in addr; addr.sin_family = AF_INET; ret = inet_pton(AF_INET, host, &addr.sin_addr); if (ret < 0) { perror("inet_pton"); exit(1); } if (ret == 0) { fprintf(stderr, "inet_pton failed: %s\n", host); exit(1); } addr.sin_port = htons(atoi(port)); ret = connect(s, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) { perror("connect"); exit(1); } sleep(1); ret = write(s, "", 0); if (ret == -1) { perror("write"); exit(1); } sleep(1); ret = send(s, "", 0, 0); if (ret == -1) { perror("send"); exit(1); } sleep(1); struct msghdr msg; struct iovec iov; iov.iov_base = ""; iov.iov_len = 0; msg.msg_name = NULL; msg.msg_namelen = 0; msg.msg_iov = &iov; msg.msg_iovlen = 1; msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_flags = 0; ret = sendmsg(s, &msg, 0); if (ret == -1) { perror("sendmsg"); exit(1); } sleep(1); return 0; }
というのは write, send, sendmsg で 0byte 書き込むプログラムで、これを
% ruby -rsocket -e ' TCPServer.open(8888) {|serv| loop { sock = serv.accept p sock sock.close } }'
という、accept したら即座に close するサーバに繋げて試す。
まぁ、結果は書き込みが成功してしまって、書き込み側の終了はやはり検出できないということが分かった。
なんか、うまい方法はないのかなぁ。
ふと、ハーフクローズとハーフオープンという用語が対でないことに気がつく。
% google-count --quote {1990..2040}年問題 14 1990年問題 34 1991年問題 33 1992年問題 82 1993年問題 12 1994年問題 19 1995年問題 30 1996年問題 49 1997年問題 282 1998年問題 145 1999年問題 333000 2000年問題 358 2001年問題 233 2002年問題 20700 2003年問題 182 2004年問題 10100 2005年問題 875 2006年問題 163000 2007年問題 701 2008年問題 210 2009年問題 914 2010年問題 133 2011年問題 200 2012年問題 23 2013年問題 10 2014年問題 123 2015年問題 1 2016年問題 11 2017年問題 3 2018年問題 28 2019年問題 135 2020年問題 0 2021年問題 0 2022年問題 11 2023年問題 32 2024年問題 51 2025年問題 0 2026年問題 6 2027年問題 2 2028年問題 0 2029年問題 37 2030年問題 5 2031年問題 18 2032年問題 101 2033年問題 4 2034年問題 4 2035年問題 57 2036年問題 61 2037年問題 955 2038年問題 15 2039年問題 43 2040年問題
GoboLinux を起動して少し眺めてみる。
ls / で usr とかが出て来ないのに、ls /usr ができるのはなんでだ?
「ハッカーのたのしみ」の乗算のオーバーフロー検出の項を読んでみる。
close(2) で EINTR になったときの file descriptor の状態は規定されていないことを知る。
そーか、close は retry してはいけないのか。
携帯用の電子辞書を買ってみた。
音が出るというので出してみようとするが、どうも出ない。
どうせ間抜けな話に違いないと思ったが、どうもどういう間抜けさなのか思いつかなかったので、説明書の「故障かな? と思ったら」という項を読んでみる。
すると、音が出ないという症状はちゃんと書いてあって、いくつか書いてあった原因のうちひとつが実際に問題であった。つまり、ボリュームが最小になっていた。
うぅむ。この類の項はいろんな説明書に書いてあって、これまで生きて来て一度も役に立ったことがなく、あんなのが役に立つことはあるんだろうかと疑問に思っていたのだが、どうも役に立つことはあるらしい。
飛行機
横になって眠ったのは始めてな気がする
RubyConf 2005
発表
せっかくなので、google.com から google.co.jp にリダイレクトされるかどうか試してみる。
% telnet www.google.com 80 Trying 64.233.161.99... Connected to www.google.com. Escape character is '^]'. GET / HTTP/1.0 HTTP/1.0 200 OK Cache-Control: private Content-Type: text/html Set-Cookie: PREF=ID=87e6e938ee3898ef:TM=1129482919:LM=1129482919:S=PceoSj8xrUWYGAD8; expires=Sun, 17-Jan-2038 19:14:07 GMT; path=/; domain=.google.com Server: GWS/2.1 Date: Sun, 16 Oct 2005 17:15:19 GMT Connection: Close <html><head>...
やはりここではされないか。
雨に降られる
2軒の本屋にいったが、両方ともマンガがあった
普通の本屋におくようになったのだろうか
Lightning Talk を聞く
受け狙いなのが少ない
硬貨を使うのは難しい
gcc の [4.1 Regression] -1073741824 <= n && n <= 1073741823 is true where n is 1073741824 で、Andrew Pinski はあまりの反応のなさにめげちゃったかんじ?
そういえば、<URL:http://convergepl.org> は気になる。
このまえ買った電子辞書ではメモリースティックに MP3 を入れておくと聞けるようなので、メモリースティック (とリーダ&ライタ) を買って来て、IT Conversations からちょっと落して聞いてみる。
ふと、「天文学者 物理学者 数学者」を google で検索してみる
少なくとも羊と牛とその他ひとつのバージョンが存在するようだ
調子が悪いときには眠るに限る
[latest]