longjmp () del manejador de señal

Estoy usando el siguiente código para intentar leer una entrada del usuario y el tiempo de espera y salir si pasan más de 5 segundos. Esto se logra a través de una combinación de setjmp / longjmp y la señal SIGALRM.

Aquí está el 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); 
}

Ahora, mi pregunta es si hay algo que pueda salir mal con esta función. He leído que llamar a longjmp () desde un controlador de señales puede tener un comportamiento indefinido, ¿a qué se refiere exactamente?

Además, ¿qué sucede si la alarma se activa justo después de que fgets () regrese, pero antes de que se active la alarma (0)? ¿Hará que la función devuelva -2 incluso si el usuario ingresó algo?

DESPUÉS DE EDITAR: No me interesan las formas de mejorar el código. Sólo quiero saber cómo podría fallar.

Respuestas a la pregunta(7)

Su respuesta a la pregunta