SIGINT Singal ловится только один раз

Вот простое воссоздание этой проблемы:

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 на консоли. Нужно ли мне каждый раз сбрасывать обработчик или что-то подобное? Заранее спасибо.

1 ответ

Решение

signal сильно зависит от реализации, и вы должны использовать sigaction из-за этого. Вы наблюдаете так называемую семантику sysv signal- сигнал сбрасывается в обработчике на 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;
}

Это не сбрасывает сигнал и не блокирует его (по умолчанию блокируется на время обработки), потому что новый образ процесса, скорее всего, не захочет его заблокировать.

Другие вопросы по тегам