POSIX 2013 より前の POSIX 規格では、シグナルハンドラ内で出来ることはかなり制限されてゐました。出来ることはせいぜい volatile な sig_atomic_t 型の静的記憶域期間変数に値を代入することによってフラグを立てる程度でした。
POSIX 2013 ではシグナルハンドラの制約が緩和され、単一スレッドプログラムでは以下の様な場面で「シグナルハンドラ内で何をしても良い」ことになりました。
- sigprocmask 関数でシグナルをブロックしておく。また sigaction 関数等でシグナルハンドラを設定しておく。
- スレッドにシグナルが送信される (が、ブロックされてゐるのでシグナルハンドラはまだ呼ばれない)。
- sigprocmask 関数 (または pselect や sigsuspend 等) でシグナルのブロックを解除する。この時 sigprocmask 関数等が返る前にシグナルハンドラが実行される。
これを利用すると、例へば以下の様なことが可能になります。
シグナルを受信した回数を数へる
以前の制約のもとでは volatile sig_atomic_t 型の静的記憶域期間変数を読むことができなかったため、値をインクリメントすることができませんでした。そのためシグナルハンドラから代入できる値は固定値のみでした。
新しい制約では値を読むことができるので変数のインクリメントをすることができます。これにより同じシグナルを複数回受信したときに受信回数を正確に数へることができます。
シグナルハンドラ内で直接複雑な処理をする
非同期シグナル安全でない関数 (malloc や printf 等) をシグナルハンドラ内で自由に呼ぶことができます。
特に、 sigaction で SA_SIGINFO フラグを使ってゐる時に、シグナルハンドラに渡された siginfo_t 型のデータを扱ふのが容易になりました。従来は、 siginfo_t の中身をパイプに write してシグナルハンドラの外で read するなどしなければ siginfo_t のデータを取り出した後さまざまな用途に応用することができませんでした。