wiki:LinuxControllingTTY

Linux:制御端末

もしかして常識でしたか?「/dev/console」が制御端末に成れないことを。

Unixで仕事するようになって2 decadeほど経つというのに、こんなことで数時間悩んでしまいました。悲しい。

制御端末というのは、Unix系OSで、各プロセスが^Cとか^Zによる制御を受ける端末(文字端末)のことです。 言い方を変えると、ある端末で^C^Zを押したとき、それぞれSIGINTRやSIGTSTPシグナルが、その端末を制御端末としている複数のプロセスに送られます。 制御端末の話題とからんで、必ずプロセスグループとかセッションどうのこうのという話題がつきまといますが、ここでは割愛します。 自分もマニュアルを読みながらじゃないと説明できないから。

本題ですが、Linuxカーネル(ドライバ)のソースを読んでみたところ、以下の端末デバイスは制御端末に成れないのです。 興味がある人は、ソース、drivers/char/tty_io.ctty_open()を見てみてください。

  • /dev/console -- カーネルの起動時の端末。システム関連のメッセージを表示するのにも使う。
  • /dev/tty0 -- tty1~の「Linux Virtual Terminal」のうち、現在表示している物を示す。
  • /dev/tty -- 現在使っている端末を示す。
  • PTYのマスター側

ttytty0は仮想的な物であり、物理的なデバイスは、アクセスしたプロセスやアクセスしたタイミングによって異なります。 だから、制御端末になれないようにするのは、当然ともいえます。 PTYのマスター側も、この上で動くプロセスは無いはずだから、考えてみればあたりまえ。 で、consoleですが、どういう理由なんでしょうね。確かに「仮想的」と言えばそのとおりですが、誰がいつアクセスしても同じ物理デバイスがアクセスされるわけなので、制御端末に成れてもいいような気がします。 これは想像ですが、マシンルームなどに設置された「コンソール」からいたずらができないようにしているのではないかと思います。 システムの起動処理中(rcが動いている最中)に^Cで止められたらたまった物ではありません。 あるいは、起動後であっても、コンソールで^Cを押したことが、いずれかのプロセスに影響してしまったら困ります。 だから、/dev/consoleは制御端末に成れないようにしてあるのではないかと思います。

そういえば、僕が大学生のとき、大学の「端末室」に一台だけ設置してあった「 Sony NEWS」は、起動処理中に^Cを押すとシングルユーザモードのシェルプロンプトが現れました。 勝手にユーザIDを登録して遊んでいました。今はそういうことができないようになったってことでしょうか。

以上はLinuxのソースで調べたのですが、正統派のUnixではどうなのでしょうね。

なぜこんなことにぶつかったのかといえば、 BusyBoxです。 最近、とある仕事でLinuxを組み立てているのですが、これまでBusyBox 1.2.1だったのを1.6.1に変更したら、シェルでのジョブ制御ができなくなりました。曰く「can't access tty; job control turned off」。 調べていくと、ttyコマンドの結果が1.2.1の時には「/dev/ttyS0」だったのに、1.6.1では「/dev/console」に変わってます。 この原因は、!BusyBoxのソースの「init/init.c」のconsole_init()関数です。 1.2.1では、コンソールとして使っている(本当の)デバイスを探す処理が入っていたのですが、1.6.1では無くなっています。 1.2.1でうまくいっていたのは、こういう「怪しい」ことをやっていたからなのです。 では、1.6.1ではわざわざ低機能化させたのかといえば、そんなことはありません。 この機能は別のコマンド「/usr/bin/cttyhack」に移っています。 これまで「/bin/sh」としてシェルを起動していた部分を、「/usr/bin/cttyhack /bin/sh」に変えれば、元通りジョブ制御ができるようになります。

(2007/8/13 - sgk) `