プロが教える店舗&オフィスのセキュリティ対策術

こんにちわ,
今Cの学習をしています。
alarmの使用法なんですが,1度SIGALRMを捕らえて,シグナルハンドラの関数に飛んだ後,LONGJMPでもどってくると,2回目以降,alarmは使用できないのでしょうか。具体的には下記のとおりです。

jmp_buf fin;

main(){
int i,
x =0;
for(i=1;i<=5;i++){
signal(SIGALRM, timeout);
x=setjmp(fin);
if(x=1){
   alarm(5);
/*何かを入力等を行う*/
   alarm(0); 
}
else
{
x=0;
}
}
}

void timeout()
{
longjmp(fin,1);
return;
}

このように何か入力まちをしていて入力されずに5秒まつと再度入力をするようなプログラムを5回,回したいのですが,うまくいきません。

よろしくおねがいします。

A 回答 (2件)

#1です。


ちょっと訂正します。

#1の回答で、2回目以降もプロセスが終了することはなくなるはずですが、今度は5回でも100回でもforループを抜けないはずです。

というか、正確に言うと、ループしてないんですよ。
longjmp()でsetjmp()のところに舞い戻ってくるんですから、何回繰り返してもループ1回目なんですよね。

/*何か入力等をおこなう*/
という部分がSIGALRMの発生によってブロック解除されるものであれば(大抵の入力待ち関数はerrno=EINTRでエラー終了するものです)、
単純にsetjmp()とlongjmp()を削除してみてください。

こんどこそ、お望みの動作になるはずです。

参考まで。
    • good
    • 0

ループ2回目でプロセスが死んでしまう、という状況ですよね?



SIGALRMは発生すると、デフォルトに戻ります。
(SIGALRMのデフォルト動作はプロセス終了です。)

言い換えると、
ループ一回目は、signal(SIGALRM, timeout)が効いていますが、
ループ二回目は、signal(SIGALRM, SIG_DFL)状態
ということです。

signal(SIGALRM, timeout);
x=setjmp(fin);

x=setjmp(fin);
signal(SIGALRM, timeout);
とすると、お望みの動作になりますよ。

参考まで。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!