SIGALTSTACK(2) | FreeBSD System Calls Manual | SIGALTSTACK(2) |
名称
sigaltstack — シグナルスタックコンテキストの設定や入手ライブラリ
Standard C Library (libc, -lc)書式
#include < signal.h>
typedef struct { char *ss_sp; size_t ss_size; int ss_flags; } stack_t;
int
sigaltstack( const stack_t * restrict ss, stack_t * restrict oss);
解説
sigaltstack() システムコールによって、現在のスレッドのために処理されるシグナルの代わりのスタックを定義することができます。 ss が 0 でないなら、シグナルを配信する シグナルスタック へのポインタとサイズを指定します。ハンドラがシグナルスタックで動作する必要があることをシグナルのアクションが示す場合 ( sigaction(2) システムコールで指定)、システムは、スレッドがそのスタックで動作中であるかどうかをチェックします。スレッドがシグナルスタックで動作していない場合、システムは、シグナルハンドラの動作中は、シグナルスタックを適切なものに切り替えます。アクティブなスタックを変更することはできません。
SS_DISABLE が ss_flags で設定されていると、 ss_sp と ss_size は、無視されてシグナルスタックは、無効になります。スタックが無効になると、すべてのシグナルは、通常のユーザスタックで動作するようになります。スタックが後で有効にると、代替スタックで処理するように指定されたすべてのシグナルは、その指定どおりに再開されます。
oss を 0 以外にすると、現在のシグナルスタックの状態が戻されます。 ss_flags フィールドの値は、スレッドが現在シグナルスタックにある場合は、 SS_ONSTACK に、シグナルスタックが現在無効である場合は、 SS_DISABLE になります。
注
値 SIGSTKSZ は、代替スタック領域を割り当てる一般的なケースで使用するバイト数 / 文字数に定義されます。代替スタックの割り当てには、一般的に以下のようなコードが使用されます。
if ((sigstk.ss_sp = malloc(SIGSTKSZ)) == NULL) /* error return */ sigstk.ss_size = SIGSTKSZ; sigstk.ss_flags = 0; if (sigaltstack(&sigstk, NULL) < 0) perror("sigaltstack");
デフォルトサイズ以外の特定量のスタックスペースを必要とするシグナルハンドラを使用するプログラムでは、別の方法が使用できます。値 MINSIGSTKSZ は、代替スタックの実行にオペレーティングシステムが必要とするバイト数 / 文字数に定義されています。代替スタックのサイズを算出する場合は、プログラムでスタック要件に MINSIGSTKSZ を追加し、オペレーティングシステムのオーバヘッドを許容する必要があります。
シグナルスタックは、スタックの拡大傾向とアラインメント要件に従って自動的に調整されます。シグナルスタックは、ハードウェアで保護されることもされないこともあり、通常のスタックのように自動的に ``拡大'' しません。スタックがオーバフローし、スペースが保護されていない場合は、予期せぬ結果となることがあります。
戻り値
The sigaltstack() function returns the value 0 if successful; otherwise the value -1 is returned and the global variable errno is set to indicate the error.エラー
以下のうち 1 つが発生すると、 sigaltstack() システムコールは、処理を失敗し、シグナルスタックコンテキストは、変更されずに残ります。- [ EFAULT]
- ss か oss が、プロセスアドレス空間の有効な部分でないメモリを指しています。
- [ EPERM]
- アクティブなスタックを変更する試みが行われました。
- [ EINVAL]
- ss_flags フィールドが無効でした。
- [ ENOMEM]
- 代替スタック領域のサイズが MINSIGSTKSZ 以下になっています。
歴史
sigaltstack() の前バージョンである sigstack() システムコールは、 4.2BSD で登場しました。May 6, 2010 | FreeBSD |