4.2.5 シグナル処理と OpenVMS の例外処理 |
|
ここでは, HP C RTL のシグナル処理が OpenVMS の例外処理でどのように実装され,どのように相互に影響するかについて説明します。このセクションの説明を読むと, HP C RTL のシグナル処理と競合しない OpenVMS 例外ハンドラを作成することができます。 OpenVMS の例外処理の詳細については,『OpenVMS Procedure Calling and Condition Handling Standard』を参照してください。
HP C RTL では, OpenVMS の例外によってシグナルを実装しています。
gsignalまたは
raiseを呼び出すと,シグナル番号が特定の OpenVMS 例外に変換され, LIB$SIGNAL の呼び出しで使用されます。ユーザ・エラーによって発生した OpenVMS 例外を検出し,それを対応する UNIX シグナルに変換するには,この機能が必要です。たとえば,NULL ポインタへの書き込みによって発生する ACCVIO は, SIGBUS または SIGSEGV シグナルに変換されます。
表 4-4 ,および 4-5 は, HP C RTL のシグナル名,対応する Open VMS Alpha,および Integrity の例外,シグナルを生成するイベント,
gsignal関数および
raise関数で使用するための省略可能なシグナル・コードを示しています。
signalまたは
sigvecによって設定したシグナル・ハンドラを呼び出すために, HP C RTL は,プログラムの main ルーチンに OpenVMS 例外ハンドラを配置することにより,シグナルに対応する OpenVMS 例外をインターセプトします。プログラムに
main関数がある場合は,この例外ハンドラが自動的に設定されます。
main関数がない場合や, main 関数が HP C 以外の言語で作成されている場合は,このハンドラを設定するために
VAXC$CRTL_INITルーチンを呼び出す必要があります。
HP C RTL では,OpenVMS 例外を使用して
setjmp関数と
longjmp関数を実装しています。
longjmp関数を呼び出すと, C$_LONGJMP OpenVMS 例外が通知されます。 C$_LONGJMP 例外がユーザ例外ハンドラによって妨害されるのを防止するには,
LIB$ESTABLISHを呼び出す代わりに,
VAXC$ESTABLISHルーチンを使用してユーザ OpenVMS 例外ハンドラを設定します。 C$_LONGJMP ニーモニックは
<errnodef.h>ヘッダ・ファイルに定義されています。
C プログラムで OpenVMS 例外ハンドラと UNIX シグナルを使用する場合は,表
4-4 (Alpha only) に示した OpenVMS 例外を受け付けて再通知するように, OpenVMS 例外ハンドラを準備する必要があり,さらに HP C RTL の将来のバージョンで導入される可能性のある C$ 機能例外や C$_LONGJMP 例外も受け付けるようにしなければなりません。これは,UNIX シグナルがコンテキストでグローバルであるのに対し, OpenVMS 例外がスタック・フレーム・ベースだからです。
したがって,OpenVMS 例外ハンドラは, main ルーチンの HP C RTL 例外ハンドラより前に, UNIX シグナルに対応する例外を常に受け取ります。 OpenVMS 例外を再通知することにより, HP C RTL 例外ハンドラは例外を受け取ることができます。 OpenVMS 例外をインターセプトすることも可能ですが,その場合は,対応する UNIX シグナルを禁止します。