리눅스 시스템 프로그래밍
#40 고급 시그널 처리
쿠리 Kuri
2022. 12. 1. 18:30
반응형
고급 시그널 관리
int sigaction(int signum, const struct sigaction *act,
struct sigaction *oldact);
파라미터
- signum : 대상 시그널 번호
- act : 시그널 처리 액션
- oldact : 기존 시그널 처리 액션
반환 값
- 성공 시 0
- 실패 시 -1
struct 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_flags 에 SA_SIGINFO 포함 시 sa_sigaction이 호출된다.
- sa_mask 는 시그널 핸들러 실행하는 동안 블록해야 할 시그널 모음 정의
sa_flags
flags | meaning |
SA_SIGINFO | sa_sigaction()이 사용된다. |
SA_NODEFER | 설정시 시그널 핸들러가 실행 중인 시그널에 대해 블록하지 않는다. |
SA_NOCLDSTOP | signo가 SIGCHLD인 경우 자식이 정지해도 SIGCHLD를 보내지 않도록 한다. |
SA_NOCLDWAIT | signo가 SIGCHLD인 경우 자식에 대한 자동처리 활성화(wait() 필요 없음) |
SA_RESETHAND | 시그널 핸들러가 1회면 동작한 후 default로 초기화 된다. |
SA_RESTART | read() 등의 시스템콜이 자동으로 재시작된다. |
siginfo_t 주요 필드
field | meaning |
si_signo | 시그널 번호 |
si_errno | 0이 아닌 경우 시그널과 관련된 에러 코드 |
si_code | 시그널을 일으킨 원인 |
si_int, si_ptr | sigqueue()를 통해 보낸 시그널 페이로드 |
si_addr | SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTRAP의 경우 장애를 일으킨 주소 |
si_fd | SIGPOLL의 경우 작업을 완료한 파일 디스크립터 |
모든 시그널 번호에 대해 유효한 si_code
si_code | meaning |
SI_ASYNCIO | 비동기식 입출력의 완료 표시 |
SI_KERNEL | 커널이 보낸 시그널 |
SI_MESGQ | POSIX 메시지 큐의 상태 변화 표시 |
SI_QUEUE | sigqueue()로 보낸 시그널 |
SI_TIMER | POSIX 타이머 만료를 표시 |
SI_USER | kill() 또는 raise()로 보낸 시그널 |
SIGCHLD인 경우에만 유효한 si_code
si_code | meaning |
CLD_CONTINUED | 자식이 정지되었다가 재시작됨 |
CLD_DUMPED | 자식이 비정상적으로 종료됨 |
CLD_EXITED | 자식이 exit()로 정상 종료됨 |
CLD_KILLED | 자식이 종료됨 |
CLD_STOPPED | 자식이 정지됨 |
CLD_TRAPPED | 자식이 트랩에 걸림 |
페이로드와 함께 시그널 전송
union sigval {
int sival_int;
void *sival_ptr;
};
int sigqueue(pid_t pid, int signo, const union sigval value);
파라미터
- pid : 대상 프로세스
- signo : 시그널 번호
- value : 페이로드
반환 값
- 성공 시 0
- 실패 시 -1
해당 시그널을 sigaction()으로 받으면
- siginfo_t.si_code : SI_QUEUE로 설정된다.
- siginfo_t.si_int : 페이로드가 설정된다.
반응형