sigsetjmp() - スタック環境とシグナル・マスクの保管

標準

標準/拡張機能 C/C++ 依存項目

POSIX.1
XPG4
XPG4.2
Single UNIX Specification、バージョン 3

両方  

形式

#define _POSIX_SOURCE
#include <setjmp.h>

int sigsetjmp(sigjmp_buf env, int savemask);

機能説明

オプションでの現行シグナル・マスクを含む、現行スタック環境を 保管します。sigsetjmp() によって保管されたスタック環境およびシグナル・マスクは、あとで siglongjmp() を使って復元できます。

env は、sigjmp_buf 構造体のアドレスです。savemask は、シグナル・マスクを保管するかどうかを 決定するのに使用されるフラグです。これに 0 の値があった場合には、現行シグナル・マスクは 環境の一部として保管または復元されません。その他のどの値も、現行シグナル・マスクの保管および復元が 行われることを意味します。

シグナル・マスク保存のオプション機能を除けば、sigsetjmp() は setjmp() および _setjmp() に 似ています。setjmp() および longjmp() と同様に、sigsetjmp() と siglongjmp() 関数は、非ローカル goto

を実行する方法を提供します。

sigsetjmp() と siglongjmp() の対、setjmp() と longjmp() の対、_setjmp() と _longjmp() の対、および getcontext() と setcontext() の対を混用することはできません。sigsetjmp() によって保管されたスタック環境およびシグナル・マスクは、siglongjmp() でのみ復元できます。

sigsetjmp() を呼び出すと、現行スタック環境が env に保管されます。savemask パラメーターの値がゼロ以外の場合には、現行シグナル・マスクも env に保管されます。siglongjmp() への以降の呼び出しにより、保管済み環境および シグナル・マスク (sigsetjmp() で保管された場合) が復元され、制御が sigsetjmp() 呼び出しに対応するポイントへ戻されます。制御を受信する関数にアクセス可能な (レジスター変数を除いた) すべての変数の値に、siglongjmp() の呼び出し時に保持していた値が 含まれています。レジスター変数の値は、予測不可能です。sigsetjmp() と siglongjmp() の間の呼び出しで変更される、非揮発性の auto 変数も予測不可能です。

注: sigsetjmp() を呼び出す関数が、対応する siglongjmp() 関数を呼び出す前に戻らないことを確認してください。sigsetjmp() を呼び出す関数が戻った後に siglongjmp() を呼び出すと、プログラムが予測不可能な動作をする原因になります。

C++ の特殊な動作: sigsetjmp() と siglongjmp() を使用して z/OS® XL C++ プログラム内の制御権を移動すると、自動オブジェクトの破壊に関する動作は未定義です。 これは z/OS XL C++z/OS XL C/C++ の ILC の両方のモジュールに当てはまります。 sigsetjmp() と siglongjmp() の、try()、catch()、および throw() との併用も未定義です。

XPLINK コンパイル C++ の特殊な動作: setjmp.h および ucontext.h に関連する制約事項は、以下のとおりです。
  1. Language Environment® V2R10 以降のライブラリーと共に実行され、jmp_bufsigjmp_buf、または ucontext_t の型を使用する、V2R10 以降の C コンパイラーでコンパイルされたすべての XPLINK プログラムは、Language Environment V2R9 以前からの C ヘッダーを付けてコンパイルすることはできません。
  2. いずれかのレベルの Language Environment ヘッダーを付けてコンパイルされた XPLINK 以外の関数は、jmp_bufsigjmp_buf、または ucontext_t のデータ項目を定義し、これらの渡されたデータ項目をもった getcontext()、longjmp()、 _longjmp()、setjmp()、_setjmp()、setcontext()、sigsetjmp()、または swapcontext() を 呼び出す XPLINK 関数に、それらのデータ項目を渡すことはできません。
  3. __XPLINK__ が定義されると、Language Environment V2R10 およびそれ以降のヘッダーは、setjmp()、getcontext()、および関連した関数が XPLINK ルーチンから呼び出される際に、これらの関数によって必要とされるより大きな jmp_bufsigjmp_buf、または ucontext_t の領域を定義します。__XPLINK__ が定義されないと、Language Environment V2R10 およびそれ以降のヘッダーは、より小さい jmp_bufsigjmp_buf、または ucontext_t の領域を定義します。V2R10 より前の Language Environment ヘッダーも、これらのデータ域がより小さいバージョンを定義します。XPLINK 関数が、小さい jmp_bufsigjmp_buf、または ucontext_t の領域を 持った setjmp()、getcontext()、または類似の関数を呼び出す場合、渡された (小さすぎる) データ域の終端を超えて C ライブラリーを保管しようとすると、ストレージ・オーバーレイまたはプログラム・チェックが発生する場合があります。

戻り値

スタック環境およびシグナル・マスクの保管のために起動される際に、sigsetjmp() は 0 を戻します。

sigsetjmp() が発行されたユーザーのプログラム内の所定位置に制御が siglongjmp() によって転送される場合、sigsetjmp() は、siglongjmp() で指定されている値 val を戻します (val の値がゼロの場合には 1 を戻します)。

設定される 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,1) != 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)
{
⋮
}

関連情報