2017-03-17 27 views
1

更改默认操作在C语言中,我要赶在SIGINT信号,并打印出一个消息像 使用的sigaction并通过无法为SIGINT

传递一个新的处理程序,以它
sa.sa_sigaction = handler; 

我不“收到SIGINT”不想终止程序。

如果我通过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; 
} 
+0

你在sigaction之后和从main返回之前做了什么? – rici

+0

我更新了代码。我只是回应用户输入。 –

+0

那么你怎么知道sigint终止你的程序?我认为它只是完成,因为fgets返回。 – rici

回答

1

的问题是,fgets将调用read系统调用,系统调用会返回一个错误时SIGINT打断,看到读手册页:

EINTR的调用被中断在读取任何数据之前的信号;见信号(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; 
} 
+0

你是对的...我忘记了读取系统调用.....我只是试图用一个无限循环(wihle(1)),它的工作....非常感谢! –

+0

不客气! :P – fluter