Cygwin の妙な端末仕様

Cygwin では、端末を open() したり process を fork() したりする度に端末設定項目の一つである ISIG というパラメータが有効になってしまうという妙ちくりんな仕様があります。

例えば /dev/tty を open() したあとその file descriptor に対して c_lflag &= ~ISIG して tcsetattr() しますよね。普通は次に tcsetattr() を明示的に実行するまで ISIG は無効のままの筈なんですが、Cygwin では違います。も一度 /dev/tty を open() してその file descriptor に対して tcgetattr() を実行すると何故か ISIG が有効になってます。「おや?」と思って先に open() した方の file descriptor も調べてみるとこっちまで ISIG が有効になってしまってます。

同様のことが fork() でも起こります。fork() した子供の方でだけ起こるというのならまだ理解出来なくもありませんが、親の方でも勝手に ISIG が有効にされてしまいます。なので、端末設定状態を保ちたければ、fork() の前後で tcgetattr()/tcsetattr() を実行して端末状態を保存しておく必要があります。面倒臭いったらありゃしません。

ISIG ってのは、Ctrl+C とか Ctrl+Z とかいった、signal を発生させるキー入力を許すか否かというパラメータで、これを無効にしておくことで Ctrl+C や Ctrl+Z をそのまんまのキー入力として処理することが出来ます。有効になってると process が終了したり停止したりして、キー入力としては受付けて貰えません。

Cygwin ではこの設定をことある毎に有効にすることで、Windows 環境の中でキー割込みを発生させることの困難さをユーザに知らしめようという意図があるのだと思われます。もしくは、少しでも気を許すと Windows API にキー入力が食われてしまって signal に至らないので、機会さえあれば API から制御を奪い取ろうと躍起になっているのかも知れません。

いや多分バグだと思うんだけどさ。何故かどこ調べても載ってないので誰も気付いてないのかしらん?