Namespaces
Variants

signal

ja.cppreference.net より
ヘッダ <signal.h>
void (*signal( int sig, void (*handler) (int))) (int);

シグナル sig の取り扱いを変更する。handler の値に応じて、シグナルは無視されるか、デフォルトに設定されるか、(*handler)(sig) として呼び出されるユーザ定義関数によって処理される。

シグナルハンドラが関数に設定されてシグナルが発生した場合、シグナルハンドラの開始直前に signal(sig, SIG_DFL) が実行されるかどうかは処理系定義である。また、実装は、シグナルハンドラの実行中に発生するいくつかの処理系定義のシグナルセットを防止することができる。

パラメータ

sig - シグナルハンドラを設定するシグナル。実装定義の値、または以下の値のいずれかであり得る:
シグナルの種類を定義する
(マクロ定数)
handler - シグナルハンドラ。以下のいずれかでなければならない:
  • SIG_DFL マクロ。シグナルハンドラはデフォルトのシグナルハンドラに設定される。
  • SIG_IGN マクロ。シグナルは無視される。
  • 関数へのポインタ。関数のシグネチャは以下と等価でなければならない:
void fun(int sig);

戻り値

成功した場合は以前のシグナルハンドラ、失敗した場合は SIG_ERR (一部の実装ではシグナルハンドラの設定が無効化されている場合がある)。

シグナルハンドラ

シグナルハンドラとしてインストールされるユーザ定義関数には、以下の制限が課される。

ユーザ定義関数が SIGFPE、SIGILL、または SIGSEGV の処理中に戻った場合、動作は未定義である。

シグナルハンドラが abort または raise の結果として呼び出された場合、シグナルハンドラが raise を呼び出すと動作は未定義である。

シグナルハンドラが abort または raise の結果としてではなく呼び出された場合 (つまり、シグナルハンドラは 非同期)、以下の場合に動作は未定義である:

  • シグナルハンドラが標準ライブラリ内の任意の関数を呼び出す場合。ただし、
  • abort
  • _Exit
  • quick_exit
  • signal を現在処理中のシグナル番号を最初の引数として呼び出す場合を除く (非同期ハンドラはそれ自身を再登録できるが、他のシグナルは再登録できない)。
  • アトミック関数 (<stdatomic.h> の) で、アトミック引数がロックフリーである場合
  • atomic_is_lock_free (任意の種類のアトミック引数を持つ)

シグナルハンドラに入るとき、浮動小数点環境の状態とすべてのオブジェクトの値は未規定である。ただし、以下は除く:

  • 型 volatile sig_atomic_t
  • のオブジェクトロックフリーアトミック型のオブジェクト (C11 以降)
  • atomic_signal_fence を通して可視化される副作用 (C11 以降)

シグナルハンドラから戻るとき、シグナルハンドラによって変更されたオブジェクトの値で、volatile sig_atomic_t またはロックフリーアトミックではない(C11 以降) ものは未定義である。

マルチスレッドプログラムで signal を使用した場合の動作は未定義である。スレッドセーフである必要はない。

ノート

POSIX は signal がスレッドセーフであることを要求し、任意のシグナルハンドラから呼び出しても安全な非同期シグナルセーフなライブラリ関数のリストを指定している。

abort と raise に加えて、POSIX は kill、pthread_kill、および sigqueue が同期シグナルを生成することを指定している。

POSIX は、シグナルハンドラの実行中のシグナル配信に関して、動作の規定が不十分で実装によるばらつきが大きいため、sigaction の代わりに signal を推奨している。

例

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

volatile sig_atomic_t gSignalStatus;

void signal_handler(int signal)
{
    gSignalStatus = signal;
}

int main(void)
{
    signal(SIGINT, signal_handler);

    printf("SignalValue: %d\n", gSignalStatus);
    printf("Sending signal: %d\n", SIGINT);
    raise(SIGINT);
    printf("SignalValue: %d\n", gSignalStatus);
}

出力:

SignalValue: 0
Sending signal: 2
SignalValue: 2

参考文献

  • C23 規格 (ISO/IEC 9899:2024):
  • 7.14.1.1 The signal function (p: 285-286)
  • C17 規格 (ISO/IEC 9899:2018):
  • 7.14.1.1 The signal function (p: 193-194)
  • C11 規格 (ISO/IEC 9899:2011):
  • 7.14.1.1 The signal function (p: 266-267)
  • C99 規格 (ISO/IEC 9899:1999):
  • 7.14.1.1 The signal function (p: 247-248)
  • C89/C90 規格 (ISO/IEC 9899:1990):
  • 4.7.1.1 The signal function

関連項目

特定のシグナルのシグナルハンドラを実行する
(関数)