본문 바로가기
dev, tech

SIGACTION

by 구띵 2006. 12. 27.

SIGACTION

Section: Linux Programmer's Manual (2)
Updated: 8 May 1999
Index
Return to Main Contents
 

이름

sigaction, sigprocmask, sigpending, sigsuspend - POSIX 시그널 처리 함수 

사용법

#include <signal.h>

int sigaction(intsignum, const struct sigaction *act,struct sigaction *oldact);

int sigprocmask(inthow, const sigset_t *set,sigset_t *oldset);

int sigpending(sigset_t *set);

int sigsuspend(const sigset_t *mask); 

설명

sigaction시스템 호출은 특정 시그널이 수신되었을 때, 프로세스가 취할 액션을 변경하는데 사용된다.

signum는 시그널을 가리키며,SIGKILLSIGSTOP를 제외한 모든 시그널 값이 될 수 있다.

act가 null이 아닐 때, 시그널signum에 대한 새로운 액션은act가 되며,oldact이 null이 아닐 때, 기존의 액션은oldact에 저장된다.

sigaction구조는 다음과 같이 정의된다.

struct sigaction {    void (*sa_handler)(int);    void (*sa_sigaction)(int, siginfo_t *, void *);    sigset_t sa_mask;    int sa_flags;    void (*sa_restorer)(void);}

아키텍쳐에 따라 공용체로 되어 있기도 하므로,sa_handlersa_sigaction을 모두 지정하지 말라.

sa_restorer요소는 쓰이지 않으며, 사용되어서는 안된다. POSIX는sa_restorer요소를 갖지 않는다.

sa_handlersignum시그널이 오면 실행되는 액션을 명시하며, 디폴트 액션을 취하라는SIG_DFL, 시그널을 무시하라는SIG_IGN, 시그널을 처리하는 특정 함수에 대한 포인터 중의 하나가 될 수 있다. 세번째의 경우 시그널 처리 함수는 시그널 번호만을 유일한 인수로 갖는다.

sa_sigaction또한signum시그널과 연결된 액션을 명시한다. 처리 함수는 시그널 번호를 첫번째 인수로,siginfo_t에 대한 포인터를 두번째 인수로, 그리고 void형 포인터로 캐스트된ucontext_t에 대한 포인터를 세번째 인수로 갖는다.

sa_mask는 시그널 핸들러의 실행 동안 블록화되어야 하는 시그널의 마스크를 제공한다. 또한,SA_NODEFER또는SA_NOMASK이 사용되지 않으면, 핸들러를 시동시켰던 그 시그널도 블록화된다.

sa_flags는 시그널 처리 프로세스의 행위를 변경시키는 일련의 플래그들을 명시한다. 이는 bitwise 혹은 플래그는 아래 플래그 들의 0개 이상의 OR 비트 연산으로 만들어진다.

SA_NOCLDSTOP
signumSIGCHLD이면 자식 프로세스가 중지되어도 통지를 받지 않는다. (즉, 자식 프로세스들이SIGSTOP,SIGTSTP,SIGTTIN,SIGTTOU중 하나를 수신할 때)
SA_ONESHOT또는SA_RESETHAND
시그널 처리기가 호출되어 한번 실행된 후, 시그널 액션을 원래의 디폴트 액션으로 되돌려 놓는다. (이는signal(2) 호출에 대한 기본 행위이다.)
SA_RESTART
일부 시스템 호출들이 시그널을 통해 재시작할 수 있도록 함으로서 BSD 시그널과의 호환성을 제공한다.
SA_NOMASKorSA_NODEFER
어떤 시그널 처리기의 동작동안 그 시그널 자신을 막지 않는다.
SA_SIGINFO
시그널 처리기가 한 개가 아닌 3개의 인수를 취한다. 이 경우,sa_handler대신에sa_sigaction이 설정되어야 한다. (sa_sigaction 필드는 리눅스 2.1.86에서 추가되었다.)

sa_sigactionsiginfo_t변수는 다음의 요소들을 갖는 구조체(struct)이다.

siginfo_t {    int      si_signo;  /* 시그널 넘버 */    int      si_errno;  /* errno 값 */    int      si_code;   /* 시그널 코드 */    pid_t    si_pid;    /* 프로세스 ID 보내기 */    uid_t    si_uid;    /* 프로세스를 전송하는 실제 사용자 ID */    int      si_status; /* Exit 값 또는 시그널 */    clock_t  si_utime;  /* 소모된 사용자 시간 */    clock_t  si_stime;  /* 소모된 시스템 시간 */    sigval_t si_value;  /* 시그널 값 */    int      si_int;    /* POSIX.1b 시그널 */    void *   si_ptr;    /* POSIX.1b 시그널 */    void *   si_addr;   /* 실패를 초래한 메모리 위치 */    int      si_band;   /* 밴드 이벤트 */    int      si_fd;     /* 파일 기술자 */}

si_signo,si_errno그리고si_code는 모든 시그널에 대해 정의되었다.kill(2), POSIX.1b 시그널과 SIGCHLD은si_pidsi_uid을 채운다.SIGCHLD은 또한si_status,si_utime,si_stime을 채운다.si_int그리고si_ptr는 POSIX.1b 시그널의 송신자에 의해 명시된다. 좀더 자세한 사항을 보려면,sigqueue(2) 을 참조하라. SIGILL, SIGFPE, SIGSEGV 그리고 SIGBUS은si_addr를 오류의 주소로 채운다. SIGPOLL 은si_bandsi_fd를 채운다.si_code는 왜 시그널이 보내졌는지에 대해 지시한다. 이는 bitmask가 아닌 값이다. 나올 수 있는 모든 시그널 값은 이 테이블에 나열되어 있다.

si_code
ValueSignal origin
SI_USERkill, sigsend or raise
SI_KERNELThe kernel
SI_QUEUEsigqueue
SI_TIMERtimer expired
SI_MESGQmesq state changed
SI_ASYNCIOAIO completed
SI_SIGIOqueued SIGIO
SIGILL
ILL_ILLOPCillegal opcode
ILL_ILLOPNillegal operand
ILL_ILLADRillegal addressing mode
ILL_ILLTRPillegal trap
ILL_PRVOPCprivileged opcode
ILL_PRVREGprivileged register
ILL_COPROCcoprocessor error
ILL_BADSTKinternal stack error
SIGFPE
FPE_INTDIVinteger divide by zero
FPE_INTOVFinteger overflow
FPE_FLTDIVfloating point divide by zero
FPE_FLTOVFfloating point overflow
FPE_FLTUNDfloating point underflow
FPE_FLTRESfloating point inexact result
FPE_FLTINVfloating point invalid operation
FPE_FLTSUBsubscript out of range
SIGSEGV
SEGV_MAPERRaddress not mapped to object
SEGV_ACCERRinvalid permissions for mapped object
SIGBUS
BUS_ADRALNinvalid address alignment
BUS_ADRERRnon-existant physical address
BUS_OBJERRobject specific hardware error
SIGTRAP
TRAP_BRKPTprocess breakpoint
TRAP_TRACEprocess trace trap
SIGCHLD
CLD_EXITEDchild has exited
CLD_KILLEDchild was killed
CLD_DUMPEDchild terminated abnormally
CLD_TRAPPEDtraced child has trapped
CLD_STOPPEDchild has stopped
CLD_CONTINUEDstopped child has continued
SIGPOLL
POLL_INdata input available
POLL_OUToutput buffers available
POLL_MSGinput message available
POLL_ERRi/o error
POLL_PRIhigh priority input available
POLL_HUPdevice disconnected

sigprocmask호출은 현재 블록화된 시그널들을 변경시키는데 사용된다. 호출은 지정된how값에 따라 다르게 동작한다.

SIG_BLOCK
set인수가 지정한 시그널 집합이 블록시킬 시그널 집합에 더해진다.
SIG_UNBLOCK
set에 포함된 시그널들이 블록시킬 시그널들의 집합에서 삭제된다. 블록하고 있지 않은 시그널을 삭제하려 해도 괜찮다.
SIG_SETMASK
블록화할 시그널 집합을set으로 설정한다.

oldset이 null이 아닐 때, 기존의 마스크 시그널 집합은oldset에 저장된다.

sigpending호출은 블록화에 막혀 기다리고 있는 시그널을 살펴볼 수 있도록 해준다. 기다리는 시그널들의 시그널 마스크는set내에 저장된다.

sigsuspend호출은 프로세스가 막고 있는 시그널 마스크를 지정한mask로 잠시 대체하고, 다음 시그널이 수신될 때까지 프로세스를 중지시킨다. 

반환값

sigaction,sigprocmask,sigpending는 성공하면 0을 실패하면 -1을 리턴한다.sigsuspend항상 -1을 리턴한다. 보통 에러EINTR과 함께.

에러

EINVAL
지정한 시그널이 부적절하다. 혹은 받을 수 없는SIGKILL또는SIGSTOP에 대한 액션을 변경하려고 했다.
EFAULT
act,oldact,set또는oldset이 프로세스의 메모리 영역이 아닌 곳을 가리키고 있다.
EINTR
시스템 호출이 인터럽트되었다.
 

주의

sigprocmask 호출로SIGKILL또는SIGSTOP을 블록화할 수 없다. 이런 명령은 무시된다.

POSIX에 따르면, 프로세스가kill()또는raise()함수가 만들어 낸 것이 아닌 GFPE, SIGILL, 혹은 SIGSEGV를 무시한 이후의 프로세스의 동작은 정의되지 않는다. 정수를 0으로 나눈 결과 또한 정의되지 않는다. 일부 아키텍쳐에선 0으로 나누기가 SIGFPE 시그널을 만들어 낼 것이다. (또한 가장 큰 음의 정수를 -1로 나누어도 SIGFPE를 생성할 수 있다.) 이 시그널을 무시하면 무한 루프를 초래할 수 있다.

POSIX 스펙은 오직SA_NOCLDSTOP만을 정의한다 . 다른sa_flags의 사용은 이식이 불가능하다.

SA_RESETHAND플래그는 동일한 이름의 SVr4 플래그와 호환가능하다.

SA_NODEFER플래그는 커널 1.3.9과 새로운 버전하에서 동일한 이름의 SVr4 플래그와 호환가능하다.

SVr4 호환성을 위한SA_RESETHANDSA_NODEFER이름들은 오직 라이브러리 버전 3.0.9 그리고 그 이후의 버전에서만 존재한다.

SA_SIGINFO플래그는 POSIX.1b에 의해서만 명시된다. 이에 대한 지원은 리눅스 2.2에 추가되었다.

sigaction현재 시그널 처리기에 쿼리를 하기 위해 널 두번째 인수로 호출될 수 있다. 이를 널 두번째 그리고 세번째 인수들로 이를 호출함으로서 현재 머신에 대한 주어진 시그널이 타당한가를 체크하는데 사용될 수 있다.

시그널 체계 조작에 대한 자세한 정보를 얻으려면,sigsetops(3) 을 참조하라. 

호환

POSIX, SVr4. SVr4 는 EINTR 조건에 대한 문서를 제공하지 않는다. 

관련 항목

kill(1),kill(2),killpg(2),pause(2),raise(3),siginterrupt(3),signal(2),signal(7),sigsetops(3),sigvec(2) 

번역

ASPLINUX <man@asp-linux.co.kr> 2000년 7월 29일
한글 Manpage 프로젝트 (http://man.kldp.org) 2005년 2월 13일

댓글