Provided by: manpages-ja-dev_0.5.0.0.20210215+dfsg-1_all
名前
signal - ANSI C シグナル操作
書式
#include <signal.h> typedef void (*sighandler_t)(int); sighandler_t signal(int signum, sighandler_t sighandler);
説明
signal() の動作は UNIX のバージョンにより異なる。 また、歴史的に見て Linux のバージョンに よっても異なっている。 このシステムコールの使用は避け、 代わりに sigaction(2) を使用する こと。 下記の「移植性」を参照。 signal() はシグナル signum の処理方法を handler に設定する。 handler には、 SIG_IGN、 SIG_DFL、 プログラマが定義した関数 (「シグナルハンドラー」) のアドレスの いずれかを指定す る。 シグナル signum がプロセスに配送されると、以下のいずれかが発生する。 * 処理方法が SIG_IGN に設定されている場合、そのシグナルは無視される。 * 処理方法が SIG_DFL に設定されている場合、シグナルに関連づけられた デフォルトの動作が行 われる (signal(7) 参照)。 * 処理方法として関数が設定されている場合、 まず最初に処理方法が SIG_DFL にリセットされる かそのシグナルのブロックが実行された後、 signum を引き数として handler が呼び出される。 ハンドラーが起動される際にシグナルがブロックされた場合、 ハンドラーが返る際にそのシグナ ルのブロックが解除される。 シグナル SIGKILL と SIGSTOP は捕捉できず、無視することもできない。
返り値
signal() は、今までのシグナルハンドラーの値を返す。 エラーの場合は SIG_ERR を返し、 errno にエラーの原因を示す値を設定する。
エラー
EINVAL signum が不正である。
準拠
C89, C99, POSIX.1-2001.
注意
マルチスレッドプロセスにおける signal() の結果は、指定されていない。 POSIX では、 kill(2) や raise(3) で生成できないシグナル SIGFPE, SIGILL, SIGSEGV を無視 (ignore) した場合、その後の動作は未定義である。 ゼロによる整数割り算の結果は未定義となる。 アーキテクチャーによっては、このとき SIGFPE シグナルが生成される。 (同様に負の最大整数を -1 で割ると SIGFPE が生成されるかもしれない) このシグナルを無視すると無限ループに陥るかも しれない。 SIGCHLD の動作として SIG_IGN を設定した場合の詳細な動作については、 sigaction(2) を参照す ること。 シグナルハンドラー内から安全に呼び出すことができる、 async-signal-safe functions (非同期シ ングルで安全な関数) の リストについては signal(7) を参照。 sighandler_t の使用は GNU 拡張であり、 _GNU_SOURCE が定義された場合に公開される。glibc で は _BSD_SOURCE が定義された場合には (BSD 由来の) sig_t も定義される。このような型を使用し ないと、 signal() の宣言は読みにくいものとなる。 void ( *signal(int signum, void (*handler)(int)) ) (int); 移植性 移植性のある signal() の使い方は、シグナルの処理方法を SIG_DFL か SIG_IGN に設定する方法 だけである。 シグナルハンドラーを設定するのに signal() を使ったときの動作はシステムにより 異なる (POSIX.1 は明示的にこの違いを認めている)。 移植性が必要なときはこのシステムコールを 使用しないこと。 POSIX.1 は、 sigaction(2) を規定することで移植性に関する混乱を解決した。 sigaction(2) は シグナルハンドラーが起動される際の挙動を明示的に制御できる。 signal() の代わりにこのイン ターフェイスを使うこと。 オリジナルの UNIX システムでは、 signal() を使って設定されたハンドラーがシグナルの配送に より起動されると、 そのシグナルの処理方法は SIG_DFL にリセットされ、システムは同じシグナル がさらに生成されても シグナルの配送をブロックしなかった。これは、以下のフラグで sigaction(2) を呼び出すのと等価である。 sa.sa_flags = SA_RESETHAND | SA_NODEFER; System V でも、 signal() に対してこれらの挙動を規定している。 こうした挙動はまずく、ハン ドラーがハンドラー自身を再設定する機会が 来るより前に、同じシグナルがまた配送される可能性 がある。 さらに、同じシグナルが立て続けに配送されると、同じシグナルが ハンドラーを繰り返し 起動されることになる。 BSD はこの状況が改善したが、残念なことに、その過程で既存の signal() の挙動も変更された。 BSD では、シグナルハンドラーが起動された際、 シグナルの処理方法はリセットされず、 ハンド ラーの実行中は、同じシグナルのさらなる生成は配送がブロックされる。 また、 シグナルハンド ラーが中断された場合、 停止中のシステムコールのいくつかは自動的に再スタートされる。 BSD の 挙動は、 以下のフラグを指定した sigaction(2) の呼び出しと等価である。 sa.sa_flags = SA_RESTART; Linux での状況は以下の通りである。 * カーネルの signal() システムコールは System V 方式を提供している。 * デフォルトでは、glibc 2 以降では、 signal() ラッパー関数はカーネルのシステムコールを起 動しない。 代わりに、ラッパー関数は BSD 方式を示すフラグを使って sigaction(2) を呼び出 す。 機能検査マクロ _BSD_SOURCE を定義していれば、このデフォルトの動作となる。 デフォル トでは、 _BSD_SOURCE が定義される。 _BSD_SOURCE は _GNU_SOURCE が定義された場合には暗黙 のうちに定義され、 もちろん明示的に定義することもできる。 * glibc 2 以降では、機能検査マクロ _BSD_SOURCE が定義されていなければ、 signal() は System V 方式となる。 (gcc(1) が標準指定モード (-std=xxx or -ansi) で起動された場 合、もしくは _POSIX_SOURCE, _XOPEN_SOURCE, _SVID_SOURCE といった他の様々な機能検査マクロ が定義された場合、 デフォルトの _BSD_SOURCE の暗黙の定義は行われない。 feature_test_macros(7) を参照のこと。)
関連項目
kill(1), alarm(2), kill(2), killpg(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 3.79 の一部である。 プロジェクト の説明とバグ報告に関する情報は http://www.kernel.org/doc/man-pages/ に書かれている。