C SIGQUIT和STDIN(读取函数的意外转储)
我遇到了stdin和sigquit信号处理的问题。任务是忽略sigquit信号。一切都很好,除了所有的“读取”缓冲区都消失了,我不知道如何避免它。这是我的密码: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
#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