〜2003年4月上旬〜
548通。とうとう500を越えた。
というのもOpenSSH 3.6がリリースされたからなんだけど。
% CFLAGS=-Os ./configure % make % sudo make install
更新。 パスに使える文字ってこのためだったのか。
-dオプションが無効だったのでその修正。
--- lib/refe/database.rb~ 2003-04-02 07:04:51.000000000 +0900 +++ lib/refe/database.rb 2003-04-03 01:28:10.000000000 +0900 @@ -23,3 +23,3 @@ def initialize( rootdir = nil, init = false ) - @rootdir = nil + @rootdir = rootdir @init = init
REFE_DATA_DIRのデフォルトが/usr/local/share/refeになってなかったので追加。
--- bin/refe~ 2003-04-02 08:56:00.000000000 +0900 +++ bin/refe 2003-04-03 01:28:59.000000000 +0900 @@ -121,2 +121,3 @@ +REFE_DATA_DIR = '/usr/local/share/refe'
あ、どうせなら、
REFE_DATA_DIR = File.join(File.dirname(File.dirname(__FILE__)), 'share', 'refe')
のほうがいいか。これでパッケージ作っとこう。
更新。 statという名前が使われているため、
common.c:851:47: macro "stat" passed 3 arguments, but takes just 2
というエラーになる。win32/win32.hでstatをdefineしてるから。実際は
bdb_test_error(dbp->stat(dbp, &bdb_stat, 0));
という感じで使われているんだけど、 考えてみるとstatという名前の変数はありがちだ。
とりあえず直前でundefしてお茶を濁す。
更新。
同じようなことを考えている人がいるなあ。でも
./configure --prefix=/foo make make PREFIX=/bar install
じゃ、$LOAD_PATHのprefixは/usr/localなので駄目なのだよ。 config.hができた時点で決まってしまうので。
DOSISH(Cygwinを含む)な環境ではRuby DLLやruby.exe相対になるから問題ないんだけど。 というより、すべての環境でそうなっていれば自由に移動できていいんだよね。 でも、一般的に自分自身がどこにあるのかはわからない。 argv[0]にはフルパスで入ってるわけでもないし、PATHから探し出すのもねえ。
posh is a stripped-down version of pdksh with several improvements that aims for compliance with Debian's /bin/sh policy, and few extra features. Currently, Debian's policy is to adhere to POSIX with the exception of supporting 'echo -n', so posh strives toward compliance with SUSv3 (with the exception of 'echo -n').
早速 diet libcで試すとget_current_dir_nameとcanonicalize_file_nameがundefinedになる。 Debianだしglibc固有の関数だろうか?info libcしてみると見つかった。 そのようだ。get_current_dir_nameはだいたいgetcwd(NULL, 0)と同じ。 違いは環境変数PWDを見ることぐらい。 canonicalize_file_name(x)はrealpath(x, NULL)と同じらしい。ということで、
#ifdef __dietlibc__ #define get_current_dir_name() getcwd(NULL, 0) #define canonicalize_file_name(x) realpath(x, NULL) #endif
を追加したらmakeは通った。でもmake checkするといっぱいFAILする。
Total failed: 159 (155 unexpected) Total passed: 2
2個だけかよ!直接verboseモードでテストスクリプトを動かしてみると
unexpected exit status 11 (signal 11), expected 0
と出てる。どうもSEGVってるようだ。でも手でその通りに入力するとちゃんと動くんだよねえ。困ったね。
例のtempfile.rbではなくtempfile(1)のほう。 poshのmake checkで呼ばれるがPlamoにはない。 調べてみると debianutilsにある。道理でないわけだよ。
diet libcはとりあえず置いといて、 uClibcで再挑戦。こっちにはget_current_dir_nameはあるのでsh.hは
#ifdef __dietlibc__ #define get_current_dir_name() getcwd(NULL, 0) #endif #if defined __dietlibc__ || defined __UCLIBC__ #define canonicalize_file_name(x) realpath(x, NULL) #endif
のように分割。make checkもかなり順調。
Total failed: 5 (1 unexpected) Total passed: 156
unexpectedは1個だけだ。-vつきで実行してみると、これもSEGVしてる。 実際はcd -P /で起きてる。これは手動でも再現した。あ、realpathの中だ。 ということはあのdefineじゃまずいわけだね。 uClibcのrealpathのソースを見ると2番目の引数にチェックなしてstrcpyしてる。 というわけで、
#if defined __dietlibc__ || defined __UCLIBC__ #include <sys/param.h> #define canonicalize_file_name(x) realpath(x, malloc(MAXPATHLEN)) #endif
に変更。これでmake checkも通った。
% sudo cp posh /bin/posh % sudo ln -sf /bin/posh /bin/sh
として、posh自身をconfigureし直してみよう。
checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes Memory fault configure: WARNING: `missing' script is too old or missing
いきなりなんか変だ。missingが動いてない。
% ./missing --run true zsh: segmentation fault ./missing --run true
これもSEGVか。というかshiftがSEGVだな。
% ./posh -c shift zsh: segmentation fault ./posh -c shift
uCLibcだからというわけでなく、glibcでも同じだ。 うーむ。こんな基本的なところにバグがあるのか?
% cd tests % grep shift *.t
とshiftのテストはない。 gdbで調べてみるとsrc/builtin.cのgetoptを呼んでいるところで起きてることがわかった。 shiftに対する引数の処理なんだけど、
while ((optc = getopt(argc, argv, NULL)) != -1) { switch (optc) { default: bi_errorf("shiftza"); } }
このNULLがかなり意味不明だ。そこにNULLを渡しちゃまずいでしょ、やっぱ。 NULLの変わりに""を渡せばいけそうだ。それにしてもshiftzaってなに?
CC='/usr/i386-linux-uclibc/usr/bin/gcc -static'で作り直して、 /bin/poshへコピー。configureも問題ないようだ。 ちゃんとbootするかどうかは明日の楽しみにとっておこう。
早速configureを実行してみると
checking build system type... config.guess: \ cannot create a temporary directory in /tmp
と謎のエラーに。まずいとしたらposhぐらいしかない。
% cd /bin % sudo ln -sf bash sh
してみたら通った。
% posh config/config.guess config.guess: cannot create a temporary directory in /tmp % ash config/config.guess config.guess: cannot create a temporary directory in /tmp
どうも、config.guessでは互換性のない機能を使ってるようだ。 というより
% mktemp -d -q /tmp/cgXXXXXX error: -d option is not supported on Linux
がいけないようだ。debianutilsにあるので、これを使おう。
% posh config/config.guess i586-pc-linux-gnu % ash config/config.guess i586-pc-linux-gnu
okだ。
昨日の件を抜き出して整形してみる。
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 exit 1 }
これは要するにmktempも$RANDOMも使えない環境ではconfig.guessは失敗することを意味する。 ということは先日アップデートされたRubyのconfig.guessでも全く同じわけで、 Ruby 1.8 preview3を出したほうがいいんじゃないかと思ってしまう。
bashやzshでは$RANDAMを参照するたびに乱数を生成する。
% echo $RANDOM,$RANDOM,$RANDOM 27074,15634,19319
poshやashにはそんな機能はない。
これを元にreadline 4.3対応をしてみよう。
1.8用のriが公開された。
うささんの協力でRubyのmswin32版でもreadline.soが使えるところまではできた。 これから、移植したライブラリを ここに集めようと思う。
サイズが2MBって、単にstripしてないだけのような。 たぶん500KB以内に収まる気がします。
kbhit()をやめてWaitForSingleObject()だけを使えば、 busy waitはなくなった。なんかとても変なループだったなあ。
次はカーソルキー対応だな。 ってunsigned charじゃ0x1f8は表現できないよ。解決。
うささんのVC++対応をマージ。
新手のvirusか?Fromがいまいちなので、騙されないと思うんだけど。