C 信号只被捕捉到一次

C 信号只被捕捉到一次,c,unix,signals,sigint,C,Unix,Signals,Sigint,以下是对这一问题的简单再创造: void handler(int sig){ if(sig == SIGINT){ printf("Signal caught\n"); execl("./recreate","./recreate",NULL); } } int main(){ printf("Main start\n"); signal(SIGINT,handler); w

以下是对这一问题的简单再创造:

void handler(int sig){
        if(sig == SIGINT){
                printf("Signal caught\n");
                execl("./recreate","./recreate",NULL);
        }
}

int main(){
    printf("Main start\n");
    signal(SIGINT,handler);
    while(1);

        return 0;
}

它只是在收到信号后再次运行。发生的情况是,它只能从终端读取CTR+C一次。从第二点开始,就是简单地在控制台上写入^C。我是否需要每次重置处理程序或类似的操作?提前感谢。

信号
是高度实现定义的,因此您应该使用
sigaction
。您所观察到的是
signal
的所谓sysv语义——该信号在处理程序中被重置为
SIG_DFL
,并且不会被阻止重新执行

您可能需要以下内容:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>

#define WRITE_LIT(fd, lit) write(fd, lit, sizeof lit - 1)

void handler(int sig){
        if(sig == SIGINT){
            WRITE_LIT(2, "Signal caught\n");
            execl("./recreate","./recreate", (char*)NULL);
            WRITE_LIT(2, "Couldn't run ./recreate\n");
            _exit(127);
        }
}

int main(){
    printf("Main start\n");
    sigaction(SIGINT, &(struct sigaction const){ 
        .sa_handler = handler, 
        .sa_flags = SA_NODEFER /*don't block signals for the new process image*/
    },
    0);
    while(1);
        return 0;
}
#包括
#包括
#包括
#定义写入(fd,LIT)写入(fd,LIT,LIT大小-1)
无效处理程序(int sig){
if(sig==SIGINT){
写入(2,“捕获信号”);
execl(“./重新创建”、“./重新创建”、(char*)NULL);
WRITE_LIT(2,“无法运行/重新创建”);
_出口(127);
}
}
int main(){
printf(“主启动\n”);
sigaction(SIGINT,&(struct-sigaction-const){
.sa_handler=handler,
.sa_flags=sa_NODEFER/*不阻止新进程映像的信号*/
},
0);
而(1),;
返回0;
}

这不会重置信号,也不会阻止它(默认设置是在处理程序期间阻止它),因为新进程映像可能不希望阻止它

signal
是高度实现定义的,因此您应该使用
sigaction
。您所观察到的是
signal
的所谓sysv语义——该信号在处理程序中被重置为
SIG_DFL
,并且不会被阻止重新执行

您可能需要以下内容:

#include <unistd.h>
#include <signal.h>
#include <stdio.h>

#define WRITE_LIT(fd, lit) write(fd, lit, sizeof lit - 1)

void handler(int sig){
        if(sig == SIGINT){
            WRITE_LIT(2, "Signal caught\n");
            execl("./recreate","./recreate", (char*)NULL);
            WRITE_LIT(2, "Couldn't run ./recreate\n");
            _exit(127);
        }
}

int main(){
    printf("Main start\n");
    sigaction(SIGINT, &(struct sigaction const){ 
        .sa_handler = handler, 
        .sa_flags = SA_NODEFER /*don't block signals for the new process image*/
    },
    0);
    while(1);
        return 0;
}
#包括
#包括
#包括
#定义写入(fd,LIT)写入(fd,LIT,LIT大小-1)
无效处理程序(int sig){
if(sig==SIGINT){
写入(2,“捕获信号”);
execl(“./重新创建”、“./重新创建”、(char*)NULL);
WRITE_LIT(2,“无法运行/重新创建”);
_出口(127);
}
}
int main(){
printf(“主启动\n”);
sigaction(SIGINT,&(struct-sigaction-const){
.sa_handler=handler,
.sa_flags=sa_NODEFER/*不阻止新进程映像的信号*/
},
0);
而(1),;
返回0;
}

这不会重置信号,也不会阻止它(默认设置是在处理程序期间阻止它),因为新进程映像可能不希望阻止它

信号的行为取决于您使用的Unix变体。要获得一致的行为,请改用。对于一般的信号处理和
signal()
函数尤其可在线使用,也可通过
man
命令使用。还请注意,
printf
不被认为是在信号处理程序中调用的安全函数。
signal
的行为取决于您使用的Unix变体。要获得一致的行为,请改用。对于一般的信号处理和
signal()
函数,有很好的文档可供在线使用,并且可以通过
man
命令使用。还请注意,
printf
不被认为是调用信号处理程序的安全函数。