C言語システムコール-sigaction

sigactionシステムコール

概要

sigactionはシグナル受信時の動作を設定します。

シグナルハンドラとして設定した処理を実行したり、シグナルを無視するという動作が可能となります。

なお、sigactionではSIGKILLとSIGSTOPについては指定することができません。


sigactionではsigaction構造体を利用します。


struct sigaction {
    /* シグナルハンドラへの関数ポインタ */
    void     (*sa_handler)(int);
    void     (*sa_sigaction)(int, siginfo_t *, void *);
    /* シグナルハンドラ実行中にブロックするシグナルのマスク */
    sigset_t   sa_mask;
    /* シグナルハンドラの動作を修正するためのフラグ */
    int        sa_flags;
    /* 現在では廃止扱いであり、使用禁止です。 */
    void     (*sa_restorer)(void);
};

サンプルプログラム

回転するマークを表示して三十秒待ち合わせを行います。

SIGINT([Ctrl] + [c])で正常終了します。


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

/*!
 * @brief    正常にEXITする
 * @note     本来引数にintが必要
 */
static void
exit_process()
{
    fprintf(stderr, "Exit normally.\n");
    exit(0);
}

/*!
 * @brief      回転マークを表示して時間待ち合わせ
 * @param[in]  second  秒指定の待ち合わせ時間
 */
static void
wait_process(int second)
{
    int cnt = 0;
    char mark[5] = {'|', '/', '-', '\'};

    for(cnt = 0; cnt < second; cnt++){
        fprintf(stdout, "%c\r", mark[(cnt+1)%4]);
        fflush(stdout);
        sleep(1);
    }
}

/*!
 * @brief     sigaction sample
 * @return    0:success/-1:failure
 */
static int
sample_func(void)
{
    int rc = 0;
    struct sigaction act;

    /* シグナル設定 */
    memset(&act, 0, sizeof(act));
    act.sa_handler = exit_process; /* 関数ポインタを指定する */
    act.sa_flags = SA_RESETHAND;   /* ハンドラの設定は一回だけ有効 */

    /* SIGINTにシグナルハンドラを設定する */
    rc = sigaction(SIGINT, &act, NULL);
    if(rc < 0){
        printf("Error: sigaction() %s\n", strerror(errno));
        return(-1);
    }

    /* 待ち合わせ処理 */
    wait_process(30);

    return(0);
}

int
main(int argc, char *argv[])
{
    int rc = 0;

    if(argc != 1){
        fprintf(stderr, "Usage: %s\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    rc = sample_func();
    if(rc != 0) exit(EXIT_FAILURE);

    exit(EXIT_SUCCESS);
}

関連ページ