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
まで。