〜2002年2月下旬〜
incr/からpatch-2.4.18-rc1-rc2.bz2を取ってきた。やっぱこのほうが楽だ。
更新。
ピンポーンと誰か来た。ペリカン便だった。上記のRDGが来た。 というか10時過ぎてる。来なきゃ昼まで寝ていたに違いない。 おっちゃんありがとう。 でも今日は会社で10時から打ち合わせがあったんだよ。ぐふっ。
ふとw3m Mew.pngしてみたが
Hit any key to quit w3m:
とつれない返事。-T image/pngもつけたらどう?やっぱ同じ。 じゃ、これでどうだ。
% echo '<img src="Mew.png">' |w3m -T text/html
やっと2匹の仔猫が出た。というかこれなら出て当たり前だな。
更新。
ちゃんと公約通り2ヶ月毎に出すのはすごいなあ。
久し振りに@niftyでコメント書いた気がする。 調べてみると、去年の12月13日以来だ。
makeanimtab.shというシェルスクリプトで
animcount=$(( $animcount + 1 ))
のように使われている。ashでは計算してくれないのはいいが、 単に$(())を無視するようだ。で、animcountの初期値が0なので
0 + 1 + 1 + 1 + 1 + 1
になり、それが
#define NUMANIMS 0 + 1 + 1 + 1 + 1 + 1
となれば最終的には問題なさそうだが、なぜか
#define NUMANIMS 0 + 1 + 1 + 1 + 1 + 1 ^G
とC-gがつく。これは流石にgccも無視はしてくれない。 しかたないので、あらかじめここだけbashで実行しておいた。
結局1時間程使って IceWM に戻したのであった。
ruby-talkを見てるとmswin32版だとpopenが動かないという結論になってるようだけど、 そうなんだっけ?
% c:/usr/local/bin/ruby -ve 'p IO.popen("ls").gets' ruby 1.6.6 (2002-02-22) [i386-mingw32] "COPYING\n"
問題ないよねえ。逆はというと
% c:/usr/local/bin/ruby -ve 'IO.popen("grep abc","w"){|x|x.print "abc\n"}' ruby 1.6.6 (2002-02-22) [i386-mingw32]
あ、だめだ。Cygwin版だと
% ruby -ve 'IO.popen("grep abc","w"){|x|x.print "abc\n"}' ruby 1.6.6 (2002-02-22) [i386-cygwin] abc
とokだ。このことを言っているのか?1.7なら
% c:/usr/local/bin/ruby-1.7 -ve 'IO.popen("grep abc","w"){|x|x.print "abc\n"}' abc ruby 1.7.2 (2002-02-22) [i386-mingw32]
とok。順番が違うのはバッファリングの影響なので気にしないように。
やっぱmswin32/mingw32版ruby 1.6はいけてない。 いまさらbackportして1.6をいじるのもなんだし、 _popen/_pcloseでお茶を濁すのはどうだろう?
0.15が出てたので更新。
存在しないファイルをcatするとSEGVるのに気づいた。 ltraceしてみると
% ltrace cat hoge <snip> open("hoge", 0, 010000236064) = -1 __errno_location() = 0x4012fda0 error(0, 2, 0x0804ca4e, 0xbffff7fc, 0x40013c34 <unfinished ...> --- SIGSEGV (Segmentation fault) --- +++ killed by SIGSEGV +++
またunfinishedか。原因は man と同じだな。 glibc-2.2.5にするとバイナリ互換じゃなくなるのか? textutilsに含まれるコマンドを調べてみるとwcもSEGVになる。 他にもheadやtailは何も表示しない。 これもltraceしてみるとエラー表示しようとしてるんだけど、 たまたま"\0"だったという感じのようだ。
% cat --version cat (GNU textutils) 1.22
やけに古いな。ついでだからバージョンアップしとこう。 fileutilsよりシステムに依存する部分が少ないのでdiet libcを使う。
% tar xfvz textutils-2.0.tar.gz % cd textutils-2.0 % mkdir diet; cd diet % CC='diet gcc -nostdinc' ../configure --prefix=/usr --disable-nls % make <snip> ../../src/paste.c:57: storage size of `dummy_closed' isn't known ../../src/paste.c:61: storage size of `dummy_endlist' isn't known make[2]: *** [paste.o] Error 1
む?問題の個所は
static FILE dummy_closed; /* Element marking a file that has reached EOF and been closed. */ #define CLOSED (&dummy_closed) static FILE dummy_endlist; /* Element marking end of list of open files. */ #define ENDLIST (&dummy_endlist)
だ。diet libcのFILEは
typedef struct __stdio_file FILE;
で、struct __stdio_file自体は公開してない。 つまりFILE *でしか使えないようになっている。 paste.cでは単に他とは違うpointerという意味で使っているだけなので
#define CLOSED ((FILE *)-1) #define ENDLIST ((FILE *)-2)
でごまかすことにしよう。 これでリンク時にいろいろ文句言われるのを除いてmakeは通った。
make checkするとwcのところでどうも無限ループしてる雰囲気。
% VERBOSE=1 make check
するとwc -lのテストでループしてるようだ。実際に
% echo a | src/wc -l
をやらしてみると、確かに返ってこない。 ソースを見ると他との違いと言えばmemchrを使っているぐらいだ。 こんなもんがバグっているとも思えないしなあ。 確認の意味でlib/memchr.cを使うようにしたらちゃんと動く。 ということはdiet libcのmemchrがなんか変なのか?
diet libcのmemchrはi386/memchr.Sだ。 そう。Cじゃないのだよ、これが。 で、どうもmemchrの3番目の引数に0を渡したときがなんか変だということがわかったので、そのあたりを調べてみる。
memchr: pushl %edi movl 8(%esp),%edi movl 12(%esp),%eax movl 16(%esp),%ecx cld repne scasb je .Lfound xorl %edi, %edi incl %edi .Lfound: movl %edi, %eax decl %eax popl %edi ret
なるほど。実際1番目の引数-1が返ってきてるから.Lfoundへ行ってるようだ。 となると%ecxへ代入したときに0だったら、 何もしないで直に見つからなかった処理へ行けばいいわけだ。
memchr: pushl %edi movl 8(%esp),%edi movl 12(%esp),%eax movl 16(%esp),%ecx je .Lnot_found cld repne scasb je .Lfound .Lnot_found: xorl %edi, %edi incl %edi .Lfound: movl %edi, %eax decl %eax popl %edi ret
としてみた。これでいいようだ。
というかlib/memchr.cを使えばいいだけの話ではある。
ruby-devはどうなってるんだ?俺達にも情報をよこせみたいな意見がruby-talkで出てる。 というかはっきり言って今やruby-talkのほうがよっぽどruby-devだよ。 逆に週一でruby-devへ情報をくれるとありがたいくらい。
diet libc と来れば次は当然 uClibc だ。 RubyのためにはConfigのDO_C99_MATHをtrueにしておく(ldexp)。 ちなみにRuby with diet libcは非常に面倒なので途中でやめた。
ふつう対応するにはその環境固有のpredefineなもので#ifdefしたりするわけだけど、
% cmp =(gcc -E -dM -x c /dev/null) \ =(/usr/i386-linux-uclibc/bin/gcc -E -dM -x c /dev/null) %
と違いがない。まったくもって移植者泣かせなブツだ。 configure時にuClibcを使ってるかどうかを判断しないとだめだな。 とはいうものの、io.cのREAD_DATA_PENDING()だけ対応すればminirubyはokなので、 結構素性はいい。 random(3)はあるのにsetstate(3),initstate(3)はないというのもあるが、 とりあえず
#undef HAVE_RANDOM
しとく。で、肝心のREAD_DATA_PENDING()は<stdio.h>を見ると
#define READ_DATA_PENDING(fp) ((fp)->bufpos < (fp)->bufend)
でよさそう。
ext/socketはgai_strerror()がconflictする。これは後回し。
make testすると
echo: error while loading shared libraries: libdl.so.0: \ cannot open shared object file: No such file or directory
とメッセージが出る。./ruby sample/test.rbなら通る。なんか不思議だ。
あ、version.hが1.6.7になってる。
busybox のソースを見てたら__UCLIBC__を発見。 <feature.h>で定義しているようだ。 <feature.h>は<stdio.h>でincludeされていて、 <stdio.h>は"ruby.h"でincludeされているので、 結局Rubyでは__UCLIBC__で判断できることがわかった。 randomの件も__UCLIBC__が使える。
ext/socket/{addinfo.h,getaddrinfo.c}は
extern char *gai_strerror __P((int));
を
extern const char *gai_strerror __P((int));
にすればokだ。
まつもとさんがpreview1をcommitしたら、この変更を入れよう。
実体は-rc4そのものらしい。 というわけで、次は2.4.19-pre1か-ac1を試そうかな。
やけにでかいと思ったらjfsも含まれてる。
これは空白が区切りではなくなったことと関連してます。1.6は
#define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0')
で、1.7は
#define isdelim(c) ((c)=='\0')
となってます。つまり1.6では
% touch a b % ruby -e 'p Dir["a\nb"]' ["a", "b"]
と、"\0"じゃなくてもいいわけです。
更新。
出たようだ。が、明日を待つことにする。
[ruby-list:34112]から[ruby-list:34114]がまだ来ない。 もう24時間以上経ってるじゃん。rimよ、このままで大丈夫なのか?