gpt4 book ai didi

c - 捕获信号时使 open() 返回

转载 作者:行者123 更新时间:2023-12-04 14:47:59 24 4
gpt4 key购买 nike

当我打电话时open("./fifo",O_RDONLY) ,系统调用将阻塞,因为没有人在写入 fifo ./fifo .如果在此期间接收到没有信号处理程序的信号,则该过程立即结束。到现在为止还挺好。
但是,当接收到具有信号处理程序的信号时,将执行信号处理程序并且 open()系统调用仍然阻塞。
我该如何制作 open()当我捕捉到信号时返回?
我试图阻止信号,这不起作用,因为没有 sigmask open() 的论据就像 pselect() .使用 O_NONBLOCK也不起作用,因为那时 open()将返回错误,无论是否有信号。删除信号处理程序也没有好处,因为我希望能够对信号使用react。
我的测试代码:

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

static volatile bool end=0;

static void catchSignal(int signal)
{
(void)signal;
const char *s="Catched Signal\n";
write(STDERR_FILENO,s,strlen(s));
end=1;
}

static int openFile(void)
{
int fd=open("./in",O_RDONLY);
if(fd<0)
{
perror("can't open file");
exit(1);
}
return fd;
}


int main()
{
if(SIG_ERR==signal(SIGTERM,catchSignal))
{
perror("cant set up signal handler");
return -1;
}
int fd = openFile();
while(end==0)
{
puts("Still running");
usleep(300UL*1000);
}
puts("End now");
if(fd>0)
{
close(fd);
}
return 0;
}

最佳答案

signal()由于具有不同细节的实现历史,函数是有问题的。根据its Linux manual page :

The only portable use of signal() is to set a signal's disposition to SIG_DFL or SIG_IGN. The semantics when using signal() to establish a signal handler vary across systems (and POSIX.1 explicitly permits this variation); do not use it for this purpose.


(重点在原文)
而不是 signal() ,你应该使用 sigaction() :
  struct sigaction sa = { .sa_handler = catchSignal };

if (SIG_ERR == sigaction(SIGTERM, &sa, NULL))
请注意,在 struct sigaction 的字段中是 sa_flags ,一个位掩码,您可以使用它在历史上由 signal() 的不同版本实现的各种行为中进行选择。 .特别是,如果您不包括 SA_RESTART标志,因为上面确实没有,那么你不应该看到系统调用在被信号中断时自动恢复(除了那些明确指定这样做的少数)。

关于c - 捕获信号时使 open() 返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69666704/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com