SIGACTION(2)

명칭
sigaction - 소프트웨어 시그널 기능

프로그램 라이브러리
libc

서식
<signal.h>

    struct sigaction {
    	/*
    	 * SA_SIGINFO 플래그가 사용되어 있지 않은 경우의
    	 * SIG_DFL 및 SIG_IGN 용의 시그널 핸들러 함수
    	 */
    	void     (*sa_handler)(int);
    	/* SA_SIGINFO 플래그를 사용하는 경우의 시그널 핸들러 함수 */
    	void     (*sa_sigaction)(int, siginfo_t *, void *);
    	sigset_t sa_mask;            /* 적용하는 시그널 마스크 */
    	int	 sa_flags;           /* 후술의 시그널 옵션 참조 */
    };

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

해설
시스템에서는 시그널의 집합을 정의하고 있어, 이것들은 프로세스에 전달되는 일이 있습니다. 시그널의 전달은, 하드웨어 새치기의 발생을 닮아 있습니다. 통상의 경우, 시그널의 새로운 발생은 블록 되어 현재의 프로세스 문맥은 보존되어, 새로운 프로세스 문맥이 작성됩니다. 프로세스는, 시그널의 전달처 handler (을)를 지정하는 일도 있으면, 시그널을 무시 하는 것을 지정하는 일도 있습니다. 시그널이 발생했을 경우에, 시스템이 디폴트의 액션을 잡는다 일을 지정하는 일도 가능합니다. 시그널이 블록 되는 일도 있어, 그 경우, 시그널의 전달은, 블록이 해제 될 때까지 연기됩니다. 전달시에 취하는 액션은, 전달시에 정해집니다. 통상의 경우는, 시그널 핸들러가, 프로세스의 현행 스택으로 동작합니다. 이것은 핸들러 마다 변경 가능하고, 변경하면, 시그널은 특수한 시그널 스택 그리고 실행 가능합니다.

통상의 경우, 시그널 routine는, 호출의 원인이 된 시그널이 블록 된 상태로 동작합니다만, 그 외의 시그널이 발생할 가능성은 있습니다. 글로벌의 시그널 마스크 에는, 프로세스에의 전달이 현재 블록 되고 있는 시그널의 집합이 정의되고 있습니다. 프로세스의 시그널 마스크는, 부모의 시그널 마스크로 초기화됩니다 (통상은 하늘). sigprocmask(2) 하지만 불려 갔을 경우, 또는 시그널이 프로세스에 전달되었을 경우에, 시그널 마스크는 변경됩니다.

어느 시그널의 발생 조건이 프로세스로 발생하면(자), 그 시그널이, 프로세스로 보류중의 시그널의 집합에 추가됩니다. 그 시그널이 프로세스로 현재 블록 되어 있지 않은 경우는, 프로세스에 전달됩니다. 시그널은, 프로세스가 operating system에 들어가 있는 동안에 (시스템 호출해, 페이지 에러나 트랩, 클락 새치기중 등에) 전달됩니다. 복수의 시그널의 전달 준비가 동시에 갖추어졌을 경우는, 트랩으로 생긴 시그널이 먼저 전달됩니다. 그 외의 시그널은, 각각이 전의 시그널의 핸들러에 대해, 최초의 인스트럭션의 전에 끼어든 상태로 동시에 처리됩니다. 보류가 되어 있는 시그널의 집합은, sigpending(2) 함수로 돌려주어집니다. 포착된 시그널이 전달되면(자), 프로세스의 현재의 상태가 보존되어 새로운 시그널 마스크가 이하로 설명하도록(듯이) 산출되어, 시그널 핸들러가 불려 갑니다. 핸들러의 호출은, 시그널 처리 routine가 정상적으로 돌아왔을 경우에, 프로세스가 시그널 전달전의 문맥으로 실행을 재개하도록(듯이) 설정됩니다. 프로세스가 다른 문맥에서의 재개를 바라는 경우는, 전의 문맥 그 자체를 자기 자신으로 회복하도록(듯이) 설정할 필요가 있습니다.

시그널이 프로세스에 전달되면(자), 프로세스의 시그널 핸들러의 실행이 계속되는 동안 (또는 sigprocmask() 하지만 불려 갈 때까지), 새로운 시그널 마스크가 설치됩니다. 이 마스크는, 현재의 시그널 마스크 집합, 전달되는 시그널, 불려 가는 핸들러에 관련한 시그널 마스크의 화집합을 취해 형성됩니다.

sigaction() (은)는, sig 그리고 지정한 시그널의 액션을 할당합니다. act 하지만 0 이 아닌 경우는, 액션 (SIG_DFL, SIG_IGN 인가 핸들러 routine), 및 지정된 시그널의 전달시에 사용하는 마스크가 지정됩니다. oact 하지만 0 이 아닌 경우는, 그 시그널의 지금까지의 처리 정보가 유저에게 돌려주어집니다.

시그널 핸들러가 설치되면(자), 통상의 경우는 sigaction() (을)를 재차 호출할까 execve(2) (을)를 실행할 때까지, 그 시그널 핸들러는 설치된대로 입니다. sa_handler (을)를 SIG_DFL (으)로 설정하는 것으로, 시그널 마다 고유한 디폴트 액션에 리셋트 할 수가 있습니다. 디폴트란, 프로세스의 종료 (코어덤프가 놓치는 일도 있습니다), 액션 이루어, 프로세스의 정지, 프로세스의 계속입니다. 각각의 시그널의 디폴트 액션에 대해서는, 아래와 같은 시그널 리스트를 참조해 주세요. sa_handler 하지만 SIG_DFL 인 경우, 시그널의 디폴트 액션은 시그널의 파기가 됩니다. 또, 시그널이 보류가 되어 있는 경우에서도, 시그널이 마스크 되고 있어도 보류중의 시그널은 파기됩니다. sa_handler (을)를 SIG_IGN (으)로 설정하면(자), 현재의 시그널 실체와 보류중의 시그널 실체는 무시되어 파기됩니다.

옵션은, sa_flags (을)를 설정하는 것으로 지정할 수 있습니다. 각각의 비트의 의미는 이하대로입니다.

SA_NOCLDSTOP
    SIGCHLD 시그널의 수신 함수를 설치하는 경우에 이 비트를 설정하면(자), child process가 정지했을 때가 아니고, child process가 종료할 경우에 마셔, SIGCHLD 시그널이 생성됩니다.

SA_NOCLDWAIT
    SIGCHLD 시그널로 sigaction() (을)를 호출하는 경우에 이 비트를 설정하면(자), 시스템은, 호출측 프로세스의 child process가 종료했을 때에 좀비 프로세스를 작성하지 않게 됩니다. 그 후, 호출측 프로세스가 wait(2) 인가 거기에 상당하는 함수를 실행하면(자), 호출측 프로세스의 모두 의 child process가 종료할 때까지 블록 해, 다음에 errno (을)를 ECHILD (으)로 설정해 -1 를 돌려줍니다.

SA_ONSTACK
    이 비트를 설정하면(자), 시스템은, sigaltstack(2) 그리고 지정되었다 시그널 스택 의 위에서, 프로세스에 시그널을 전달합니다.

SA_NODEFER
    이 비트를 설정하면(자), 전달이 끝난 시그널의 새로운 발생이, 핸들러의 실행중에 마스크 되지 않게 됩니다.

SA_RESETHAND
    이 비트를 설정하면(자), 시그널이 전달된 순간에, 핸들러가 SIG_DFL 에 리셋트 됩니다.

SA_SIGINFO
    이 비트가 설정되어 있는 경우, 핸들러 함수는, sigaction 구조체의 sa_sigaction 멤버가 가리키는 것과 봅니다. 핸들러 함수는, 먼저 가리킨 prototype 혹은 다음에 가리킨다 사용예 에 일치하지 않으면 안됩니다. 이 비트는, 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) 의 다음에는, 모든 시그널, 시그널 마스크, 시그널 스택, 재개 플래그, 새치기 플래그가 child process에 계승됩니다.

execve(2) (은)는, 포착되고 있던 모든 시그널의 디폴트 액션을 바탕으로 되돌려, 모든 시그널을 유저스택으로 수신되도록(듯이) 리셋트 합니다. 무시된 시그널은 무시된대로 입니다. 시그널 마스크는 같은 상태인 채입니다. 보류중의 시스템 콜을 재개하는 설정의 시그널은, 그 재개의 설정인 채입니다.

이하는 모든 시그널의 리스트입니다. 명칭은, 인클루드 파일 <signal.h> 에 있는 것 것과 같습니다.
명칭 디폴트 액션 설명
SIGHUP | 프로세스의 종료 | 단말 라인의 행업
SIGINT | 프로세스의 종료 | 프로그램의 새치기
SIGQUIT | core image의 작성 | 프로그램의 중단 종료
SIGILL | core image의 작성 | 부정한 인스트럭션
SIGTRAP | core image의 작성 | 트랩의 트레이스
SIGABRT | core image의 작성 | abort(3)
의 호출 (이전의 SIGIOT)
SIGEMT | core image의 작성 | 인스트럭션 실행의 에뮤레이트
SIGFPE | core image의 작성 | 부동 소수 예외
SIGKILL | 프로세스의 종료 | 프로그램의 강제 종료
SIGBUS | core image의 작성 | 버스 에러
SIGSEGV | core image의 작성 | 분할 위반
SIGSYS | core image의 작성 | 존재하지 않는 시스템 콜의 호출
SIGPIPE | 프로세스의 종료 | 읽기측이 없는 파이프에의 기록
SIGALRM | 프로세스의 종료 | 리얼타임 타이머의 만료
SIGTERM | 프로세스의 종료 | 소프트웨어 종료 시그널
SIGURG | 시그널의 파기 | 긴급 상황이 소켓에 발생
SIGSTOP | 프로세스의 정지 | 정지 (포착도 무시도 할 수 없습니다)
SIGTSTP | 프로세스의 정지 | 키보드로부터 생성된 정지 시그널
SIGCONT | 시그널의 파기 | 정지 후의 계속
SIGCHLD | 시그널의 파기 | child process 상태 변화
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()

위의 리스트에 기재되지 않은 모든 함수는, 시그널에 관해서 안전하지 않다 (이)라고 생각됩니다. 즉, 그러한 함수가 시그널 핸들러로부터 불려 갈 때의 동작은, 미정도리입니다.

반환값

사용예
핸들러가 일치할 가능성이 있는 prototype는 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_SIGINFO 비트가 설정되어 있는 경우, 핸들러 함수는 SA_SIGINFO prototype에 일치하지 않으면 안됩니다. 그 경우, sigaction 구조체의 sa_sigaction 멤버가 핸들러 함수를 가리키지 않으면 안됩니다. 이 방법으로 SIG_DFL 혹은 SIG_IGN 를 할당해선 안 되는 것에 주의해 주세요.

SA_SIGINFO 플래그가 설정되어 있지 않은 경우, 핸들러 함수는 ANSI C 혹은 전통적인 BSD prototype의 어딘가에 일치하지 않으면 안되어, sigaction 구조체의 sa_handler 멤버가 핸들러 함수를 별로 있지 않으면 안됩니다. 실제로는, FreeBSD (은)는 항상 후자이다 BSD prototype의 3 개의 인수를 보내고, ANSI C prototype는 그 부분집합이 되어 있기 때문에, 어디라도 동작합니다. 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 인수는 sigcontext 구조체의 인스턴스를 가리키고 있습니다.

POSIX SA_SIGINFO 핸들러의 uap 인수는, ucontext_t 의 인스턴스를 가리키고 있습니다.

에러
이하중 1 개(살)이 발생하면(자), sigaction() (은)는 에러가 되어, 새로운 시그널 핸들러는 설치되지 않습니다.

[EFAULT]
    act 인가 oact (은)는, 프로세스에 할당할 수 있었던 address 공간의 범위외를 가리키고 있습니다.

[EINVAL]
    sig 하지만, 올바른 시그널 번호가 되어 있지 않습니다.

[EINVAL]
    SIGKILL 인가 SIGSTOP 의 핸들러를 무시할까 제공하려고 했습니다.

표준
sigaction() 함수 호출은, p1003.1-90 에 준거하고 있습니다. SA_ONSTACK 플래그와 SA_RESTART 플래그는, Berkeley 의 확장 기능입니다. SIGTRAP, SIGEMT, SIGBUS, SIGSYS, SIGURG, SIGIO, SIGXCPU, SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH, SIGINFO 시그널도 같습니다. 이러한 시그널은, BSD (으)로부터 파생한 시스템의 대부분으로 사용할 수 있습니다. SA_NODEFER 플래그와 SA_RESETHAND 플래그는, 그 외의 operating system와의 하위 호환성을 유지하기 위한 것입니다. SA_NOCLDSTOP 플래그와 SA_NOCLDWAIT 플래그는, 그 외의 operating system로 일반적으로 볼 수 있는 옵션입니다.

관련 항목
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)