SIGALTSTACK(2)

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

ライブラリ
libc

書式
<signal.h>

    struct sigaltstack {
    	char	*ss_sp;
    	size_t	ss_size;
    	int	ss_flags;
    };

int sigaltstack(const struct sigaltstack *ss, struct sigaltstack *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 で登場しました。