Я использую следующий код, чтобы попытаться прочитать ввод от пользователя и тайм-аут и выйти, если прошло более 5 секунд. Это достигается с помощью комбинации setjmp/longjmp и сигнала SIGALRM.longjmp() от обработчика сигнала
Вот код:
#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(), но до вызова тревоги (0)? Будет ли это заставлять функцию возвращать -2, даже если пользователь что-то вводил?
LATER EDIT: Меня не интересуют способы улучшения кода. Я просто хочу знать, как это может потерпеть неудачу.
'ret' не инициализирован, поэтому вызов' fgets' приведет к повреждению памяти. – outis
@outis: 'ret' присваивается результат вызова функции' fgets() '. – pmg
fgets() возвращает первый параметр в случае succes или NULL в случае какой-либо ошибки. Я не вижу, как это может привести к повреждению памяти. Содержимое сохраняется в s. – sttwister