signal
更新 : 2007 年 11 月
割り込みシグナル処理を設定します。
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();
}
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
Application aborting...
.NET Framework の相当するアイテム
適用できません。標準 C 関数を呼び出すには、PInvoke を使用します。詳細については、「プラットフォーム呼び出しの例」を参照してください。