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


前へ 次へ 目次 索引


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 (VAX only) および表 4-5 (Alpha only) に示した OpenVMS 例外を受け付けて再通知するように, OpenVMS 例外ハンドラを準備する必要があり,さらに HP C RTL の将来のバージョンで導入される可能性のある C$ 機能例外や C$_LONGJMP 例外も受け付けるようにしなければなりません。これは,UNIX シグナルがコンテキストでグローバルであるのに対し, OpenVMS 例外がスタック・フレーム・ベースだからです。

したがって,OpenVMS 例外ハンドラは, main ルーチンの HP C RTL 例外ハンドラより前に, UNIX シグナルに対応する例外を常に受け取ります。 OpenVMS 例外を再通知することにより, HP C RTL 例外ハンドラは例外を受け取ることができます。 OpenVMS 例外をインターセプトすることも可能ですが,その場合は,対応する UNIX シグナルを禁止します。

表 4-5 HP C RTLのシグナルと対応する OpenVMS Alpha 例外 (Alpha only )
名前 OpenVMS 例外 シグナルを生成するイベント コード
SIGABRT SS$_OPCCUS abort 関数 --
SIGALRM SS$_ASTFLT alarm 関数 --
SIGBUS SS$_ACCVIO アクセス違反 --
SIGBUS SS$_CMODUSER 変更モード・ユーザ --
SIGCHLD C$_SIGCHLD 子プロセスの停止 --
SIGEMT SS$_COMPAT 互換性モード・トラップ --
SIGFP SS$_DECDIV 10 進数除算トラップ FPE_DECDIV_TRAP
SIGFPE SS$_DECINV 10 進数不正オペランド・トラップ FPE_DECINV_TRAP
SIGFPE SS$_DECOVF 10 進数オーバフロー・トラップ FPE_DECOVF_TRAP
SIGFPE SS$_HPARITH 0 による浮動小数点/ 10 進数除算 FPE_FLTDIV_TRAP
SIGFPE SS$_HPARITH 浮動小数点オーバフロー・トラップ FPE_FLTOVF_TRAP
SIGFPE SS$_HPARITH 浮動小数点アンダフロー・トラップ FPE_FLTUND_TRAP
SIGFPE SS$_HPARITH 整数オーバフロー FPE_INTOVF_TRAP
SIGFPE SS$_HPARITH 不正なオペランド FPE_INVOPR_TRAP
SIGFPE SS$_HPARITH 不正確な結果 FPE_INXRES_TRAP
SIGFPE SS$_INTDIV 0 による整数除算 FPE_INTDIV_TRAP
SIGFPE SS$_SUBRNG 範囲外の添字 FPE_SUBRNG_TRAP
SIGFPE SS$_SUBRNG1 範囲外の添字 1 FPE_SUBRNG1_TRAP
SIGFPE SS$_SUBRNG2 範囲外の添字 2 FPE_SUBRNG2_TRAP
SIGFPE SS$_SUBRNG3 範囲外の添字 3 FPE_SUBRNG3_TRAP
SIGFPE SS$_SUBRNG4 範囲外の添字 4 FPE_SUBRNG4_TRAP
SIGFPE SS$_SUBRNG5 範囲外の添字 5 FPE_SUBRNG5_TRAP
SIGFPE SS$_SUBRNG6 範囲外の添字 6 FPE_SUBRNG6_TRAP
SIGFPE SS$_SUBRNG7 範囲外の添字 7 FPE_SUBRNG7_TRAP
SIGHUP SS$_HANGUP データ・セット・ハングアップ --
SIGILL SS$_OPCDEC 予約命令 ILL_PRIVIN_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$_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 より前のバージョン)。

OpenVMS Alpha のシグナル処理に関する注意 (Alpha only)

  • OpenVMS VAX システムに存在するシグナルはすべて OpenVMS Alpha システムにも存在しますが,対応する OpenVMS 例外とコードは,多くの場合異なります。これは,Alpha プロセッサでは,2 つの新しい OpenVMS 例外が追加され,複数の例外が無効になったからです。

  • OpenVMS Alpha システムのすべての浮動小数点例外は, OpenVMS 例外 SS$_HPARITH ( 高性能算術演算トラップ ) によって通知されます。発生した特定のタイプのトラップは,例外サマリ・ロングワードを使用することによって HP C RTL で変換されます。このロングワードは,高性能算術演算トラップが通知されるときに設定されます。

  • SS$_COMPAT,SS$_TBIT, SS$_RADMOD 例外が OpenVMS Alpha システムで報告されることはないため,OpenVMS Alpha システムではこれらの例外は HP C RTL で認識さません。これらの各例外に対応するシグナルは,他の OpenVMS 例外にも対応するため,すべてのシグナルが 表 4-5 に示されています。

4.3 プログラムの例

例 4-1 は, signalalarmpause関数の動作方法を示しています。また,プログラムの終了を防止するために,シグナルを検出するようにシグナル・ハンドラを設定する方法も示しています。

例 4-1 プログラムの一時停止と再開

/*    CHAP_4_SUSPEND_RESUME.C                                   */ 
 
/* This program shows how to alternately suspend and resume a   */ 
/* program using the signal, alarm, and pause functions.        */ 
 
#define SECONDS 5 
 
#include <stdio.h> 
#include <signal.h> 
 
int number_of_alarms = 5;       /*  Set alarm counter.            */ 
 
void alarm_action(int); 
 
main() 
{ 
    signal(SIGALRM, alarm_action); /*  Establish a signal handler. */ 
                                   /*  to catch the SIGALRM signal.*/ 
 
    alarm(SECONDS);     /* Set alarm clock for 5 seconds. */ 
 
    pause();    /*  Suspend the process until     * 
                 *  the signal is received.       */ 
} 
 
void alarm_action(int x) 
{ 
    printf("\t<%d\007>", number_of_alarms); /*  Print the value of  */ 
                                            /*  the alarm counter.  */ 
 
    signal(SIGALRM, alarm_action);      /*  Reset the signal.       */ 
 
    alarm(SECONDS);     /*  Set the alarm clock.      */ 
 
    if (--number_of_alarms)     /*  Decrement alarm counter.  */ 
        pause(); 
} 

例 4-1 から次の出力が生成されます。


$ RUN  EXAMPLE
       <5>   <4>   <3>   <2>   <1>


第 5 章
サブプロセス関数

HP C Run-Time Library (RTL) では, HP C プログラムからサブプロセスを生成するための関数が提供されます。サブプロセスを生成するプロセスをと呼び,生成されるサブプロセスをと呼びます。

親プロセスの内部で子プロセスを生成するには, exec関数 ( execlexecleexecvexecveexeclpexecvp) および vfork関数を使用します。その他にも,親プロセスと子プロセスがプロセス間でデータの読み書きを実行するための関数 ( pipe) や 2 つのプロセスの同期をとるための関数 ( wait) などもあります。この章では,これらの関数のインプリメントの方法と使用方法について説明します。

親プロセスは子プロセスの内部で,同期的または非同期的に HP C プログラムを実行できます。同時に実行できる子プロセスの数は,システムの各ユーザに対して設定されている /PRCLM ユーザ登録クォータによって決定されます。サブプロセスの使用に影響を与える可能性のあるその他のクォータとしては, /ENQLM (キュー・エントリ・リミット),/ASTLM (AST 待ちリミット), /FILLM (オープン・ファイル・リミット) があります。

この章では,サブプロセス関数について説明します。 表 5-1 は, HP C RTL で提供されるすべてのサブプロセス関数を示しています。各関数の詳細については,『HP C ランタイム・ライブラリ・リファレンス・マニュアル (下巻)』「リファレンス・セクション」を参照してください。

表 5-1 サブプロセス関数
関数 説明
子プロセスの生成
system コマンド・プロセッサによって実行される文字列をホスト環境に渡す。
vfork 独立した子プロセスを生成する。
exec 関数
execl,execle,execlp
execv,execve,execvp
子プロセスの内部で起動されるイメージの名前を渡す。
プロセスの同期化
wait wait3 wait4 waitpid 値が子から返されるまで,親プロセスを一時停止する。
プロセス間通信
pipe 親プロセスと子プロセスの間の通信を可能にする。

5.1 HP C での子プロセスの生成

子プロセスは,OpenVMS LIB$SPAWN RTL ルーチンと HP C 関数によって生成されます (LIB$SPAWN の詳細については, VMS Run-Time Library Routines Volume を参照してください)。 LIB$SPAWN を使用すると,複数レベルの子プロセスを生成できます。親から生成された子がさらに子を生成することができます。生成できるレベルは,この章の冒頭で説明したユーザ登録クォータで認められている上限値までです。

子プロセスは他の HP C プログラムだけを実行できます。他のネイティブ・モードの OpenVMS 言語は,プロセス間で通信するために HP C の機能を共用しません。プロセス間で通信する場合,他の言語は同じ機能を使用しません。親プロセスは,DCL など,弊社がサポートするコマンド言語インタプリタ (CLI) のもとで実行しなければなりません。親を独立プロセスとして実行したり,ユーザ指定 CLI の制御のもとで実行することはできません。

DECC$DETACHED_CHILD_PROCESS 機能論理名を有効にすると,子プロセスが,サブプロセスではなく,デタッチされたプロセスとして生成されます。この機能のサポートには,制限があります。場合によっては,コンソールが親プロセスと,デタッチされたプロセスで共用できず, execが失敗することがあります。

親プロセスと子プロセスは, 図 5-1 に示すようにメールボックスを通じて通信します。このメールボックスは,子が実行されるコンテキストを転送します。このコンテキスト・メールボックスは,親がオープンしたすべてのファイルの名前やファイル記述子,それらのファイル内での現在の位置など,親から継承する情報を子に渡します。子イメージが終了すると,メールボックスは親によって削除されます。

図 5-1 親プロセスと子プロセスの間の通信リンク


注意

vfork関数と exec関数によって作成されるメールボックスは一時的なものです。このメールボックスの論理名は VAXC$EXECMBX であり, HP C RTL で使用するために予約されています。

メールボックスは 512 バイトの最大メッセージ・サイズおよび 512 バイトのバッファ・クォータで作成されます。これらの RTL 関数を使用してメールボックスを作成するには,TMPMBX 特権が必要です。 TMPMBX は DCL コマンド PRINT および SUBMIT で必要とされる特権であるため,システムの大部分のユーザはこの特権を保有しています。保有しているシステム特権を確認するには, SHOW PROCESS/PRIVILEGES コマンドを入力します。

これらのメールボックスの属性を変更することはできません。メールボックスの詳細については, VMS I/O User's Reference Volume を参照してください。

5.2 exec 関数

子プロセスで HP C イメージを実行するために呼び出すことのできる exec関数は 6 つあります。これらの関数では,戻りアドレスを設定するために vforkがあらかじめ呼び出されていることが必要です。 exec関数は,親プロセスで vforkが呼び出されていない場合,その関数を呼び出します。

vforkが親で呼び出されると, exec関数は親プロセスに戻ります。 vforkexec関数によって呼び出されると, exec関数はその関数自体に戻り,子プロセスが終了するのを待ち,その後で親プロセスを終了します。 exec関数は,親が vforkを呼び出して戻りアドレスを保存しない限り,親プロセスに戻りません。

OpenVMS バージョン 7.2 で, exec関数は実行可能イメージまたは DCL コマンド・プロシージャを起動するように拡張されました。ファイル拡張が file_name 引数に指定されていない場合は,この関数はまずファイル拡張が .EXE であるファイルを検索し,次にファイル拡張が .COM であるファイルを検索します。同じ名前の実行可能イメージとコマンド・プロシージャの両方が存在する場合は,コマンド・プロシージャを強制的に起動するために, .COM ファイル拡張を指定する必要があります。

DCL コマンド・プロシージャの場合は, exec関数は, P1P2,...パラメータなど, exec呼び出しに指定した最初の 8 つの arg0arg1,... 引数をコマンド・プロシージャに渡します。その場合,大文字と小文字の区別は保持されます。

UNIX ベースのシステムと異なり, HP C RTL の exec関数は,指定された実行可能イメージまたはコマンド・プロシージャが存在するかどうか,またこれらを起動および実行できるがどうかを常に判断できるわけではありません。したがって, exec関数は,子プロセスが指定されたファイルを実行できない場合でも,正常終了したように見えることがあります。

親プロセスへ返される子プロセスの状態は,エラーが発生したことを示します。このエラー・コードは, wait関数ファミリのいずれかの関数を使用することにより検索できます。

注意

OpenVMS システムの HP C RTL の vfork関数と exec関数は, UNIX システムの場合と異なる方法で動作します。

  • UNIX システムでは, vforkは子プロセスを生成し,親プロセスを一時停止し,親が停止した場所から子プロセスの実行を開始します。

  • OpenVMS システムでは, vforkexec関数で後で使用されるコンテキストを設定しますが,指定されたプログラムを実行するプロセスを開始するのは, vforkではなく, exec関数です。

プログラマの場合,次の重要な相違点に注意してください。

  • OpenVMS システムでは, vfork関数の呼び出しと exec関数の呼び出しの間のコードは親プロセスで実行されます。
    UNIX システムでは,このコードは子プロセスで実行されます。

  • OpenVMS システムでは, exec関数が呼び出されたポイントで,子プロセスはオープンされているファイルの記述子などを継承します。
    UNIX システムでは,この継承は, vforkが呼び出されたポイントで行われます。


前へ 次へ 目次 索引