signal - システムコールの説明 - Linux コマンド集 一覧表
名前
signal - ANSI C シグナル操作
書式
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int
signum
, sighandler_t
sighandler
);
説明
signal
()システム・コールは
signum
で指定された番号のシグナルに
新しいシグナル・ハンドラーを設定する。
このシグナル・ハンドラーは
sighandler
に設定される。
sighandler
は、ユーザーの指定した関数、
SIG_IGN
、
SIG_DFL
のいずれかである。
シグナル番号
signum
のシグナルを受けると次のように動作する。
対応するハンドラーが
SIG_IGN
に設定されている場合は、シグナルは無視される。
ハンドラーが
SIG_DFL
に設定されている場合は、シグナルに関連づけられた
デフォルトの動作を行う
(
signal
(7)を参照)。
ハンドラーが関数
sighandler
に設定されている場合は、まず最初にハンドラーが SIG_DFL にリセットされ
(あるいは実装に依存するシグナルのブロックが実行され)、
次に
signum
を引き数として
sighandler
が呼ばれる。
シグナルに対してシグナルハンドラー関数を使うことは、
「シグナルのキャッチ」と呼ばれる。
シグナル
SIGKILL
と
SIGSTOP
はキャッチできず、無視することもできない。
返り値
signal ()関数は今までのシグナル・ハンドラーの値を返すか、エラーの場合は SIG_ERR を返す。
移植性
Unix のオリジナルの
signal
()はハンドラーを SIG_DFL にリセットする。
System V (と Linux カーネルと libc4,5) も同じである。
一方、BSD ではハンドラーのリセットを行わず、
ハンドラーが呼ばれている間に
シグナルの新しいインスタンスが発生するのをブロックする。
glibc2 ライブラリでは BSD の動作に従っている。
libc5 システムにおいて
"<signal.h>"
のかわりに
"<bsd/signal.h>"
をインクルードすると、
signal
()は
__bsd_signal
に再定義されて BSD 方式となる。
これは推奨されない。
glibc2 システムにおいて
_XOPEN_SOURCE
のような機能検査マクロを定義したり、この関数とは別の
sysv_signal
関数を使ったりすれば、以前のような動作をする。
これは推奨されない。
マクロの定義やファイルのインクルードで
この関数の方式を変更しようとするのは、良くない考え方である。
signal
()を使うのを完全に避けて、代わりに
sigaction
(2) を使った方が良い。
注意
マルチスレッドプロセスにおけるこの関数の結果は、指定されていない。
他の場所での処理が任意の箇所で割り込まれるため、
ルーチン
handler
は非常に注意しなければならない。
POSIX には「安全な関数」という概念がある。
シグナルが安全でない関数に割り込み、
かつ
handler
がその安全でない関数を呼び出していた場合、その挙動は未定義である。
安全な関数は様々な規格に明確にリストされている。
POSIX.1-2003 でのリストは以下の通りである:
_Exit()
_exit()
abort()
accept()
access()
aio_error()
aio_return()
aio_suspend()
alarm()
bind()
cfgetispeed()
cfgetospeed()
cfsetispeed()
cfsetospeed()
chdir()
chmod()
chown()
clock_gettime()
close()
connect()
creat()
dup()
dup2()
execle()
execve()
fchmod()
fchown()
fcntl()
fdatasync()
fork()
fpathconf()
fstat()
fsync()
ftruncate()
getegid()
geteuid()
getgid()
getgroups()
getpeername()
getpgrp()
getpid()
getppid()
getsockname()
getsockopt()
getuid()
kill()
link()
listen()
lseek()
lstat()
mkdir()
mkfifo()
open()
pathconf()
pause()
pipe()
poll()
posix_trace_event()
pselect()
raise()
read()
readlink()
recv()
recvfrom()
recvmsg()
rename()
rmdir()
select()
sem_post()
send()
sendmsg()
sendto()
setgid()
setpgid()
setsid()
setsockopt()
setuid()
shutdown()
sigaction()
sigaddset()
sigdelset()
sigemptyset()
sigfillset()
sigismember()
signal()
sigpause()
sigpending()
sigprocmask()
sigqueue()
sigset()
sigsuspend()
sleep()
socket()
socketpair()
stat()
symlink()
sysconf()
tcdrain()
tcflow()
tcflush()
tcgetattr()
cgetpgrp()
tcsendbreak()
tcsetattr()
tcsetpgrp()
time()
timer_getoverrun()
timer_gettime()
timer_settime()
times()
umask()
uname()
unlink()
utime()
wait()
waitpid()
write().
POSIX によると、 kill (2) や raise (3) 関数で生成できない SIGFPE , SIGILL , SIGSEGV シグナルを無視した後の動作は未定義である。 0 による整数割り算の結果は未定義となる。 ある種のアーキテクチャーでは、これは SIGFPE シグナルを生成する。 (同様に負の最大整数を -1 で割ると SIGFPE が生成されるかもしれない。) このシグナルを無視すると無限ループに陥るかもしれない。
SIGCHLD の動作として SIG_IGN を設定した場合の詳細な動作については、 sigaction (2) を参照すること。
sighandler_t の使用は GNU 拡張である。 各種バージョンの libc でこの型は定義済みである; libc4 と libc5 では SignalHandler を定義している。 glibc では sig_t を定義しており、 _GNU_SOURCE が定義されている場合には sighandler_t も定義されている。
準拠
C89, POSIX.1-2001.