// sigdemo1.c - show how a signal handler works.
// - run this and press Ctrl-C a few times
// 在第一次等待答复时,按下 Ctrl-C 只会出现 ^C 字符。
// 之后再按
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
extern void f(int);
int main(void) {
signal(SIGINT, f);
for (int i = 0; i < 5; ++i) {
printf("blah blah blah\n");
sleep(1);
}
return EXIT_SUCCESS;
}
extern void f(int signum) {
printf("\tInterrupted! OK to quit (y/n)?");
int c = getchar();
if (c == EOF || c == 'y') {
exit(EXIT_SUCCESS);
}
fflush(stdin);
}
在第一次发送 SIGINT
之后,输入 n
并回车,第二次中断时却在输出 Interrupted! OK to quit (y/n)?
之后就不接受输入,直接继续输出 blah blah blah
, 第三次中断时才会接收输入。
怀疑 fflush(stdin)
没生效,求解。
之前的回答错了呜呜呜 QAQ
是这样子的,fflush(stdin) 在C标准里是行为未定义的,但是 glibc 说自己实现了这么个功能so。但是 glibc 2.20 骗人啦!它看看是不是存在未读取的数据,如果是,那么 lseek 回去!但很显然,连接到终端的 stdin 是不支持 lseek 的,所以就失败啦。glibc 只好忽略掉了。然后置位
_offset
字段为_IO_pos_BAD
加粗文字。不知道这个是干什么的,反正 getchar 不理它:
PS: 在信号处理器里使用不可重入函数,是可能出问题的。
PPS: 不知道为什么,我这里在按第二次 Ctrl-C 时程序就被杀掉了。因为C库调用 rt_sigaction 时设置了 SA_RESETHAND 标志。