在c语言中,我想捕捉到SIGINT信号并打印出一条类似于
通过使用sigaction并通过

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中断时,syscall将返回错误,请参阅手册页:
eIntr在读取任何数据之前,呼叫被信号中断;请参阅信号(7)。
因此,您应该检查errnofgets,如果是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;
}

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

10-11 06:29