コアダンプの数だけ強くなれるよ

見習いエンジニアの備忘log

Linuxでシグナル捕捉

使い方をすぐに忘れるsigactionでシグナルを捕捉する方法。

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

static volatile sig_atomic_t RecvSigno = 0;

void signal_handler(int signo)
{
    RecvSigno = signo;
}

int main(void)
{
    struct sigaction sigact = {
        .sa_handler = signal_handler,
        .sa_flags = 0,
    };
    uint8_t siglist[] = {
        SIGINT,
        SIGTERM,
        SIGQUIT,
        SIGCHLD,
        SIGPIPE,
    };

    sigemptyset(&sigact.sa_mask);

    for(int entry = 0; entry < sizeof(siglist); entry++) {
        if(sigaction(siglist[entry], &sigact, NULL) < 0) {
            int errcode = errno;
            char strerr[64] = {0};
            strerror_r(errcode, strerr, sizeof(strerr));
            printf("sigaction() failed(%s)\n", strerr);
        }
    }

    while (1) {
        if (RecvSigno != 0) {
            printf("Recieved signal(%d)\n", RecvSigno);
            RecvSigno = 0;
        }

        sleep(1);
    }

    return 0;
}

実行結果

$ gcc -o signal -std=gnu99 signal.c
$ ./signal
^CRecieved signal(2)   # Ctrl+C実行
Hangup                 # 別端末からkill -SIGHUP <pid>を実行
$


新規のプログラムはsignal(2)ではなくsigaction(2)を使うことが推奨される。
シグナルの扱いについてはMan page of SIGNAL参照。