Provided by: manpages-ja-dev_0.5.0.0.20180315+dfsg-1_all bug

名前

       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_IGNSIG_DFL、 プログラマが定義した関数 (「シグナルハンドラー」) のアドレスの  いずれかを指定す
       る。

       シグナル signum がプロセスに配送されると、以下のいずれかが発生する。

       *  処理方法が SIG_IGN に設定されている場合、そのシグナルは無視される。

       *  処理方法が  SIG_DFL に設定されている場合、シグナルに関連づけられた デフォルトの動作が行
          われる (signal(7)  参照)。

       *  処理方法として関数が設定されている場合、 まず最初に処理方法が SIG_DFL  にリセットされる
          かそのシグナルのブロックが実行された後、 signum を引き数として handler が呼び出される。
          ハンドラーが起動される際にシグナルがブロックされた場合、 ハンドラーが返る際にそのシグナ
          ルのブロックが解除される。

       シグナル SIGKILLSIGSTOP は捕捉できず、無視することもできない。

返り値

       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_DFLSIG_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/ に書かれている。