今日は、端末の設定を変更するtcsetattr関数について学んだ。
この関数でstruct termiosの情報のうち、ISIGというシグナルに関する設定がありますが、このビットを落としたときの挙動について調べてみました。
仕様したサンプルソースは、下記になります。
sample.c
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
void tty_mode( int how );
void set_signal_mode( void );
void f( int signum);
int main(int argc, char *argv[])
{
int i;
tty_mode(0);
set_signal_mode();
signal( SIGINT, f );
while(1) {
printf("hello\n");
sleep(1);
}
tty_mode(1);
return 0;
}
void tty_mode( int how )
{
static struct termios original_mode;
if( how == 0 ) {
tcgetattr(0, &original_mode);
} else {
tcsetattr(0, TCSANOW, &original_mode);
}
}
void set_signal_mode( void )
{
struct termios info;
tcgetattr(0, &info);
info.c_lflag &= ~ISIG;
tcsetattr(0, TCSANOW, &info);
}
void f( int signum )
{
tty_mode(1);
exit(1);
}
このソースをコンパイルして、動かして同一ターミナルからCtrl + c しても動作は
継続しました。
別端末からSIGINTを送信してみた。(※実行バイナリはa.outとして作成してあります。)
kill -2 `pidof a.out`
この結果は、signalハンドラが呼ばれて処理が終了していました。
以上を踏まえて、ISIGは同一端末上からのシグナルに対する設定のようです。
ちなみに下記のようにSIG_IGNした場合は、他の端末から送信してもシグナルは無視されます。
signal( SIGINT, SIG_IGN );