OpenVMS
HP C ランタイム・ライブラリ・
リファレンス・マニュアル (上巻)


前へ 次へ 目次 索引


4.2 シグナル処理

シグナルとは,ユーザ・プロセスの通常の実行に対するソフトウェア割り込みです。シグナルは次に示すイベントなど,さまざまなイベントの結果として発生します。

4.2.1 OpenVMS と UNIX の用語の比較

OpenVMS システムと UNIX システムはどちらも,シグナル処理機能を備えています。 2 つのシステムでこれらの機能は異なる動作をしますが,使用する用語は類似しています。 HP C RTL では,プログラミングの際にどちらのシグナル処理機能も使用できます。シグナル処理ルーチンについて説明する前に,一部の用語について定義しておく必要があります。

UNIX では,ソフトウェア割り込みのことをシグナルと呼びます。 UNIX システムでシグナルを処理するために呼び出すルーチンを シグナル・ハンドラと呼びます。

OpenVMS システムでは,ソフトウェア割り込みのことをシグナル条件例外などと呼びます。 OpenVMS システムでソフトウェア割り込みを処理するために呼び出すルーチンのことをシグナル・ハンドラ条件ハンドラ例外ハンドラと呼びます。

混乱を避けるために,本書では,シグナルおよび シグナル・ハンドラという用語は, UNIX の割り込みおよび割り込み処理ルーチンのことを参照し, 例外および例外ハンドラという用語は, OpenVMS の割り込みおよび割り込み処理ルーチンのことを参照することにします。

4.2.2 UNIX のシグナルと HP C RTL

シグナルは <signal.h>ヘッダ・ファイルに定義されているニーモニックによって表現されます。 表 4-3 は,サポートされるシグナル・ニーモニックと, OpenVMS オペレーティング・システムで各シグナルを生成するイベントを示しています。

表 4-3 HP C RTLシグナル
名前 説明 シグナルを生成するイベント
SIGABRT 1 強制終了 abort ()
SIGALRM アラーム・クロック タイマ AST, alarm ルーチン
SIGBUS バス・エラー アクセス違反または変更モード・ユーザ
SIGCHLD 子プロセスの停止 子プロセスの終了または停止
SIGEMT EMT 命令 互換性モード・トラップまたはカスタマに予約されている op コード
SIGFPE 浮動小数点例外 浮動小数点オーバフロー/アンダフロー
SIGHUP ハングアップ データ・セット・ハングアップ
SIGILL 1 不正な命令 不正な命令,予約オペランド,予約アドレス・モード
SIGINT 4 割り込み OpenVMS Ctrl/C 割り込み
SIGIOT 1 IOT 命令 カスタマに予約されている op コード
SIGKILL 23 削除 外部シグナルのみ
SIGQUIT 5 中止 インプリメントされていない
SIGPIPE 破壊されたパイプ リーダのないパイプへの書き込み
SIGSEGV セグメント違反 長さ違反または変更モード・ユーザ
SIGSYS システム呼び出しエラー システム呼び出しに対する不正な引数
SIGTERM ソフトウェアの終了 外部シグナルのみ
SIGTRAP 1 トレース・トラップ TBIT トレース・トラップまたはブレークポイント・フォルト命令
SIGUSR1 ユーザ定義シグナル シグナルを送信するための明示的なプログラム呼び出し
SIGUSR2 ユーザ定義シグナル シグナルを送信するための明示的なプログラム呼び出し
SIGWINCH 6 ウィンドウ・サイズの変更 シグナルを送信するための明示的なプログラム呼び出し


1検出したときにリセットできない。
2検出または無視できない。
3ブロックできない。
4SIGINT を設定すると, Ctrl/Y 割り込みの種類に影響を与える可能性がある。たとえば,SIGINT をブロックまたは無視するという呼び出し元の要求に応答して, HP C RTL は Ctrl/Y 割り込みを無効にする。
5SIGQUIT に対する「インプリメントされていない」という表現は, Ctrl/Y 割り込みも含めて,SIGQUIT シグナルを起動する外部イベントが存在しないため,SIGQUIT に対して設定されているシグナル・ハンドラが起動されることを意味する。このシグナルは,raise など,適切な HP C RTL 関数によってのみ生成することができる。
6OpenVMS バージョン 7.3 以降のバージョンでサポートされる。

デフォルト設定では,シグナル (SIGCHLD を除く) が発生すると,プロセスは終了します。しかし,次のいずれかの関数を使用してシグナルを無視するように設定することができます。

sigaction
signal
sigvec
ssignal

次のいずれかの関数を使用して,シグナルをブロックすることもできます。

sigblock
sigsetmask
sigprocmask
sigsuspend
sigpause

表 4-3 は,無視またはブロックできないシグナルを示しています。

次のいずれかの関数を使用して,シグナルを検出および処理するためにシグナル・ハンドラを設定することもできます。

sigaction
signal
sigvec
ssignal

表 4-3 に示した場合を除き,各シグナルはリセットできます。シグナル・ハンドラ関数が signalまたは ssignalを呼び出して,シグナルを検出するように再設定した場合,シグナルはリセットされます。 例 4-1 は,シグナル・ハンドラの設定方法とシグナルのリセット方法を示しています。

シグナル・ハンドラの呼び出しインタフェースは次のとおりです。


void handler (int sigint); 

ただし,sigint は,このハンドラを呼び出す原因になるシグナルのシグナル番号です。

sigvecによってインストールされたシグナル・ハンドラは,変更されるまでインストールされたままになります。

signalまたは signalによってインストールされたシグナル・ハンドラは,シグナルが生成されるまでインストールされたままになります。

複数のシグナルに対して 1 つのシグナル・ハンドラをインストールすることができます。このことを制御するには, SA_RESETHAND フラグを使用して sigactionルーチンを呼び出します。

4.2.3 シグナル処理の概念

イベントによってシグナルが最初に発生した場合,プロセスに対してシグナルが生成される ( またはプロセスにシグナルが送信される ) と言うことができます。このようなイベントとしては,ハードウェア障害の検出,タイマの満了,端末での動作, killの起動などがあります。場合によっては,同じイベントで複数のプロセスに対してシグナルが生成されることもあります。

各シグナルに対して各プロセスが実行する動作は,システムで定義されています。プロセスとシグナルに対して適切な動作が実行されたときに,シグナルはプロセスに配布されると言うこともできます。

シグナルが生成されてから配布されるまでの間,シグナルは保留状態であると言うことができます。通常,アプリケーションでこの間隔を検出することはできません。しかし,シグナルがプロセスに配布されないように ブロックすることはできます。

各プロセスにはシグナル・マスクがあり,現在配布されないようにブロックされているシグナルのセットが定義されます。プロセスのシグナル・マスクはその親のシグナル・マスクから初期化されます。 sigactionsigprocmasksigsuspend関数はシグナル・マスクの操作を制御します。

シグナルに対する応答としてどの動作を実行するかの判断は,シグナルの配布時に行われるため,シグナルが生成された後で変更することができます。この判断は,シグナルがもともと生成された手段とは無関係です。保留状態のシグナルが後で再び生成された場合,そのシグナルが 2 回以上配布されるかどうかはインプリメンテーションに応じて異なります。 HP C RTL ではシグナルは 1 回だけ配布されます。同時に保留状態になっている複数のシグナルがプロセスに配布される順序は不定です。

4.2.4 シグナル・アクション

このセクションの説明は, sigactionsignalsigvecssignal関数に適用されます。

シグナルに割り当てることができるアクションは次の 3 種類です。

SIG_DFL
SIG_IGN
関数を指すポインタ

最初は, mainルーチンのエントリの前で,すべてのシグナルが SIG_DFL または SIG_IGN に設定されます ( exec関数を参照)。これらの値によって設定される動作は次のとおりです。

SIG_DFL --- シグナル固有のデフォルト動作。



SIG_IGN --- シグナルを無視します。



関数に対するポインタ --- シグナルを検出します。

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 のシグナル名,対応する OpenVMS VAX および OpenVMS Alpha 例外,シグナルを生成するイベント, gsignal関数および raise関数で使用するための省略可能なシグナル・コードを示しています。

on
表 4-4 HP C RTLのシグナルと対応する OpenVMS VAX 例外 (VAX only)
名前 OpenVMS 例外 シグナルを生成するイベント コード
SIGABRT SS$_OPCCUS abort 関数 --
SIGALRM SS$_ASTFLT alarm 関数 --
SIGBUS SS$_ACCVIO アクセス違反 --
SIGBUS SS$_CMODUSER 変更モード・ユーザ --
SIGCHLD C$_SIGCHLD 子プロセスの停止 --
SIGEMT SS$_COMPAT 互換性モード・トラップ --
SIGFPE SS$_DECOVF 10 進オーバフロー・トラップ FPE_DECOVF_TRAP
SIGFPE SS$_FLTDIV 0 による浮動小数点/10 進数除算 FPE_FLTDIV_TRAP
SIGFPE SS$_FLTDIV_F 0 による浮動小数点除算フォルト FPE_FLTDIV_FAULT
SIGFPE SS$_FLTOVF 浮動小数点オーバフロー・トラップ FPE_FLTOVF_TRAP
SIGFPE SS$_FLTOVF_F 浮動小数点オーバフロー・フォルト FPE_FLTOVF_FAULT
SIGFPE SS$_FLTUND 浮動小数点アンダフロー・トラップ FPE_FLTUND_TRAP
SIGFPE SS$_FLTUND_F 浮動小数点アンダフロー・フォルト FPE_FLTUND_FAULT
SIGFPE SS$_INTDIV 0 による整数除算 FPE_INTDIV_TRAP
SIGFPE SS$_INTOVF 整数オーバフロー FPE_INTOVF_TRAP
SIGFPE SS$_SUBRNG 添字の範囲 FPE_SUBRNG_TRAP
SIGHUP SS$_HANGUP データ・セット・ハングアップ --
SIGILL SS$_OPCDEC 予約命令 ILL_PRIVIN_FAULT
SIGILL SS$_RADRMOD 予約アドレッシング ILL_RESAD_FAULT
SIGILL SS$_ROPRAND 予約オペランド ILL_RESOP_FAULT
SIGINT SS$_CONTROLC OpenVMS Ctrl/C 割り込み --
SIGIOT SS$_OPCCUS カスタマ予約 op コード --
SIGKILL SS$_ABORT 外部シグナルのみ --
SIGQUIT SS$_CONTROLY raise 関数 --
SIGPIPE SS$_NOMBX メールボックスなし --
SIGSEGV SS$_ACCVIO 長さ違反 --
SIGSEGV SS$_CMODUSER 変更モード・ユーザ --
SIGSYS SS$_BADPARAM システム呼び出しに対する不正な引数 --
SIGTERM インプリメントされていない -- --
SIGTRAP SS$_TBIT TBIT トレース・トラップ --
SIGTRAP SS$_BREAK ブレークポイント・フォルト命令 --
SIGUSR1 C$_SIGUSR1 raise 関数 --
SIGUSR2 C$_SIGUSR2 raise 関数 --
SIGWINCH 1 C$_SIGWINCH 2 raise 関数 --


1OpenVMS バージョン 7.3 以降のバージョンでサポートされる。
2C$_SIGWINCH が定義されていない場合は, SS$_BADWINCNT (OpenVMS バージョン 7.3 より前のバージョン)。

signalまたは sigvecによって設定したシグナル・ハンドラを呼び出すために, HP C RTL は,プログラムの main ルーチンに OpenVMS 例外ハンドラを配置することにより,シグナルに対応する OpenVMS 例外をインターセプトします。プログラムに main関数がある場合は,この例外ハンドラが自動的に設定されます。 main関数がない場合や, main 関数が HP C 以外の言語で作成されている場合は,このハンドラを設定するために VAXC$CRTL_INITルーチンを呼び出す必要があります。


前へ 次へ 目次 索引