longjmp () do manipulador de sinal
Eu estou usando o código a seguir para tentar ler uma entrada do usuário e tempo limite e sair se passar mais de 5 segundos. Isto é conseguido através de uma combinação de setjmp / longjmp e o sinal SIGALRM.
Aqui está o código:
#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);
}
Agora, minha pergunta é se há algo que possa dar errado com essa função. Eu li que chamando longjmp () de um manipulador de sinal pode ter um comportamento indefinido, o que exatamente é refferring?
Além disso, e se o alarme disparar logo após o fgets () retornar, mas antes que o alarme (0) seja chamado? Será que a função retornará -2 mesmo que o usuário tenha inserido algo?
Edição posterior: não estou interessado em maneiras de melhorar o código. Eu só quero saber como isso pode falhar.