川口です

FreeBSD + kterm において stty の設定が
起動のさせかたによっておかしくなる(?)点があるという指摘がありました.
FreeBSD の terminal 周りの問題ではないか,という
話もあるのですが,私ではよく分からないため,
識者のご意見を伺いたいとおもっています.

具体的問題点:
  * kterm にて stty の min の値が通常 1 のところが0 にて起動されることがある
   => アプリケーションによっては polling が無限ループ的な動作になる
      即ち,CPU を 100% 使ってしまうということがある
     (そのせいで ports/japanese/ng が特定の状況で "暴走" するようです)

# 後ろに(ご本人に許可を頂きましたので)
# 富田さんによって調べて頂いた内容のメールをつけます.

要点だけ記します:

  * FreeBSD にて ssh 経由で kterm を起動すると stty が min = 0 で起動されてしまう
  * (min = 0 なところから起動した kterm も min = 0 を引き継ぐ)
  * min = 0 では特定の tty なアプリケーションが暴走する
  * rxvt などは ssh 経由でも min = 0 にはならないらしい
  * Linux 等では ssh 経由でも当該現象は起きない

さて,ng 自体にて本現象を回避することは出来る(*)ようなのですが
そもそも,この "FreeBSD における kterm/xterm の挙動" は
おかしいのでしょうか? おかしいなら何がいけないのでしょう?

何が "本当の悪原因" なのか,また,直すべきなら何を直すべきなのでしょう?

(私ではその辺り(stty とか)の判断がそもそもよく分からないので)

よろしくお願い致します.

        --      --      --      --      --      --      --      --

(*) ng のバージョンによってはそもそも問題は起きない

◆ 参考1: 富田さんによる PR
> PR title:     kterm, stty -a shows min = 0. this should be min = 1
>               http://www.FreeBSD.org/cgi/query-pr.cgi?pr=92184
(時間が経ってしまっているのは私の方で対応をすっかり忘れていたことによります)


◆ 参考2: 
japanese/ng,ng-devel 関連では本件の影響(stty min 0 な状況での問題)は:
      - ng 1.4.4(ng) は暴走 
      - ng 1.5b1(ng-devel) は普通
という感じです.


◆ 参考3: TOMITA Yoshinori さんからのメール:
> なお、stty minの値の意味ですが、non-blocking readするときに、minで指定し
> た値の文字数だけ読み込んだらreadが完了する、というものです。
> くわしくはtermios(4)のNoncanonical Mode Input Processingに説明されています。
> 
> 普通、標準入力からデータを読み込むプログラムを実行すると、Enterキーを押
> すまで、read()やfread()が帰ってきませんが、ngのようなフルスクリーンエ
> ディタの場合、そんな動作をされたらエディタとして使い物になりませんから
> (Enterキーを押すまで入力した文字が見えない・・・)、端末の設定を変更し
> て、押したキーの値を瞬時に読み出せるモード(non-canonical mode)にします。
> min=0の場合は、キーを押してなくても、read()は、読み出したデータ量=0とい
> うことですぐに帰ってきます。そのため、いわゆるbusy loop状態が発生して、
> キーを読み出すだけの処理が全速力で実行されて、CPUタイムを消費します。
> min=1ならば、少なくとも、キーを1つ押すまでは、read()が帰ってこないので、
> busy loopにはなりません。
> 
> 個人的な見解ですが、これはktermの問題であって、ngの問題ではないと思いま
> す。xtermではやっている処理をktermはやっていないためです。VMINパラメータ
> を初期化せずにnon-canonical modeにするngは、おかしいことはおかしいのです
> が、japanese/ngはかなり古いプログラムですし、japanese/ng-develでは修正さ
> れているようなので、ま、いいかな?と・・・(japanese/ngのほうは、どこを
> 直していいのかさえ、わかりませんでした)。
> 
> 私は、かなり昔からFreeBSDとngを使っていたのですが、ngがCPUを100%消費する
> この問題に気がついたのは、ごく最近のことです。 FreeBSDの、ターミナル関係
> のライブラリが変更されたか、ssh(後述)の挙動が変更されたかのために、こ
> の挙動がおきるようになったのかな?と予想はしているのですが、きっかけが何
> だったのかは、いまだわかりません。
> 
> 
> 
> さて、min=0になる問題ですが、今、正しい再現方法がわかりました。
> PR用に、英語にしておきます。
> 
> 
> kterm and xterm will inherit the current terminal setting where k(x)term
> invoked.
> 
> % stty min 123
> % kterm &
> (in newly opened kterm window)
> % stty -a
> speed 9600 baud; 30 rows; 80 columns;
> lflags: icanon isig iexten echo echoe echok echoke -echonl echoctl
> -echoprt -altwerase -noflsh -tostop -flusho pendin -nokerninfo
> -extproc
> iflags: -istrip icrnl -inlcr -igncr ixon -ixoff ixany imaxbel -ignbrk
> brkint -inpck -ignpar -parmrk
> oflags: opost onlcr -ocrnl -oxtabs -onocr -onlret
> cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -dsrflow
> -dtrflow -mdmbuf
> cchars: discard = ^O; dsusp = ^Y; eof = ^D; eol = <undef>;
> eol2 = <undef>; erase = ^H; erase2 = ^H; intr = ^?; kill = ^U;
> lnext = ^V; min = 123; quit = ^\; reprint = ^R; start = ^Q;
> status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W;
> 
> So, if the current terminal is MIN=0, any new kterm window will be MIN=0.
> 
> Where the first kterm got MIN=0 ?
> The key was "ssh".
> You can reproduce like this.
> 
> % ssh SOMEHOST kterm -display MYHOST:0
> 
> In this case, ssh will not allocate pseudo-tty. kterm cannot inherit
> terminal setting and it results in MIN=0.
> By the way, you can forcibly allocate ptty with "ssh -t"
> 
> % ssh -t SOMEHOST kterm -display MYHOST:0
> 
> will be MIN=1
> 
> xterm works fine because in main.c you will see
> 
> d_tio.c_cc[VMIN] = 1;
> 
> this initialize the parameter MIN=1.
> 
> I think this is a bugf of kterm and a FreeBSD-local patch againt
> japanese/ng is not good idea.
> I confirmed this patch for kterm works fine for me. This is very short
> patch than one attached in PR.
> 
> *** main.c Wed Apr 19 11:15:39 2006
> --- /tmp/main.c Wed Apr 19 11:15:28 2006
> ***************
> *** 1405,1410 ****
> --- 1405,1411 ----
> d_tio.c_cc[VQUIT] = CQUIT; /* '^\' */
> d_tio.c_cc[VEOF] = CEOF; /* '^D' */
> d_tio.c_cc[VEOL] = CEOL; /* '^@' */
> + d_tio.c_cc[VMIN] = 1;
> #ifdef VSWTCH
> d_tio.c_cc[VSWTCH] = CSWTCH; /* usually '^Z' */
> #endif
> 
> 
> 
> I checked on debian Linux's kterm but could not found MIN=0 problem. I
> also looked into debian kterm source code but could not found any
> treatment for MIN=0 problem. I guess there is some differences in
> terminal emulation library or terminfo database(?) between FreeBSD and
> debian.

TOMITA Yoshinori <[EMAIL PROTECTED]> wrote:
> debianなLinuxのktermでは、min=0になることはないのですが、端末の設定が新
> しく開くktermへは引き継がれない、という副作用が発生しています(それは、
> たいした問題ではない気もします)。
> 
> 
> I investigated the mystery why debian linux's kterm works OK and
> FreeBSD's does not.
> 
> In main.c, there is a defined(linux) block,
> 
> /*
> * set up the tty modes
> */
> {
> #if defined(USE_SYSV_TERMIO) || defined(USE_POSIX_TERMIOS)
> #if defined(umips) || defined(CRAY) || defined(linux)
> /* If the control tty had its modes screwed around with,
> eg. by lineedit in the shell, or emacs, etc. then tio
> will have bad values. Let's just get termio from the
> new tty and tailor it. */
> if (ioctl (tty, TCGETA, &tio) == -1)
> SysError (ERROR_TIOCGETP);
> tio.c_lflag |= ECHOE;
> #endif /* umips */
> 
> On linux systems, a variable tio is initialized here and tio.c_cc[VMIN]
> becomes 1 (default value?).
> Original terminal settings seem to be always overwritten here, and not
> inherited.
> ... something strange ...

-- 
       ∧∧
Zzz.. (- - )⌒⌒⊇〜           川口 銀河
      ##############   [EMAIL PROTECTED]

メールによる返信