C SIGQUIT和STDIN(读取函数的意外转储)

C SIGQUIT和STDIN(读取函数的意外转储),c,signals,C,Signals,我遇到了stdin和sigquit信号处理的问题。任务是忽略sigquit信号。一切都很好,除了所有的“读取”缓冲区都消失了,我不知道如何避免它。这是我的密码: #include <unistd.h> #include <signal.h> #include <sys/types.h> #include <strings.h> int main(void) { char buffer[4096]; int byte; b

我遇到了stdin和sigquit信号处理的问题。任务是忽略sigquit信号。一切都很好,除了所有的“读取”缓冲区都消失了,我不知道如何避免它。这是我的密码:

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <strings.h>

int main(void)
{
    char buffer[4096];
    int byte;

    bzero(buffer, 4096);
    signal(SIGQUIT, SIG_IGN);
    while ((byte = read(0, &buffer, 4096)))
    {
        if (strlen(buffer) == 5 && !strncmp(buffer, "exit", 4))
            break ;
        write(1, "STDOUT | ", strlen("STDOUT | "));
        write(1, buffer, strlen(buffer));
        bzero(buffer, 4096);
    }
    write(1, "Program is finished\n", strlen("Program is finished\n"));
    return (0);
}
OS:MacOS Mojave-10.14.6
Clang verison:11.0.1

这不是代码中的错误。您已经正确地忽略了SIGQUIT,并且读写循环基本上没有问题(我看到的唯一实际错误是,您将
read
的返回值赋给了错误类型的变量,然后没有对它给予足够的重视;但这不是您当前问题的原因)

当您键入^\时,tty驱动程序将生成一个SIGQUIT,并丢弃任何挂起的输入行。此行为由POSIX指定,但仅通过暗示来指定:
NOFLSH
local mode标志的定义如下

如果设置了NOFLSH,则不能正常刷新与INTR、QUIT和SUSP字符相关的输入和输出队列

(开放式集团基础规范第7期,2018年版,§。)

因此,如果未设置NOFLSH(默认设置),则在处理^C、^和^Z时,输入和输出队列都将被刷新(内容被丢弃)


您可以使用
tcsetattr
设置NOFLSH标志,但必须注意在退出时再次将其取消设置。我建议您使用or库,而不是试图自己解决低级tty API。

当您点击
^C
(intr)、
^Z
(susp)和
^
(quit)时,tty层正在刷新您的输入

解决方案是在运行程序之前调用
stty noflsh


如果您需要以编程方式执行此操作,请参阅此

中的
NOFLSH
标志。请让
bzero
已经死亡-使用
memset
,它更可能是编译器的固有特性。完成了此操作,但仍然没有任何更改当然它不是解决方案。@zwol它将在“^\”之前丢弃所有内容,例如,
some_text^\other text->STDOUT|other text
Aheh,我完全错过了NOFLSH。尽管如此,你的答案很有价值(+1),不要删除它这对我来说完全有效!谢谢大家=)嗯,我在Linux上没有这样做。。。奇怪-编辑必须是PEBKAC。可以生产。
$ ./test
hello world
STDOUT | hello world
hello world^\
STDOUT |
The way it should be
STDOUT | The way it should be
And how it is now^\
STDOUT |
i need help
STDOUT | i need help
really^\
STDOUT |
exit
Program is finished