読者です 読者をやめる 読者になる 読者になる

すがブロ

sugamasaoのhatenablogだよ

SIGNAL を受信する

SIGNAL を受信するには

昔は signal 関数を使ってシグナルハンドラを設定していたけど、今は sigaction 関数を使うようだ。
参考

試しに実装してみた

大概の SIGNAL のサンプルソースだと、シグナル受けたよーで終わるのが多いけど、実際のプログラムの時はシグナルを受けたタイミングとプログラムの終了タイミングが異なるケースが多いので*1、後者の仕様で作成してみた。
受けるとる SIGNAL は SIGINT と SIGTERM にした。特に意味はない。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>

#define SIGNAL_ON 0
#define SIGNAL_OFF 1

int is_signal_int = SIGNAL_OFF;
int is_signal_term = SIGNAL_OFF;

void signal_int(int signum, siginfo_t *info, void *ctx){
        printf("signal[%d] signo(%d) code(0x%x)", signum, info->si_signo, info->si_code);
        is_signal_int = SIGNAL_ON;
}

void signal_term(int signum, siginfo_t *info, void *ctx){
        printf("signal[%d] signo(%d) code(0x%x)", signum, info->si_signo, info->si_code);
        is_signal_term = SIGNAL_ON;
}
int main(void) {
        struct sigaction signal[2];
        memset(&signal, 0, sizeof(signal));

        // シグナルハンドラ設定: SIGINT
        signal[0].sa_sigaction = signal_int;
        signal[0].sa_flags = SA_RESTART | SA_SIGINFO;

        if (sigaction(SIGINT, &signal[0], NULL) < 0) {
                exit(2);
        }

        // シグナルハンドラ設定: SIGTERM
        signal[1].sa_sigaction = signal_term;
        signal[1].sa_flags = SA_RESTART | SA_SIGINFO;

        if (sigaction(SIGTERM, &signal[1], NULL) < 0) {
                exit(2);
        }

        // シグナルで停止するまで無限ループ
        while(1) {
                puts("while[start]...");

                puts("ココの処理はかならずやり遂げるのだ!");

                // SIGNAL を受けたかチェック
                if(is_signal_term == SIGNAL_ON || is_signal_int == SIGNAL_ON) {
                        puts("終了しまーす");
                        exit(1);
                }
                puts("while[end]...");
                sleep(3);
        }

        return 0;
}

SIGNAL 送信と終了のタイミングを非同期にする為、 SIGNAL を受信したタイミングでグローバル変数に受信したよフラグを保存して、プログラム中の任意の場所でグローバル変数の状態を見て終了する。

補足のエントリを書きました

別に大した内容ではないけれど、ちょっと解説的なものを。
SIGNAL を受信する(2) - @sugamasao.blog.title # => ”コードで世界を変えたい”

*1:例えば、終了シグナルを受けたら処理中のファイルは保存しておく、等