次のコードを使用して、ユーザーからの入力を読み取ろうとし、5 秒以上経過するとタイムアウトして終了します。これは、setjmp/longjmp と SIGALRM シグナルの組み合わせによって実現されます。
コードは次のとおりです。
#include <stdio.h>
#include <setjmp.h>
#include <unistd.h>
#include <string.h>
#include <sys/signal.h>
jmp_buf buffer;
// this will cause t_gets() to return -2
void timeout() {
longjmp(buffer, 1);
}
int t_gets(char* s, int t)
{
char* ret;
signal(SIGALRM, timeout);
if (setjmp(buffer) != 0)
return -2; // <--- timeout() will jump here
alarm(t);
// if fgets() does not return in t seconds, SIGALARM handler timeout()
// will be called, causing t_gets() to return -2
ret = fgets(s, 100, stdin);
alarm(0);
if (ret == NULL ) return -1;
return strlen(s);
}
int main()
{
char s[100];
int z=t_gets(s, 5);
printf("%d\n", z);
}
さて、私の質問は、この関数で問題が発生する可能性があるかどうかです。シグナルハンドラから longjmp() を呼び出すと、未定義の動作が発生する可能性があることを読みましたが、正確には何を参照していますか?
また、fgets() が返された直後で、alarm(0) が呼び出される前にアラームがトリガーされた場合はどうなるでしょうか? ユーザーが何かを入力した場合でも、関数は -2 を返しますか?
LATER EDIT:コードを改善する方法には興味がありません。どのように失敗するのか知りたいだけです。