ずっと前から、コマンドラインやスクリプトで 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]