2017-12-16 24 views
1

私はtermiosで遊んでいました。私は、端末の設定を変更して終了すると、私の変更は持続し、自分の環境を壊してしまうことをすぐに理解しました。だから私はtcgetattrで初期設定を保存し、終了する前にそれらをリセットするために私のプログラムをセットアップしました。SIGINT/SIGTERMのtermios設定をリセットする必要がありますか?

しかし、プログラムが実行されている間にCtrl-Cを送信してSIGINTを送信すると、自分のプログラムがコードを実行していないので、端末が自分の変更した設定を保持すると予測しました。古い設定。

しかし、それは起こりませんでした。 UbuntuとmacOS Sierraの両方で、私の端末設定は、私がプログラムでそれらをリセットしたかのように元に戻った。

質問:これは私が一般的に期待できる何かの動作ですか?あるいは、シグナルハンドラを登録してSIGINT/SIGTERMを捕まえ、終了する前に端末設定を元に戻すのは意味がありますか?

コード

は、おそらくコードを見る必要はありません。この質問に答えるが、ここで私の例では、あなたが興味が場合:

#include <stdio.h> 
#include <string.h> 
#include <termios.h> 

int main() { 
     // put terminal into non-canonical mode 
     struct termios old; 
     struct termios new; 
     tcgetattr(0, &old); 
     new = old; 
     new.c_lflag &= ~(ICANON | ECHO); 
     tcsetattr(0, TCSANOW, &new); 

     // loop: get keypress and display (exit via 'x') 
     char key; 
     printf("Enter a key to see the ASCII value; press x to exit.\n"); 
     while (1) { 
       key = getchar(); 
       printf("%i\n", (int)key); 
       if (key == 'x') { break; } 
     } 

     // set terminal back to canonical 
     tcsetattr(0, TCSANOW, &old); 
     return 0; 
} 
+0

"//標準入力がファイル記述子0であると仮定" => 0が標準入力でない場合、実装はPOSIXに準拠していません。 – Stargateur

+1

私は周りを見て、私はちょうどあなたのシェルは属性自体をリセットすると思います。 – Stargateur

+0

私もそうだと思います。 –

答えて

1

私はその中を見て少し驚きました私のアーチLinuxのターミナル設定も "元に戻っていた"。しかし、実際には同じままです。あなたのコードを変更したとき、私はいくつかの異常を追跡することができました。

//... 
new.c_lflag &= ~(ICANON | ECHO); 
new.c_cc[VMIN] = 0; 
new.c_cc[VTIME] = 0; 
//... 

あなたがいずれかのボタンを押していないのであれば、ここでの出力は-1です。 Ctrl-Cにヒットし、元のプログラムを(同じ端末から)再コンパイルして起動すると、-1も印刷されるので、自動リセットはありません。

私はなぜECHOが「隠されている」のかわかりませんが、私は知りたいと思いますが、手動ですべての端末設定を元に戻すことをお勧めします。

+0

あなたが言及した振る舞いを再現することはできませんでしたが、どこにでも作成できる場合は、端末の設定をリセットするためにシグナルハンドラを登録することが正しいと思います。最悪のシナリオは少し余分な仕事をすることです。 –

関連する問題