klic on CYGWIN (Configure)
|
現状では、KLIC-3.003 KLIC-3.003-extio がとりあえず、インストール可能。
Configure のオプションも特に指定は必要ない。
KLIC-3.003-extio-shared 版は -fPIC という gcc のオプションが
エラーを吐くので、まぁ実行ファイルが大きくなるくらいとりあえず、
我慢してみる。
make で signal 11 でこけてしまう人は、gcc のバージョンが 3.x かも。
3.x 系は、-fomit-frame-pointer とかのオプションに誤動作があるらしい。
よって gcc 2.95系にするとうまく行く。
自分の cygwin は gcc-2 というのが gcc 2.95 だったので
Configure で gcc を gcc-2 にすると makeが成功した。
普通に Makefile を無改造ではさすがに無理なので、
少し書き換える。
単純に、cygwinでは実行ファイルが .exe
になるので、それを正すだけ。
kl1cmp klic klicdb
を .exe にしている。
klic-3.003-cygwin-Makefile.tar
サンプルのMakefile、これをConfigureのある
ディレクトリーで解凍すれば行くはず。
以上をふまえるととりあえずインストールできる。
setlinebuf
lockf
ulimit
isastream
が無いといわれるがとりあえず無視。
|
klic on CYGWIN (動作確認)
|
fork,pipeなどの問題はなかったが、肝心なソケットが使用できない。
根本的な問題として cygwin では、fcntl というシステムコールの
F_SETOWN というマクロ?がうまく動かないらしい。
また現在のcygwinでは、ソケットの状態変化とシグナルの発生に問題があるらしい。
KLICはそれを使っているため、大幅な改造をしないとちょっと
ソケットだけ正常には動作しないと思われる。
|
ソケットでの誤動作(一人言)
|
普通に組み込みのソケットを使用しようとすると、
多分、bindしてacceptする時にいきなり、
accept: Resource temporarily unavailable
といって落ちる。
理由はわからないが、この時点で
linux と cygwin で動作が違っている。
動作と行っても内部の話で、これをトレースすると
linuxでは、システムコールのacceptはソケットが使用可能になってから
なされるのに対して、
cygwinでは、それをまたないでacceptしているのが怪しい。
またないという現象を詳しくいうと、
bound_sock/4が中断しないのが原因。
正常動作する時の bound_sock/4の実行条件は、第3引数が具体化する時。
なぜ中断しないのかは不明。
中断前までのトレースの結果は全く同じで、その引数の具体化状態も
全く一緒にもかかわらず、linuxでは中断、cygwinでは実行。
この振舞はそれ自体がとても怪しい。
これは、ソケットだけでなく他の部分でも影響しそう。
そこで、bound_sock/4を中断するようにする。
実際には、
bound_sock([accept(R)|S],FD,Async,Async1)
を
bound_sock([accept(R)|S],FD,[X|Async],Async1)
にする。
こうしても、linux上で問題なく動作したのでとりあえずこれは解決する。
これで、
accept: Resource temporarily unavailable
は出なくなるが、単にその後動かなくなる。
connect側でもbind側でも原因はおそらく一緒で、
両方とも、Asyncという変数の具体化を常に待っていて、
その変数が具体化しないのが原因。
このAsyncが具体化するのはソケットがSIGIOを発生する時。
そのシグナルハンドラーは asyncio.c に書いてる。
ソケットがSIGIOを発生するようにしているのが、
gunix.kl1 setasync()
ここで、fcntl()が使われていて。
これがとりあえずうまく動いていないらしい。
static void setasync(sock, msg)
int sock;
char *msg;
{
#ifdef ASYNCIO
if (fcntl(sock, F_SETOWN, getpid()) < -1) {
fatalp(\"fcntl\", \"Setting error for %%s\", msg);
}
#ifdef FASYNC
if (fcntl(sock, F_SETFL, FASYNC|O_NONBLOCK) < -1) {
fatalp(\"fcntl\", \"Setting error for %%s\", msg);
}
#else
if (fcntl(sock, F_SETFL, O_NONBLOCK) < -1) {
fatalp(\"fcntl\", \"Setting error for %%s\", msg);
}
if (ioctl(sock, I_SETSIG, S_INPUT|S_OUTPUT) != 0) {
fatalp(\"ioctl\", \"Setting error for %%s\", msg);
}
#endif
#endif
}
そこで、さらにこの関数を
static void setasync(sock, msg)
int sock;
char *msg;
{
int enable = 1;
if (fcntl(sock, F_SETFL, FASYNC|O_NONBLOCK ) < -1){
fatalp(\"fcntl\", \"Setting error for %%s\", msg);
}
ioctl(sock, FIOASYNC, &enable);
}
と改造すると、SIGIOを発生するようになるが今度は、
asyncio.c sigio_handler() の中の
select()がエラーを吐いてしまう。
エラー
EBADF:集合のどれかに無効なファイル・ディスクリプタが与えられた。
selectがエラーを返す原因が判明。
selectの第一引数にフィルディスクリプタの最大数を与えるのだが、
その数が大きすぎるということが判明。
klic は その値に fd_setsize を使っていて
その fd_setsize は cygwin 上では getdtablesize()
で与えらられる。
getdtablesize は OPEN_MAX という値が入り、それが 256 である。
fd_setsize は cygwinの場合 256
これを、 64 にするとselectが正常動作することが判明。
つまり、エラーの原因は使用できないファイルディスクリプタの数を
selectの引数にしていたからであろうと思われる。
やはりソケット周りは、cygwin自体にもバグがあるらしい
そのせいでKLICの非同期I/Oがうまく作動しない。
ソケットを使っていて、ソケットが強制的に一方から
閉じられたさいにUNIXシグナル SIGIO が発生しないらしい、
他にもソケットとSIGIOとの動作があまり完璧でないのかも。
ということをふまえて
非同期I/Oは無しでなら動くようには改造できた。
がしかし、DKLICシステムは動かない。
***************
とりあえず結論
***************
現状では非同期I/Oなしのソケット装備のKLICで我慢する。
現状のcygwinのバグに対応した大幅なKLIC改造は無意味なのでしない。
(しなくていいことにする?)
cygwin開発者の人達頑張って。
(俺がやるのか...)
以上。
上記の一人言について
間違ってたらごめんなさい。
御意見、御感想は
kaneki@ueda.info.waseda.ac.jp
まで。
|