標準
標準/拡張機能 |
C/C++ |
依存項目 |
POSIX.1
XPG4
XPG4.2
Single UNIX Specification、バージョン 3
|
両方 |
|
形式
#define _POSIX_SOURCE
#include <setjmp.h>
void siglongjmp(sigjmp_buf env, int val);
機能説明
sigsetjmp() によって、以前に env に保管されたスタック環境の
場合、siglongjmp() 関数は、すべてのスタック環境
、および sigsetjmp() によって保管されたかどうかにより、シグナル・マスクをオプションで復元します。sigsetjmp() および siglongjmp() 関数は、非ローカル goto を実行する方法を提供します。
env は、sigjmp_buf 構造体のアドレスです。
val は、siglongjmp() からの戻り値です。
シグナル・マスク復元のオプション機能を除けば、siglongjmp() は longjmp()
に似ています。sigsetjmp() と siglongjmp() の対、setjmp() と longjmp() の対、_setjmp() と _longjmp() の対、および getcontext() と setcontext() の対を
混用することはできません。sigsetjmp() によって保管されたスタック環境およびシグナル・マスクは、siglongjmp() でのみ復元できます。
オプションでのシグナル・マスクを含む現行のスタック環境が、sigsetjmp() への呼び出しによって、
env に保管されます。siglongjmp() への以降の呼び出しにより、保管済み環境および
シグナル・マスク (sigsetjmp() で保管された場合) が復元され、制御が sigsetjmp() 呼び出しに対応するプログラムのポイントへ戻されます。sigsetjmp() 呼び出しによって、指定
value が
戻された時点から実行が再開されます。制御を受信する関数にアクセス可能な (レジスター変数を除いた) すべての変数に、siglongjmp() の呼び出し時に保持していた値が
含まれています。レジスター変数の値は、予測不可能です。sigsetjmp() と siglongjmp() の間の呼び出しで変更される、非揮発性の auto 変数も予測不可能です。
注 : - siglongjmp() を呼び出した場合には、sigsetjmp() への対応する
呼び出しが行われた関数を、最初に戻す必要はありません。sigsetjmp() を呼び出す関数が戻った後に
siglongjmp() を呼び出すと、予測不可能なプログラムの動作が発生します。
- XPLINK ルーチンにジャンプして戻るために siglongjmp() を使用すると、それより前の sigsetjmp() (または getcontext()、その他) が呼び出された後、および siglongjmp() が呼び出される前に、XPLINK ルーチンによって発行されたすべての alloca() 要求はバックアウトされます。これらの alloca() 要求によって取得されたすべてのストレージは、XPLINK ルーチンが再開される前に解放されます。
- XPLINK 以外のルーチンにジャンプして戻るために siglongjmp() を使用すると、sigsetjmp() の後および siglongjmp() の前に発行された alloca() 要求はバックアウトされません。
siglongjmp() に渡す value 引数は、ゼロ以外でなければなりません。ゼロ引数を value に指定すると、siglongjmp() でその位置
の値 1 が置換されます。
siglongjmp() 関数は、通常の関数呼び出しや戻りメカニズムを使用しません。siglongjmp() によって保管シグナル・マスクが復元されるのは、ゼロ以外の savemask 引数を使用した sigsetjmp() への呼び出し
によって、env パラメーターが初期設定された場合だけです。
C++ の特殊な動作: sigsetjmp() と siglongjmp() を使用して z/OS® XL C++ プログラム内の制御権を移動する場合、自動オブジェクトの破壊に関する動作は未定義です。
さらに、プログラム内の別の (宛先) ポイントに制御権を移動する例外がスローされたことによって、自動オブジェクトが破壊される場合、その同じ (宛先) ポイントに制御権を移動するスロー・ポイントで
siglongjmp() を呼び出したときの動作は、未定義です。
これは z/OS XL C++ と z/OS XL C/C++ の ILC の両方のモジュールに当てはまります。
sigsetjmp() と siglongjmp() の、try()、catch()、および throw() との併用も未定義です。
XPLINK コンパイル C++ の特殊な動作: setjmp.h および ucontext.h に関連する制約事項は、以下のとおりです。
- Language Environment® V2R10 以降のライブラリーと共に実行され、jmp_buf、sigjmp_buf、または ucontext_t の型を使用する、V2R10 以降の C コンパイラーでコンパイルされたすべての XPLINK プログラムは、Language Environment V2R9 以前からの C ヘッダーを付けてコンパイルすることはできません。
- いずれかのレベルの Language Environment ヘッダーを付けてコンパイルされた XPLINK 以外の関数は、jmp_buf、sigjmp_buf、または ucontext_t のデータ項目を定義し、これらの渡されたデータ項目をもった getcontext()、longjmp()、
_longjmp()、setjmp()、_setjmp()、setcontext()、sigsetjmp()、または swapcontext() を
呼び出す XPLINK 関数に、それらのデータ項目を渡すことはできません。
- __XPLINK__ が定義されると、Language Environment V2R10 およびそれ以降のヘッダーは、setjmp()、getcontext()、および関連した関数が XPLINK ルーチンから呼び出される際に、これらの関数によって必要とされるより大きな jmp_buf、
sigjmp_buf、または ucontext_t の領域を定義します。__XPLINK__ が定義されないと、Language Environment V2R10 およびそれ以降のヘッダーは、より小さい jmp_buf、sigjmp_buf、または ucontext_t の領域を定義します。V2R10 より前の Language Environment ヘッダーも、これらのデータ域がより小さいバージョンを定義します。XPLINK 関数が、小さい jmp_buf、sigjmp_buf、または ucontext_t の領域を
持った setjmp()、getcontext()、または類似の関数を呼び出す場合、渡された (小さすぎる) データ域の終端を超えて C ライブラリーを保管しようとすると、ストレージ・オーバーレイまたはプログラム・チェックが発生する場合があります。
戻り値
siglongjmp() は、値を戻しません。
文書化される errno 値はありません。
例
この例では、スタック環境およびシグナル・マスクが、ステートメント if(sigsetjmp(mark,1) != 0) ...
で保管されます。
システムで最初に if ステートメントが実行
される際、環境の保管時に sigsetjmp() は 0 を戻すので、mark に環境およびシグナル・マスク
が保管され、条件が偽に設定されます。
sigsetjmp() has been called
というメッセージが出力されます。
関数 p() への以降の呼び出しで、ローカル・エラー条件についてテストされます。これにより siglongjmp() が実行されることがあります。その場合、制御は
mark で保管された環境
を使用するオリジナルの sigsetjmp() 関数に戻され、シグナル・マスクを復元します。-1 が siglongjmp() 関数からの戻り値であるため、このときは、条件は真です。この場合、例ではブロック中のステートメントが実行され、
siglongjmp() has been called というメッセージが出力されます。そのあと、recover() 関数が実行され、プログラムが終了します。
#define _POSIX_SOURCE
#include <stdio.h>
#include <setjmp.h>
sigjmp_buf mark;
void p(void);
void recover(void);
int main(void)
{
if (sigsetjmp(mark) != 0) {
printf("siglongjmp() has been called¥n");
recover();
exit(1);
}
printf("sigsetjmp() has been called¥n");
⋮
p();
⋮
}
void p(void) {
int error = 0;
⋮
error = 9;
⋮
if (error != 0)
siglongjmp(mark, -1);
⋮
}
void recover(void) {
⋮
}