SIGALTSTACK(2)

名称
sigaltstack - シグナルスタックコンテキストの設定や入手

ライブラリ
libc

書式
<signal.h>

    typedef struct sigaltstack {
            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 は無視されてシグナルスタックは無効になります。 アクティブなスタックを無効にしようとすると、 sigaltstack() は -1 を戻し errno を EINVAL に設定します。 スタックが無効になると、すべてのシグナルは通常の ユーザスタックで動作するようになります。 スタックが後で有効にると、代替スタックで処理するように指定された すべてのシグナルは、その指定どおりに再開されます。

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,0) < 0)
    	perror("sigaltstack");

デフォルトサイズ以外の特定量のスタックスペースを必要とする シグナルハンドラを使用するプログラムでは、別の方法が使用できます。 値 MINSIGSTKSZ は、代替スタックの実行にオペレーティングシステムが 必要とするバイト数 / 文字数に定義されています。 代替スタックのサイズを算出する場合は、プログラムでスタック要件に MINSIGSTKSZ を追加し、オペレーティングシステムのオーバヘッドを許容する必要があります。

シグナルスタックは、スタックの拡大傾向とアラインメント要件に従って 自動的に調整されます。 シグナルスタックは、ハードウェアで保護されることもされないこともあり、 通常のスタックのように自動的に ``拡大'' しません。 スタックがオーバフローし、スペースが保護されていない場合は、 予期せぬ結果となることがあります。

戻り値

エラー
以下のうち 1 つが発生すると、 sigaltstack() システムコールは処理を失敗し、シグナルスタックコンテキストは変更されずに 残ります。

[EFAULT]
    ss か oss が、プロセスアドレス空間の有効な部分でないメモリを指しています。

[EINVAL]
    アクティブなスタックを無効にしようとしました。

[ENOMEM]
    代替スタック領域のサイズが MINSIGSTKSZ 以下になっています。

関連項目
sigaction(2), setjmp(3)

歴史
sigaltstack() の前バージョンである sigstack() システムコールは 4.2BSD で登場しました。