gpt4 book ai didi

无法更改 SIGINT 的默认操作

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:40:57 24 4
gpt4 key购买 nike

在 C 中,我想捕获 SIGINT 信号并打印出类似这样的消息通过使用 sigaction 并通过

向其传递新的处理程序来“接收到 SIGINT”
sa.sa_sigaction = handler;

我不想终止程序。

如果我通过 shell 运行我的程序并使用 Ctrl+c 生成信号,信号处理程序将捕获信号并打印出我的消息。

之后,它将执行终止进程的默认操作。

我做错了什么?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>

static void handler(int sig, siginfo_t* si, void *unused){
if(sig == SIGINT){
printf("Signal %i received\n",si->si_signo);
}
}

int main(int argc, char* argv[]){
char s [256];


struct sigaction sa;

sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;

if(sigaction(SIGINT, &sa, NULL) < 0 ){
perror("sigaction");
}

fgets(s,sizeof(s), stdin);
printf("%s", s);
return 0;
}

最佳答案

问题是fgets会调用read系统调用,系统调用被SIGINT中断时会返回错误,见man阅读页数:

EINTR The call was interrupted by a signal before any data was read; see signal(7).

所以你应该检查fgetserrno,如果是EINTR,继续调用fgets。试试我更新的程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <string.h>
#include <signal.h>
#include <errno.h>

static void handler(int sig, siginfo_t* si, void *unused){
if(sig == SIGINT){
printf("Signal %i received\n",si->si_signo);
}
}

int main(int argc, char* argv[]){
char s [256];


struct sigaction sa = {0};

sigemptyset(&sa.sa_mask);
sigaddset(&sa.sa_mask, SIGINT);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = handler;

if(sigaction(SIGINT, &sa, NULL) < 0 ){
perror("sigaction");
}

char *p;
do {
p = fgets(s,sizeof(s), stdin);
} while (!p && errno == EINTR);
printf("%s\n", s);
return 0;
}

关于无法更改 SIGINT 的默认操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42853096/

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