Linuxシステムコールの勉強(その10)

Linuxシステムコール

Linuxシステムコール

前回はこちら


今回は、端末のモード(Cooked,RAW)について説明します。まずはそれぞれの特徴をまとめます。

モード 特徴
COOKEDモード (1) 入力データのバッファリング

 標準入力から入力されたデータはEnterの押下、eof文字の入力があるまでバッファリングされる

(2) 行単位の編集サービス

 バッファリングされているデータはerase文字やkill文字などを使用して編集する事が出来る
  erase文字=ctrl+h
  kill文字 =ctrl+u
  eof文字 =ctrl+d
RAWモード COOKEDモードで実施しているサービスを全くしないモード


ひとことでまとめると、キーボードの入力をそのまま標準入力としてプログラムへ引き渡すのがRAWモード。行単位でバッファに管理して編集・引渡しを行うのがCOOKEDモードです。


通常ログインした際に使用するシェルは全てCOOKEDモードで動作しています。これをRAWモードに一時的に切り替えるプログラムを作ってみます。
# RAWモードにするにはtermio構造体のc_lflagメンバーのICANONフラグを0に設定変更する必要があります。

ICANONフラグの値 入力モード
1 COOKEDモード(初期値)
0 RAWモード
      1 #include <sys/ioctl.h>
      2 #include <stdio.h>
      3 #include <asm/termbits.h>
      4
      5 int main()
      6 {
      7         char c;
      8         struct termio tm, tm_save;
      9         int  fd_stdin;
     10
     11         fd_stdin = fileno(stdin);
     12
     13         /* 現在の設定を格納 */
     14         ioctl(fd_stdin, TCGETA, &tm);
     15         tm_save = tm;
     16
     17         /* 端末に設定を反映 */
     18         tm.c_lflag &= ~ICANON;
     19         ioctl(fd_stdin, TCSETAF, &tm);
     20
     21         printf("1文字入力してください?");
     22         fflush(stdout);
     23         read(fd_stdin, &c, 1);
     24         printf("\n入力文字 = %c\n", c);
     25
     26         /* 設定を元に戻す */
     27         ioctl(fd_stdin, TCSETAF, &tm_save);
     28
     29         return 0;
     30 }


前回同様、asm/termbits.hをincludeしないとICANONが見つからないとエラーになりました。うむむ。


ポイントは2点。

1つめはICANONのxorとandを取る事でICANONビットだけを変更して設定する方法(前回と同じ)。
2つめは22行目にあるfflush()を使っているところです。これが無いとprintf()を実行しても画面には何も表示されません。何で表示しないのかというとprintf()は内部で独自にバッファリングをしているからだそうです。そんなわけでバッファ内のデータを強制的に出力するには該当のファイルポインタを引数にしてfflush()を実行してください。


ちなみに実行結果はこちら。

[itotto@itotto ]$ gcc -o shift_rawmode shift_rawmode.c

[itotto@itotto ]$ ./shift_rawmode
1文字入力してください?8
入力文字 = 8

[itotto@itotto ]$


上記のとおり、8と入力した瞬間に入力が完了されてしまいます。Enterを押したり、eof文字が入力されなくてもデータが引き渡されている事から端末はRAWモードで動作していることが分かります。


次回は端末属性VMINとVTIMEについてのまとめと、ここまでに出てきた以外の端末属性の変更についてまとめます。


次へ進む