sigaction
sigaction関数はsignal関数よりもより細かい制御ができる.sigactionはX/Open仕様ではsignalよりも信頼できるとして推奨しているらしい.
int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);sigactionの引数について以下に示す.
- signum
- sigaction構造体を設定するシグナル.
- act
- 設定するsigaction構造体.
- oldact
- 設定前(変更前)のsigaction構造体.
sigactionを使ったサンプルを以下に示す.
以下実行結果.
successed sigaction. catched SIGINT. successed raise.sa_gflagsをSA_ONESHOTにした効果(一回シグナルをキャッチしたらデフォルトのsigactionに戻る)もちゃんと出ている.
sigaction構造体のフィールドsa_maskはsigset_t型でシグナルの集合を表すものある.これはつきつめると/usr/include/bits/sigset.hの以下の部分になっているようだ.
/* A `sigset_t' has a bit for each signal. */
# define _SIGSET_NWORDS (1024 / (8 * sizeof (unsigned long int)))
typedef struct
{
unsigned long int __val[_SIGSET_NWORDS];
} __sigset_t;
#endif
で先のサンプルでは思い切って
sigset = malloc(_SIGSET_NWORDS);などとしてしまった(いいのかな).で,このシグナル集合を扱うのに便利な関数がある.
- int sigemptyset(sigset_t *set);
- setを空に初期化.
- int sigfillset(sigset_t *set);
- setにすべてのシグナルを設定.
- int sigaddset(sigset_t *set, int signum);
- setに指定したシグナルを追加.
- int sigdelset(sigset_t *set, int signum);
- setから指定したシグナルを削除.
- int sigismember(const sigset_t *set, int signum);
- setに指定いたシグナルが含まれていれば1,含まれていなければ0,signumが不正などの理由でエラーなら-1を返す.
仲間かどうかは知らないが,とにかくman sigactionとすると一緒に出て来る関数が三つある.
- int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
- ブロックされているシグナルのリストを変更する.howで追加,設定,削除を選択する.man参照.
- int sigpending(sigset_t *set);
- (ブロックされていて)待機中のシグナルのセットを引数setに格納する.
- int sigsuspend(const sigset_t *mask);
- シグナルのマスクを一時的にmaskに置き換えてシグナルを受信するまで待機する.返り値は常に-1.
sigpendingやsigismemberを使用したサンプルを示す.
以下実行結果.C-\でSIGQUITを送信して終了できる.
successed sigaction. type C-c signal handler called 1 times. type C-c more SIGINT is pending signal handler done. signal handler called 2 times. type C-c more SIGINT is not pending signal handler done. 終了このサンプルから,シグナルハンドラ実行中にブロックされている同じシグナルを何回送信しても一回しかシグナルハンドラが起動されないことが分かる.具体的には
type C-c moreと出てから3秒以内に複数回C-cをタイプして放置しても,一回しかシグナルハンドラが起動されていないことが分かる.
man sigactionで地味に書いてあったのをメモ.
- sigactionの二番目の引数をNULLにして呼び出し,そのあとoldactを参照すれば,現在のハンドラを確認できる.
- 二番目と三番目の引数をNULLにして呼び出すことで,signumが現在のマシンで有効かどうかを確認できる.

