スポンサーリンク

SIGACTION(2) FreeBSD システムコールマニュアル SIGACTION(2)

名称

sigaction − ソフトウェアシグナル機能

ライブラリ

標準 C ライブラリ (libc, −lc)

書式

#include <signal.h>

struct  sigaction {
        union {
                void    (*__sa_handler)(int);
                void    (*__sa_sigaction)(int, struct __siginfo *, void *);
        } __sigaction_u;                /* シグナルハンドラ */
        int     sa_flags;               /* 後述のシグナルオプション参照 */
        sigset_t sa_mask;               /* 適用するシグナルマスク */
};

#define

sa_handler

__sigaction_u.__sa_handler

#define

sa_sigaction

__sigaction_u.__sa_sigaction

int

       sigaction(int sig, const struct sigaction * restrict act,struct sigaction * restrict oact);

解説

システムではシグナルの集合を定義しており、これらはプロセスに配信されるこ とがあります。シグナルの配信は、ハードウェア割込みの発生に似ています。通 常の場合、シグナルのさらなる発生はブロックされ、現在のプロセスコンテキス トは保存されて、新しいプロセスコンテキストが作成されます。プロセスは、シ グナルの配信先 handler を指定することもあれば、シグナルを 無視することを 指定することもあります。シグナルが発生した場合に、システムがデフォルトの アクションを取ることを指定することも可能です。シグナルが ブロックされるこ ともあり、その場合、シグナルの配信は、 ブロックが解除されるまで延期されま す。配信時に取るアクションは、配信時に決まります。通常の場合は、シグナル ハンドラが、プロセスの現行スタックで動作します。これはハンドラごとに変更 可能であり、変更すれば、シグナルは特殊な シグナルスタックで実行可能です。

通常の場合、シグナルルーチンは、呼び出しの原因となったシグナルが ブロック された状態で動作しますが、その他のシグナルが発生する可能性はあります。グ ローバルの シグナルマスクには、プロセスへの配信が現在ブロックされているシ グナルの集合が定義されています。プロセスのシグナルマスクは、親のシグナル マスクで初期化されます (通常は空)。 sigprocmask(2) が呼び出された場合、ま たはシグナルがプロセスに配信された場合に、シグナルマスクは変更されます。

あるシグナルの生起条件がプロセスで発生すると、そのシグナルが、プロセスで 保留中のシグナルの集合に追加されます。そのシグナルがプロセスで現在 ブロッ クされていない場合は、プロセスに配信されます。シグナルは、プロセスがオペ レーティングシステムに入っている間に (システム呼び出し、ページエラーやト ラップ、クロック割込み中などに) 配信されます。複数のシグナルの配信準備が 同時に整った場合は、トラップで生じたシグナルが先に配信されます。その他の シグナルは、それぞれが前のシグナルのハンドラに対し、最初の命令の前に割り 込んだ状態で同時に処理されます。保留になっているシグナルの集合は、 sigpending(2) システムコールで返されます。捕捉されたシグナルが配信される と、プロセスの現在の状態が保存され、新しいシグナルマスクが以下で説明する ように算出されて、シグナルハンドラが呼び出されます。ハンドラの呼び出し は、シグナル処理ルーチンが正常に戻った場合に、プロセスがシグナル配信前の コンテキストで実行を再開するように設定されます。プロセスが別のコンテキス トでの再開を望む場合は、前のコンテキストそのものを自分自身で回復するよう に設定する必要があります。

シグナルがプロセスに配信されると、プロセスのシグナルハンドラの実行が続く 間 (または sigprocmask(2) システムコールが呼び出されるまで)、新しいシグナ ルマスクが設置されます。このマスクは、現在のシグナルマスク集合、配信され るシグナル、呼び出されるハンドラに関連したシグナルマスクの和集合を取って 形成されます。

sigaction() システムコールは、 sig で指定したシグナルのアクションを割り当 てます。 act が 0 でない場合は、アクション (SIG_DFL, SIG_IGN かハンドラ ルーチン)、および指定されたシグナルの配信時に使用するマスクが指定されま す。 oact が 0 でない場合は、そのシグナルのそれまでの処理情報がユーザに返 されます。

シグナルハンドラが設置されると、通常の場合は別の sigaction() システムコー ルを呼び出すか execve(2) を実行するまで、そのシグナルハンドラは設置された ままです。 sa_handler を SIG_DFL に設定することで、シグナルごとに固有なデ フォルトアクションにリセットすることができます。デフォルトとは、プロセス の終了 (コアダンプが取られることもあります)、アクションなし、プロセスの停 止、プロセスの継続です。それぞれのシグナルのデフォルトアクションについて は、下記のシグナルリストを参照してください。 sa_handler が SIG_DFL である 場合、シグナルのデフォルトアクションはシグナルの破棄になります。また、シ グナルが保留になっている場合でも、シグナルがマスクされていても保留中のシ グナルは破棄されます。 sa_handler を SIG_IGN に設定すると、現在のシグナル 実体と保留中のシグナル実体は無視されて破棄されます。

オプションは、 sa_flags を設定することで指定できます。それぞれのビットの 意味は以下のとおりです:

             SA_NOCLDSTOP

SIGCHLD シグナルの受信関数を設置する場合にこのビッ トを設定すると、子プロセスが停止したときではなく、 子プロセスが終了するときにのみ、 SIGCHLD シグナルが 生成されます。

SA_NOCLDWAIT
SIGCHLD シグナルで sigaction() を呼び出す場合にこの ビットを設定すると、システムは、呼び出し側プロセス の子プロセスが終了したときにゾンビプロセスを作成し なくなります。そのあと、呼び出し側プロセスが wait(2) (かそれに相当する関数) を実行すると、呼び出 し側プロセスのすべての子プロセスが終了するまでブ ロックし、次に errno を ECHILD に設定して −1 を返し ます。 SIGCHLD のための sa_handler に SIG_IGN を設 定することによって、ゾンビの作成を避ける同じ効果を 得ることも可能です。

SA_ONSTACK
このビットを設定すると、システムは、 sigaltstack(2) で指定された シグナルスタックの上で、プロセスにシグ ナルを配信します。

SA_NODEFER
このビットを設定すると、配信済みシグナルのさらなる 発生が、ハンドラの実行中にマスクされなくなります。

SA_RESETHAND
このビットを設定すると、シグナルが配信された瞬間 に、ハンドラが SIG_DFL にリセットされます。

SA_RESTART
下の段落を参照してください。

SA_SIGINFO
このビットが設定されている場合、ハンドラ関数は、 struct sigaction 構造体の sa_sigaction メンバが指す ものと見なします。ハンドラ関数は、先に示したプロト タイプもしくは後で示す 使用例に一致しなくてはなりま せん。このビットは、 SIG_DFL もしくは SIG_IGN を割 り当てる時には設定してはいけません。

次に挙げるシステムコールの実行中にシグナルが捕捉されると、そのシステム コールの呼び出しは、エラー EINTR で強制終了されるか、要求より短いデータ転 送で戻るか、または再開されます。保留中のシステムコールの再開は、 sa_flags で SA_RESTART ビットを設定することで要求できます。影響を受けるシステム コールは、通信チャネルか遅いデバイス (端末など、通常ファイルではないもの) に対する open(2), read(2), write(2), sendto(2), recvfrom(2), sendmsg(2), recvmsg(2)wait(2), ioctl(2) です。しかし、すでに実行されているシステ ムコールは再開されず、部分的な処理成功の結果 (短い読取りカウントなど) を 返します。

fork(2)vfork(2) の後では、すべてのシグナル、シグナルマスク、シグナル スタック、再開フラグ、割込みフラグが子プロセスに継承されます。

execve(2) システムコールは、捕捉されていたすべてのシグナルのデフォルトア クションを元に戻し、すべてのシグナルをユーザスタックで受信されるようにリ セットします。無視されたシグナルは無視されたままです。シグナルマスクは同 じ状態のままです。保留中のシステムコールを再開する設定のシグナルは、その 再開の設定のままです。

以下はすべてのシグナルのリストです。名称は、インクルードファイル <signal.h> にあるものと同じです:

名称 デフォルトアクション 説明

SIGHUP プロセスの終了 端末ラインのハングアップ

SIGINT プロセスの終了 プログラムの割込み

SIGQUIT コアイメージの作成 プログラムの中断終了

SIGILL コアイメージの作成 不正な命令

SIGTRAP コアイメージの作成 トラップのトレース

SIGABRT コアイメージの作成 abort(3) の呼び出し (以前の SIGIOT)

SIGEMT コアイメージの作成 命令実行のエミュレート

SIGFPE コアイメージの作成 浮動小数例外

SIGKILL プロセスの終了 プログラムの強制終了

SIGBUS コアイメージの作成 バスエラー

SIGSEGV コアイメージの作成 セグメンテーション違反

SIGSYS コアイメージの作成 存在しないシステムコールの呼び出 し

SIGPIPE プロセスの終了 読取り側がないパイプへの書込み

SIGALRM プロセスの終了 リアルタイムタイマの満了

SIGTERM プロセスの終了 ソフトウェア終了シグナル

SIGURG シグナルの破棄 緊急状況がソケットに発生

SIGSTOP プロセスの停止 停止 (捕捉も無視もできません)

SIGTSTP プロセスの停止 キーボードから生成された停止シグ ナル

SIGCONT シグナルの破棄 停止後の継続

SIGCHLD シグナルの破棄 子プロセスの状態変化

SIGTTIN プロセスの停止 バックグラウンドプロセスが制御端 末から読み取ろうとした

SIGTTOU プロセスの停止 バックグラウンドプロセスが制御端 末に書き込もうとした

SIGIO シグナルの破棄 記述子への I/O 可能 (fcntl(2) 参 照)

SIGXCPU プロセスの終了 cpu 制限時間の超過 (setrlimit(2) 参照)

SIGXFSZ プロセスの終了 ファイルサイズ制限の超過 (setrlimit(2) 参照)

SIGVTALRM プロセスの終了 仮想時間アラーム (setitimer(2) 参 照)

SIGPROF プロセスの終了 プロファイリングタイマアラーム (setitimer(2) 参照)

SIGWINCH シグナルの破棄 ウィンドウサイズの変化

SIGINFO シグナルの破棄 キーボードからのステータス要求

SIGUSR1 プロセスの終了 ユーザ定義シグナル 1

SIGUSR2 プロセスの終了 ユーザ定義シグナル 2

act に指定する sa_mask フィールドでは、 SIGKILL や SIGSTOP をブロックでき ません。ブロックしようとしても無視されます。

以下の関数は、再入的であるかシグナルで割り込まれることがないかのどちらか で、非同期シグナルでも安全です。このため、アプリケーションは、シグナル受 信関数から制限なく呼び出せます:

ベースインタフェース

_exit(), access(), alarm(), cfgetispeed(), cfgetospeed(), cfsetispeed(), cfsetospeed(), chdir(), chmod(), chown(), close(), creat(), dup(), dup2(), execle(), execve(), fcntl(), fork(), fpathconf(), fstat(), fsync(), getegid(), geteuid(), getgid(), getgroups(), getpgrp(), getpid(), getppid(), getuid(), kill(), link(), lseek(), mkdir(), mkfifo(), open(), pathconf(), pause(), pipe(), raise(), read(), rename(), rmdir(), setgid(), setpgid(), setsid(), setuid(), sigaction(), sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(), signal(), sigpending(), sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), tcdrain(), tcflow(), tcflush(), tcgetattr(), tcgetpgrp(), tcsendbreak(), tcsetattr(), tcsetpgrp(), time(), times(), umask(), uname(), unlink(), utime(), wait(), waitpid(), write()

リアルタイムインタフェース

aio_error(), clock_gettime(), sigpause(), timer_getoverrun(), aio_return(), fdatasync(), sigqueue(), timer_gettime(), aio_suspend(), sem_post(), sigset(), timer_settime()

ANSI C インタフェース

strcpy(), strcat(), strncpy(), strncat() そして多分他にもいくつか

拡張インタフェース

strlcpy(), strlcat()

上のリストに記載されていないすべての関数は、シグナルに関して安全でないと 考えられます。つまり、そのような関数がシグナルハンドラから呼び出されると きの動作は、未定義です。しかし一般的に、シグナルハンドラはフラグを設定す る以上のことはあまりするべきではなく、それ以外のアクションは安全ではあり ません。

また、大域変数 errno のコピーを作成し、シグナルハンドラから戻る前にその値 を戻すようにするのはよいことです。こうすることによって、シグナルハンドラ の内部から呼ばれた関数によって errno が設定されてしまうという副作用を防ぐ ことができます。

戻り値

関数 sigaction() は、処理が成功すると値 0 を返します。そうでない場合、値 -1 が返され、グローバル変数 errno が設定されてエラーを示します。

使用例

ハンドラが一致する可能性のあるプロトタイプは 3 つあります:

             ANSI C:

void handler(int);

伝統的な BSD スタイル:
void
handler(int, int code, struct sigcontext *scp);

POSIX の SA_SIGINFO:
void
handler(int, siginfo_t *info, ucontext_t *uap);

sa_flags フラグ中で SA_SIGINFO ビットが設定されている場合、ハンドラ関数は SA_SIGINFO プロトタイプに一致しなくてはなりません。その場合、 struct sigaction 構造体の sa_sigaction メンバがハンドラ関数を指していなければな りません。この方法で SIG_DFL あるいは SIG_IGN を割り当ててはいけないこと に注意してください。

SA_SIGINFO フラグが設定されていない場合、ハンドラ関数は ANSI C もしくは伝 統的な BSD プロトタイプのどちらかに一致しなくてはならず、 struct sigaction 構造体の sa_handler メンバがハンドラ関数を指していなければなり ません。実際には、 FreeBSD は常に後者である BSD プロトタイプの 3 つの引数 を送りますし、 ANSI C プロトタイプはそのサブセットになっていますので、ど ちらでも動作します。 FreeBSD インクルードファイルの sa_handler メンバ宣言 は、 (POSIX の要求に従い) ANSI C のものです。そのため、 BSD スタイルの関 数のポインタの場合、警告メッセージを無くしてコンパイルするにはキャストす る必要があります。伝統的な BSD スタイルは移植性がなく、その機能性も SA_SIGINFO ハンドラの完全な部分集合になっていますので、 BSD スタイルを使 うことは推奨されていません。

sig 引数はシグナル番号で、 <signal.h> の SIG... 値のうちの 1 つです。

BSD スタイルのハンドラの code 引数および SA_SIGINFO ハンドラへの info 引 数の si_code メンバには、シグナルの発生理由を説明した数値コードが含まれて います。通常、この数値コードは <sys/signal.h> にある SI_... 値の 1 つであ るか、もしくはシグナルに特化したコード、すなわち SIGFPE に対する FPE_... 値です。

BSD スタイルのハンドラの scp 引数は struct sigcontext 構造体のインスタン スを指しています。

POSIX SA_SIGINFO ハンドラの uap 引数は、ucontext_t のインスタンスを指して います。

エラー

以下のうち 1 つが発生すると、 sigaction() システムコールはエラーになり、 新しいシグナルハンドラは設置されません:

       [EFAULT]

actoact は、プロセスに割り当てられたアドレス空間の 範囲外を指しています。

[EINVAL]
sig
引数が、正しいシグナル番号になっていません。

[EINVAL]
SIGKILL か SIGSTOP のハンドラを無視するか提供しようと しました。

規格

sigaction() システムコールは、 ISO/IEC 9945-1:1990 (‘‘POSIX.1’’) に適合し ています。 SA_ONSTACK フラグと SA_RESTART フラグは、Berkeley の拡張機能で す。 SIGTRAP, SIGEMT, SIGBUS, SIGSYS, SIGURG, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO シグナルも同様です。これらのシグナ ルは、 BSD から派生したシステムのほとんどで使用できます。 SA_NODEFER フラ グと SA_RESETHAND フラグは、その他のオペレーティングシステムとの下位互換 性を保つためのものです。 SA_NOCLDSTOP フラグと SA_NOCLDWAIT フラグは、そ の他のオペレーティングシステムで一般的に見られるオプションです。これらの フラグは SIGCHLD を無視することによってゾンビの作成を避けるオプションと一 緒に、 Version 2 of the Single UNIX Specification (‘‘SUSv2’’) によって承 認されました。

関連項目

kill(1), kill(2), ptrace(2), sigaltstack(2), sigblock(2), sigpause(2), sigpending(2), sigprocmask(2), sigsetmask(2), sigsuspend(2), sigvec(2), wait(2), fpsetmask(3), setjmp(3), siginterrupt(3), sigsetops(3), ucontext(3), tty(4)

FreeBSD 10.0 June 7, 2004 FreeBSD 10.0

スポンサーリンク