| 日本−日本語 |
|
|
|
![]() |
HP-UX リファレンス: セクション 2 : システムコール > ssigvector(2)廃止予定HP-UX 11i Version 2: September 2004 |
|
名称sigvector ― ソフトウェアシグナル機構 説明システムは、プロセスに届けることができるシグナルの集合を定義しています。 シグナルの集合は、 それぞれのシグナルの意味と副作用とともに signal(5) で定義されています。 このマニュアルエントリーでは、 sigblock(2)、 sigsetmask(2)、 sigpause(3C)、 および sigspace(2) とともに、 シグナルの到着と、シグナルを扱う手続きの整合性を保証する、 これらのシグナルを扱うひとつの機構を定義しています。 ここで述べる機構は、 signal(2) と同じプログラムの中では使わないでください。 sigvector() インタフェースでは、 シグナルの到着はハードウェア割込みの発生と似ています。 つまり、シグナルはそれ以上の条件をブロックされ、 現在のプロセスのコンテキストは保存され、新しいコンテキストが作られます。 プロセスは、シグナルが届いたときに起動されるハンドラー関数を指定するか、 シグナルがブロックされるか、無視されるかを指定することができます。 プロセスは、シグナルが発生したときに、システムがデフォルトの動作を とるかどうかを指定することもできます。 sigspace() を用いてシグナルを処理するためのスタック領域の最小量を保証することができます ( sigspace(2) を参照)。 すべてのシグナルは同じ優先順位を持っています。 起動の要因となったシグナルはブロックされ、 他のシグナルはなお発生可能な状態で、シグナルルーチンが実行されます。 大域的なシグナルマスクは、現在プロセスへの到着をブロックされている シグナルの集合を定義します。 あるプロセスのシグナルマスクは、 その上位のプロセスにより 初期化 されます (通常は 0 です)。 シグナルマスクは、 sigblock()、 sigsetmask()、 または sigpause() コール によって変更されるか、もしくはシグナルがプロセスに届けられたときに変更されます。 シグナルマスクは、 1 ビットがそれぞれのブロックされるシグナルを表す long として表現されます。 <signal.h> で定義されている次のマクロは、 シグナル番号 を相当するシグナルマスクのビットに変換するのに使われます。
あるプロセスにシグナルが発生すると、 そのシグナルはプロセスのペンディングしているシグナル集合に加えられます。 シグナルは、現在そのプロセスでブロックされていないならば、 プロセスに送られます。 シグナルが届くと、プロセスの現在の状態は保存され、 新しいシグナルマスクが計算され (以下で解説する)、 シグナルハンドラーが起動されます。 ハンドラーの呼出しは、 シグナルを扱うルーチンが正常に終了すれば、 プロセスが シグナルの到着の前と同じコンテキストでの実行に復帰できるようになっています。 プロセスが異なったコンテキストで復帰したければ、 自分自身で前のコンテキストを再設定するようにしなければいけません。 シグナルがプロセスへ届けられると、 プロセスの シグナルハンドラーが実行されている間 (または、 sigblock() や sigsetmask() が呼び出されるまで)、 新しいシグナルマスクが設定されます。 このマスクは、現在のシグナルマスクと、 届いたシグナルに対して最も最近に呼び出された sigvector() の vec.sv_mask (以下を参照) の値とのビット単位の OR を計算することにより作られます。 また、 SV_RESETHAND フラグがセットされていない場合 (以下を参照)、 到着したシグナルに応じたビットをセットすることにより作られます。 ユーザーのシグナルハンドラーが正常に終了したとき、もとのマスクが再設定されます。 sigvector() は、 sig で指定されるシグナルにハンドラーを割り当てます。 vec と ovec は、次の要素を含んでいる sigvec 構造体へのポインタです。
vec が 0 でない場合、 vec は、 ハンドラールーチン sv_handler) と、指定されたシグナルを届けるのに、システムが用いる マスク sv_mask) と、 シグナルの到着を変更するフラグセット sv_flags) を指定します。 ovec が 0 でない場合、 以前のシグナルの取扱いの情報がユーザーに返されます。 vec が 0 の場合、シグナルの取扱いは変更されません。 それゆえ、 sigvector() は、与えられたシグナルの現在の取扱いを調べるのに用いることができます。 vec と ovec が同じ構造体を指していた場合、 vec の値は上書きされる前に読み出されます。 sv_flags フィールドは、 シグナルの受け取りを変更するのに用いられます。 次のフラグビットが定義されています。
SV_ONSTACK がセットされている場合、システムは、 sigspace() システムコールでのシグナル処理のための領域を用いるか、またはその利用を許可します。 SV_BSDSIG がセットされている場合、シグナルはバークレー方式で与えられます。 次のシグナルがこのフラグにより影響されます。
SV_RESETHAND がセットされている場合、シグナルハンドラーは、 signal(2) で設定されるハンドラーと同じ方式で設定されます。 これは、シグナルハンドラーが実行されている間のシグナルマスクの設定 (上記参照) と、 シグナルを受けた後にハンドラーがリセットされるかどうか (下記参照) に影響を与えます。 SV_RESETHAND がセットされていない場合、 いったんシグナルハンドラーが設定されると、他の sigvector() コールが行われるか、 exec() システムコール ( exec(2) を参照) が実行されるまで設定されたままになります。 SV_RESETHAND がセットされていて、シグナルが signal(5) の "not reset when caught(捕獲時にリセットしない)"のうちのひとつである場合、 デフォルトのアクションは、 シグナルが捕まってシグナルを受けとる関数に入る前に、もとに戻されます。 "not reset when caught(捕獲時にリセットしない)"の違いは、 sigvector() が呼び出されて、 SV_RESETHAND がセットされていないときは無効です。 シグナルのデフォルトの動作は、 sv_handler を SIG_DFL にセットすることによりもとに戻すことができます。 通常このデフォルトは、プロセスの終了になっています。 sv_handler が、 SIG_IGN の場合、通常シグナルは後に無視され、 ペンディングしているシグナルは捨てられます。 SIG_DFL と SIG_IGN のそれぞれのシグナルの正確な意味は、 signal(5) で議論されています。 ある種のシステムコールはシグナルにより割り込まれる可能性がありますが、 他のすべてのシステムコールは、シグナルが送られる前に 完了します。 signal(5) に解説されている scp ポインタは、 sigvector() がサポートされている限り、 null にはなりません。 scp は機種に依存した sigcontext 構造体を指します。 この構造体のインプリメンテーションのすべては次のフィールドを含みます。
sc_syscall フィールドに対する SYS_NOTSYSCALL という値は、 シグナルがシステムコールに割り込んでいないことを示していて、 他のすべての値はシステムコールに割り込んでいることを示します。 受け取ったシグナルが、割込み可能なシステムコールの実行中に発生した場合、 シグナルハンドラーはすぐに起動されます。 シグナルハンドラーが正常終了すると、 sc_syscall_action フィールドの値が調べられ、その値が SIG_RETURN であれば、システムコールは中止され、割り込まれたプログラムはその呼出し を通り越して実行を続けます。 割り込まれたシステムコールの戻り値は-1 で、 errno が EINTR にセットされます。 sc_syscall_action フィールドの値が SIG_RESTART であれば、その呼び出しは再起動されます。 システムコールは、 read() もしくは write() システムコール で、データがまったく転送されていない場合に再起動されます ( read(2) または write(2) を参照)。 データがいくつか転送されていた場合、 操作は半転送で完了したとみなされ、 sc_syscall の値は SYS_NOTSYSCALL になります。 他の値は、未定義で、将来の使用のためにリザーブされています。 ハンドラーが異常終了した場合 ( longjmp() を使ったような場合 ― setjmp(3C) を参照)、それ以上のコンテキストの実行はユーザーの責任にまかされたまま、 システムコールは中止されます。 scp->sc_syscall の値が SYS_NOTSYSCALL のとき、 scp->sc_syscall_action は無視されます。 scp->sc_syscall_action は、 シグナルハンドラーの起動の前に、 常に SIG_RETURN に 初期化 されます。 割り込み可能なシステムコールが、 複数のシグナルに割り込まれたとき、 あるシグナルハンドラーが、 scp->sc_syscall_action に SIG_RETURN を返した場合、 続くシグナルハンドラーのすべては、 scp->sc_syscall に SYS_NOTSYSCALL を渡します。 高速なデバイス (ディスクなど) に対する read()、 write()、 または ioctl() の呼出しは、割り込まれないことに注意してください。 しかし、 遅いデバイス (プリンタなど) に対する I/O 呼出しは、割り込まれることがあります。 ネットワーキングに使われるような、他のシステムコールも、 いくつかのインプリメンテーションでは、割り込まれることがあります。 このような場合は、付加的な値を scp->sc_syscall に指定できます。 scp->sc_syscall の値を見るプログラムは、 常にそれらを記号定数と比べなければいけません。 なぜなら、 これらの定数の数値表現は、インプリメンテーションにより異なるかもしれないからです。 割り込み可能な システムコールと対応する scp->sc_syscall の値を下に示します。
<signal.h> をインクルードしたときに、 プリプロセッサマクロ _XPG2 が定義されている場合は、 これらのシステムコールは 定義されません。 これは、 『X/Open Portability Guide, Issue 2』 が SYS_OPEN ( limits(5) を参照) に対して異なった意味を割り当てているためです。 fork() または vfork() システムコールの後、 子プロセスは、 すべてのシグナル、シグナルマスク、用意されたシグナルスタック領域を引き継ぎます。 exec(2) は、 受け付けたシグナルのすべてをデフォルトのアクションに戻します。 無視されているシグナルは無視されたままで、 シグナルマスクは変更されず、 用意されたシグナルスタック領域は解放されます。 vec で指定されるマスクは、 signal(5) で定義されている、無視できないシグナルを ブロックすることはできません。 これはシステムにより暗黙のうちに強制されています。 現在終了している (ゾンビの) 子を持つプロセスが、 SIGCLD を捕まえるために sigvector() を呼び出した場合、 SIGCLD シグナルはすぐに呼出しプロセスに届けられるか、 現在 SIGCLD がブロックされているならブロックが解かれてからすぐに 届けられます。 それゆえ、 複数の子を起動していて SIGCLD を捕まえるプロセスでは、 複数のゾンビがいることを考慮して、 それぞれの起動の後で SIGCLD のハンドラーを再設定したほうがよいことがあります。 SIGCLD がハンドラーでブロックされている間に複数のプロセスが終了すると、 たった 1 つのシグナルしか到着しないので、 これは、 signal(2) のようにシステムによりリセットされないシグナルを扱う場合でも言えることです。 関数は、 wait() または wait3() を呼び出した後で、自分自身でハンドラーの再設定をしなければならないことに注意してください。 さもなければ、もとのシグナルを発生させた子プロセスが、 常にもうひとつのシグナルを送るということが起きます。 エラーsigvector() は次の条件のどれかを満たす場合に異常終了し、 新しいシグナルハンドラーは設定されません。
警告select(2) システムコールを再起動すると、予期しない結果が起きることがあります。 select() コールにタイムアウトが指定された場合、 コールの再起動では、 タイムアウトの、シグナルによる割込みの前に経過した部分が無視されます。 通常は、これは単にタイムアウトを伸ばすだけで問題にはなりません。 しかし、ハンドラーが繰り返しシグナルを受け取り、 select() に指定したタイムアウトがそれらのシグナルの間隔より長い場合、 select() コールを再起動することは、事実上、タイムアウトを無限にすることになります。 sigvector() を、 sigset(3C) で述べた機能と組み合わせて使わないようにしてください。 アプリケーション使用法スレッドについての留意事項sigvector() で設定されるシグナル受信時の動作 (捕捉無視デフォルト など) は、プロセス内のすべてのスレッドで共有されます。各スレッドは、ブロックされているシグナルマスクを個別に管理します。 シグナルとスレッドの詳細については、 signal(5) を参照してください。 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||