signal
割り込みシグナル処理を設定します。
void (__cdecl *signal(
int sig,
void (__cdecl *func ) (int [, int ] )))
(int);
パラメーター
sig
シグナル値。func
実行される関数 最初のパラメーターはシグナル値、2 番目のパラメーターは最初のパラメーターが SIGFPE の場合に使用できるサブコードです。
戻り値
signal は、指定したシグナルに関連付けられている func の以前の値を返します。 たとえば、func の以前の値が SIG_IGN の場合は、戻り値も SIG_IGN になります。 戻り値が SIG_ERR の場合はエラーであり、その場合には errno が EINVAL に設定されます。
戻り値の詳細については、「_doserrno、errno、_sys_errlist、および _sys_nerr」を参照してください。
解説
signal 関数を使用すると、プロセスはオペレーティング システムからの割り込みシグナルの処理について、複数の方法から 1 つ選択します。 引数 sig は signal が応答する割り込みであり、SIGNAL.H で定義されている以下の記号定数 (マニフェスト定数) の 1 つを指定する必要があります。
sig の値 |
説明 |
---|---|
SIGABRT |
異常終了 |
SIGFPE |
浮動小数点エラー |
SIGILL |
無効な命令 |
SIGINT |
Ctrl + C シグナル |
SIGSEGV |
ストレージへの無効なアクセス |
SIGTERM |
終了要求 |
sig が上記のいずれの値でもない場合、「パラメーターの検証」に定義されているように、無効なパラメーター ハンドラーが呼び出されます。 実行の継続が許可された場合、この関数は errno を EINVAL に設定し、SIG_ERR を返します。
既定では、signal は sig の値に関係なく呼び出しプログラムを終了コード 3 で終了します。
注意
SIGINT は、すべての Win32 アプリケーションでサポートされていません。 Ctrl + C 割り込みが発生すると、Win32 オペレーティング システムはその割り込みの処理専用に新規スレッドを生成します。 その結果、UNIX などのシングルスレッド アプリケーションはマルチスレッドになり、予期しない動作の原因になります。
引数 func は、書き込むシグナル ハンドラーのアドレス、または SIGNAL.H でも定義されている定義済みの定数 SIG_DFL または SIG_IGN です。 func が関数の場合は、指定したシグナルのシグナル ハンドラーとしてインストールされます。 シグナル ハンドラーのプロトタイプには、int 型の仮引数 sig が必要です。 オペレーティング システムは、割り込みの発生時に sig を通じて実引数を渡します。この引数は、割り込みの発生元のシグナルです。 したがって、シグナル ハンドラー内で 6 つの記号定数 (上の表を参照) を使用して、どの割り込みが発生したかを判断し、適切なアクションを実行できます。 たとえば、signal を 2 回呼び出して同じハンドラーを 2 つの異なるシグナルに割り当ててから、ハンドラー内で引数 sig をテストし、受け取ったシグナルに基づいて異なるアクションを実行できます。
浮動小数点例外 (SIGFPE) をテストする場合、func は省略可能な 2 番目の引数を取る関数を指します。この 2 番目の引数は、FPE_xxx 形式の FLOAT.H で定義されている複数の記号定数 (マニフェスト定数) の 1 つです。 SIGFPE シグナルが発生した場合は、2 番目の引数の値を調べて浮動小数点例外の種類を判断し、適切なアクションを実行できます。 この引数と引数の値は、Microsoft の拡張機能です。
浮動小数点例外では、func の値はシグナルの受信時にリセットされません。 浮動小数点例外から回復するには、浮動小数点演算の前後の try/except 句を使用します。 または、setjmp と longjmp を組み合わせて使用する方法もあります。 どちらの場合でも、呼び出し側のプロセスは、未定義の浮動小数点状態のまま再開されます。
シグナル ハンドラーから値が返されると、呼び出し側プロセスは割り込みシグナルを受信した位置の直後から再開されます。 この位置は、シグナルの種類や操作モードには左右されません。
指定の関数が実行される前に、func の値は SIG_DFL に設定されます。 次の割り込みシグナルは、途中で signal 関数の呼び出しによって特に指定されない限り、SIG_DFL の説明どおりに処理されます。 したがって、呼び出された関数内でシグナルをリセットできます。
通常、シグナル ハンドラー ルーチンは割り込みの発生時に非同期に呼び出されるため、ランタイム操作が完了せず、状態が不明の場合は、シグナル ハンドラー関数が制御を取得することがあります。 シグナル ハンドラー ルーチンで使用できる関数の制限は以下のとおりです。
下位のルーチンや STDIO.H で定義されている入出力ルーチン (printf、fread など) は実行しない。
ヒープ ルーチンや、ヒープ ルーチンを使用するルーチン (malloc、_strdup、_putenv など) は呼び出さない。 詳細については、「malloc」を参照してください。
システム コールを生成する関数 (_getcwd、time など) を使用しない。
割り込みの原因が浮動小数点例外 (つまり、sig が SIGFPE の場合) 以外の場合は、longjmp を使用しない。 この場合は、まず _fpreset を呼び出して浮動小数点パッケージを再初期化します。
オーバーレイ ルーチンは使用しない。
signal 関数で SIGFPE 例外をトラップするには、プログラムに浮動小数点コードを含める必要があります。 プログラムに浮動小数点コードがなく、ランタイム ライブラリのシグナル処理コードが必要な場合は、volatile double を宣言して 0 で初期設定します。
volatile double d = 0.0f;
SIGILL シグナルと SIGTERM シグナルは、Windows NT では生成されません。 これらのシグナルは ANSI 互換用です。 したがって、これらのシグナルのシグナル ハンドラーを signal 関数で設定したり、raise を呼び出してシグナルを明示的に生成したりできます。
シグナルの設定は、_exec 関数または _spawn 関数を呼び出して生成した子プロセスでは保持されません。 シグナル設定は、新しいプロセスでは既定値にリセットされます。
必要条件
ルーチン |
必須ヘッダー |
---|---|
signal |
<signal.h> |
互換性の詳細については、「C ランタイム ライブラリ」の「互換性」を参照してください。
使用例
signal を使用して SIGABRT シグナルに独自の動作を追加する例を次に示します。 中止の動作の詳細については、「_set_abort_behavior」を参照してください。
// crt_signal.c
// compile with: /c
// Use signal to attach a signal handler to the abort routine
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Application aborting...\n");
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGABRT, SignalHandler);
abort();
}
同等の .NET Framework 関数
該当なし標準 C 関数を呼び出すには、PInvoke を使用します。詳細については、「プラットフォーム呼び出しの例」を参照してください。