`fflush(stdin)` 失败
// 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
加粗文字。
c
int
_IO_new_file_sync (fp)
_IO_FILE *fp;
{
_IO_ssize_t delta;
int retval = 0;
/* char* ptr = cur_ptr(); */
if (fp->_IO_write_ptr > fp->_IO_write_base)
if (_IO_do_flush(fp)) return EOF;
delta = fp->_IO_read_ptr - fp->_IO_read_end;
if (delta != 0)
{
#ifdef TODO
if (_IO_in_backup (fp))
delta -= eGptr () - Gbase ();
#endif
_IO_off64_t new_pos = _IO_SYSSEEK (fp, delta, 1);
if (new_pos != (_IO_off64_t) EOF)
fp->_IO_read_end = fp->_IO_read_ptr;
#ifdef ESPIPE
else if (errno == ESPIPE)
; /* Ignore error from unseekable devices. */
#endif
else
retval = EOF;
}
if (retval != EOF)
fp->_offset = _IO_pos_BAD;
/* FIXME: Cleanup - can this be shared? */
/* setg(base(), ptr, ptr); */
return retval;
}
不知道这个是干什么的,反正 getchar 不理它:
c
int
getchar (void)
{
int result;
_IO_acquire_lock (_IO_stdin);
result = _IO_getc_unlocked (_IO_stdin);
_IO_release_lock (_IO_stdin);
return result;
}
c
#define _IO_getc_unlocked(_fp) \
(_IO_BE ((_fp)->_IO_read_ptr >= (_fp)->_IO_read_end, 0) \
? __uflow (_fp) : *(unsigned char *) (_fp)->_IO_read_ptr++)
PS: 在信号处理器里使用不可重入函数,是可能出问题的。
PPS: 不知道为什么,我这里在按第二次 Ctrl-C 时程序就被杀掉了。因为C库调用 rt_sigaction 时设置了 SA_RESETHAND 标志。
以上是 `fflush(stdin)` 失败 的全部内容, 来源链接: utcz.com/p/195430.html