【发布时间】:2009-11-11 14:13:58
【问题描述】:
我正在使用以下代码尝试从用户读取输入并超时并在超过 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?
稍后编辑: 我对改进代码的方法不感兴趣。我只是想知道它是如何失败的。
【问题讨论】:
-
ret没有初始化,所以调用fgets会导致内存损坏。 -
@outis:
ret被分配了fgets()函数调用的结果。 -
fgets() 在成功的情况下返回第一个参数,在任何错误的情况下返回 NULL。我看不出这会如何导致任何内存损坏。内容保存在s中。
-
没关系 - 快速浏览。误读“fgets(s, ...)”。