Provided by: manpages-ja-dev_0.5.0.0.20221215+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 が不正である。
準拠
POSIX.1-2001, POSIX.1-2008, C89, C99.
注意
マルチスレッドプロセスにおける signal() の結果は、指定されていない。 POSIX では、 kill(2) や raise(3) で生成できないシグナル SIGFPE, SIGILL, SIGSEGV を無視 (ignore) した場合、その後の動作は未定義である。 ゼロによる整数割り算の結果は未定義となる。 アーキテクチャーによっては、このとき SIGFPE シグナルが生成される。 (同様に負の最大整数を -1 で割ると SIGFPE が生成されるかもしれない) このシグナルを無視すると無限ループに陥るかも しれない。 See sigaction(2) for details on what happens when the disposition SIGCHLD is set to SIG_IGN. シグナルハンドラー内から安全に呼び出すことができる、 async-signal-safe functions (非同期シ グナルで安全な関数) のリストについては signal-safety(7) を参照。 The use of sighandler_t is a GNU extension, exposed if _GNU_SOURCE is defined; glibc also defines (the BSD-derived) sig_t if _BSD_SOURCE (glibc 2.19 and earlier) or _DEFAULT_SOURCE (glibc 2.19 and later) is defined. Without use of such a type, the declaration of signal() is the somewhat harder to read: 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 方式を提供している。 * By default, in glibc 2 and later, the signal() wrapper function does not invoke the kernel system call. Instead, it calls sigaction(2) using flags that supply BSD semantics. This default behavior is provided as long as a suitable feature test macro is defined: _BSD_SOURCE on glibc 2.19 and earlier or _DEFAULT_SOURCE in glibc 2.19 and later. (By default, these macros are defined; see feature_test_macros(7) for details.) If such a feature test macro is not defined, then signal() provides System V semantics.
関連項目
kill(1), alarm(2), kill(2), pause(2), sigaction(2), signalfd(2), sigpending(2), sigprocmask(2), sigsuspend(2), bsd_signal(3), killpg(3), raise(3), siginterrupt(3), sigqueue(3), sigsetops(3), sigvec(3), sysv_signal(3), signal(7)
この文書について
この man ページは Linux man-pages プロジェクトのリリース 5.10 の一部である。プロジェクトの 説明とバグ報告に関する情報は https://www.kernel.org/doc/man-pages/ に書かれている。