struct sigvec { void (*sv_handler)(); int sv_mask; int sv_flags; };Ft int Fn sigvec int sig struct sigvec *vec struct sigvec *ovec
システムではシグナルの集合を定義しており、 これらはプロセスに配信されることがあります。 シグナルの配信は、ハードウェア割込みの発生に似ています。 シグナルのさらなる発生はブロックされ、現在のプロセスコンテキストは 保存されて、新しいプロセスコンテキストが作成されます。 プロセスは、シグナルの配信先 handler を指定することもあれば、シグナルを ブロックすること および 無視すること を指定することもあります。 シグナルが発生した場合に、システムがデフォルトのアクションを取ることを 指定することも可能です。 通常の場合、シグナルハンドラは、プロセスの現行スタックで動作します。 これは、ハンドラ毎に変更して、シグナルが特殊な シグナルスタック でハンドルされるようにできます。
すべてのシグナルの 優先順位 は同じです。 シグナルルーチンは、呼び出しの原因となったシグナルが ブロックされた 状態で動作しますが、その他のシグナルが発生する可能性はあります。 グローバルな シグナルマスク には、プロセスへの配信が現在ブロックされているシグナルの集合が 定義されています。 プロセスのシグナルマスクは、親のシグナルマスクに初期化されます (通常は 0)。 シグナルマスクは、 sigblock(2) か sigsetmask(2) を呼び出すか、シグナルがプロセスに配信された場合に変更され得ます。
シグナル条件がプロセスで発生すると、そのシグナルが、 プロセスで保留になっているシグナルの集合に追加されます。 そのシグナルがプロセスで現在 ブロック されていない場合は、プロセスに配信されます。 シグナルが配信されると、プロセスの現在の状態が保存され、 新しいシグナルマスクが以下で説明するように 算出されて、シグナルハンドラが呼び出されます。 ハンドラの呼び出しは、シグナル処理ルーチンが正常に戻った場合に プロセスがシグナル配信前のコンテキストで実行を再開するように編成されます。 プロセスが別のコンテキストでの再開を望む場合は、 プロセスが前のコンテキストそのものを回復するように編成する必要があります。
シグナルがプロセスに配信されると、新しいシグナルマスクが、 プロセスのシグナルハンドラが続く間 (または sigblock(2) か sigsetmask(2) が呼び出されるまで) 設置されます。 このマスクは、現在のシグナルマスクに、配信されるシグナルを追加し、 呼び出されるハンドラに関連したシグナルマスクとの論理和 ( or を取って形成されます。
Fn sigvec 関数は、特定のシグナルにハンドラを割り当てます。 Fa vec を 0 以外にした場合は、指定したシグナルを配信する場合に使用する ハンドラルーチンとマスクが指定されます。 SV_ONSTACK ビットが Fa sv_flags で設定されている場合、システムは、 sigaltstack(2) で指定された シグナルスタック のプロセスにシグナルを配信します。 Fa ovec を 0 以外にした場合は、シグナルの前の処理情報がユーザに返されます。
以下はすべてのシグナルのリストです。 名称は、インクルードファイル In signal.h と同じです:
シグナルハンドラが設置されると、
Fn sigvec
を再度呼び出すか
execve(2)
を実行するまでシグナルハンドラは設置されたまま残ります。
シグナルに固有なデフォルトアクションへは、
Fa sv_handler
を
SIG_DFL
に設定することでリセットできます。
デフォルトは、プロセスの終了 (コアダンプが取られることもあります)、
アクションなし、プロセスの停止、プロセスの継続です。
それぞれのシグナルのデフォルトアクションについては、
上のシグナルリストを参照してください。
Fa sv_handler
が
SIG_IGN
である場合、シグナルの現在と保留中のインスタンスは無視されて放棄されます。
以下のリストのシステムコール中にシグナルが補足されると、 通常の場合、呼び出しは再開されます。 SV_INTERRUPT ビットを Fa sv_flags で設定することで、システムコールは、 Er EINTR エラー値を伴い、途中で終了するように強制可能です。 影響を受けるシステムコールは、 通信チャネルか遅いデバイス (端末などで、通常ファイルではない) に対する read(2), write(2), sendto(2), recvfrom(2), sendmsg(2), recvmsg(2) と wait(2), ioctl(2) の途中です。 しかし、すでに実行されているシステムコールは再開されず、 部分的な結果 (短い読取りカウントなど) を返します。
fork(2) か vfork(2) の後では、すべてのシグナル、シグナルマスク、シグナルスタック、 再開 / 割込みフラグが子に継承されます。
execve(2) システムコールは、補足されたすべてのシグナルのデフォルトアクションを元に戻し、 ユーザスタックで補足されるすべてのシグナルをリセットします。 無視されたシグナルは無視されたまま残ります。 シグナルマスクは同じ状態のままです。 システムコールに割り込むシグナルは、割込みを続けます。
BSD 4.2 では SV_INTERRUPT フラグを使用できないので、下位互換性が必要な場合は使用しないでください。
void handler(sig, code, scp) int sig, code; struct sigcontext *scp;
Fa sig は、ハードウェアフォルトとトラップのマップ対象のシグナル番号であり、 下のように定義されます。 Fa code 引数は、下で定義する定数、または互換性モードフォルトの場合は、 ハードウェアが提供するコードであるパラメータです (互換性モードフォルトは、pslに PSL_CM が設定されていることから、他の SIGILL トラップと区別されます)。 Fa scp 引数は、 Fa sigcontext 構造体 In ( signal.h で定義) へのポインタで、シグナル前にコンテキストを復元するために使用されます。