Chapter 10(p.271~331)
terminate
프로세스 종료ignore
전달받은 시그널을 무시함 (SIGKILL, SIGSTOP는 catch 불가능하므로 제외)stop
프로세스 정지continue
프로세스 재개terminate w/ Core
종료 시, Core의 Memory Image를 Dump하여 커널에 보관한 후 종료함. 저장된 Memory Image는 디버깅 등에 이용된다.sigset_t
라는 구조체를 제공하는데, <sys/sygnal.h>에 정의되어 있으며, sigset_t
구조체는 크기가 4인 unsigned int 배열을 사용합니다.typedef struct {
unsigned int __sigbits[4];
} sigset_t;
함수 원형.
void ( *signal (int signo, void(*func)(int)) )(int)
2개 인자를 받고, void형 함수포인터를 리턴함.
첫번째 인자는 signo 정수, 두번째 인자는 함수포인터인데 int형 인자를 하나 받고 리턴하는게 없음
마지막도 int형 인자를 하나 받음
기능. 시그널을 받을 때 해당 시그널을 처리할 함수나 상수를 지정할 수 있습니다.
헤더.<signal.h>
매개변수1.int signo
시그널 번호(SIGKILL9, SIGSTOP19 제외)
매개변수2.void(*func)(int)
시그널을 처리할 핸들러로 아래 3가지 중 하나를 설정해야함
1.함수이름(시그널 핸들러의 주소)
시그널이 발생하면 지정된 함수를 호출한다.
2.SIG_IGN
시그널을 무시한다. (SIGKILL과 SIGSTOP은 무시할 수 없음)
3.SIG_DFL
기존 방법을 따른다.
리턴. (성공) 이전에 설정된 시그널 핸들러의 포인터를 리턴
(실패) SIG_ERR를 리턴
예시.
만약 두번째 인자가 함수 주소고,
signo가 SIGKILL(9), SIGTRAP(5), SIGPWR(30)이 아니라면,
signal 함수는 시그널을 처리한 후 시그널 처리 방법을 기본 처리 방법(SIG_DFL)로 재설정함.
따라서 시그널 처리를 계속하려면 signal 함수를 호출해 시그널을 처리한 후 다시 signal함수를 설정해야함.
#define 되어있음.#define SIG_ERR (void (*) ()) -1 //시그널로 반환되면 오류가 발생함 #define SIG_DFL (void (*) ()) 0 #define SIG_IGN (void (*) ()) 1
함수 원형.
int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact)
기능. signal()보다 향상된 기능을 제공하는, 시그널 처리를 결정하는 함수
헤더.<signal.h>
매개변수1.int signo
시그널 번호
매개변수2.const struct sigaction *act
시그널을 처리할 방법을 지정한 구조체 주소
매개변수3.struct sigaction *oldact
기존에 시그널을 처리하던 방법을 저장할 구조체 주소. 보통 NULL값을 사용함 (새로운 행동인 act가 등록되면서 기존의 행동은 oldact에 저장됨)
리턴. (성공) 0, (실패) -1
signal()에서는 처리할 행동 정보로 시그널이 발생하면 호출이 될 함수포인터를 넘겨주었음. 그러나 sigaction()에서는 struct sigaction 구조체 값을 사용해서 좀 더 다양한 지정이 가능함.
struct sigaction {
void (*sa_handler)(int);
//시그널을 처리하기 위한 핸들러(SIG_DFL/SIG_IGN/핸들러함수)
void (*sa_sigaction)(int, siginfo_t *, void *);
//sa_handler 대신에 사용할 수 있고 sa_handler에 비해 추가 정보를 알 수 있음 (둘 중 하나만 사용)
//sa_flags = SA_SIGINFO 여야함
//int는 signo, siginfo_t*는 시그널이 발생한 원인을 담은 구조체 포인터
//void * 시그널이 전달될 때 시그널을 받는 프로세스의 내부 상태를 나타내는 ucontext_t 구조체 포인터
sigset_t sa_mask;
//시그널 마스크: 봉쇄된 시그널들의 집합
//sa_mask에 등록된 시그널은 시그널 핸들러가 실행되는 동안 봉쇄됨
//봉쇄(blocking): 무시가 아니라, 시그널 핸들러 실행이 완료될 때까지 처리가 미뤄짐.
//현재 처리 중인 시그널도 봉쇄됨
int sa_flags;
//시그널 처리 절차를 수정하는데 사용됨
//여러 플래그를 사용하고 싶으면 '|'(OR연산자) 사용
}
값 | 의미 |
---|---|
SA_SIGINFO | sa_handler 대신에 sa_sigaction을 선택함. sa_sigaction이 받는 인수에는 시그널 번호, 시그널이 만들어지는 이유, 시그널을 받은 프로세스의 정보 등 확인 가능함 |
SA_NOCLDSTOP | signo가 SIGCHILD일 때, 자식 프로세스가 종료되거나 중단되더라도 부모 프로세스는 이를 알려고 하지 않음 |
SA_RESETHAND | signo에 대해서 시그널 핸들러를 최초에 한번만 실행하고, 그 다음부터는 동일한 시그널에 대해서 SIG_DFL에 해당하는 기본적인 동작만 수행함 |
SA_NODEFER | 시그널 핸들러 내에서 시그널 받는 것을 금지하지 않음. 즉, 마스크를 사용하지 않음 |
함수 원형.
int sigemptyset(sigset_t *set)
기능. 시그널 집합 비우기
시스템에서 정의한 모든 시그널을 배제해 인자로 지정한 시그널 집합을 빈 집합으로 만듭니다. 즉, 시그널 집합의 모든 비트를 0으로 설정합니다.
헤더.signal.h
매개변수1.sigset_t *set
시그널 집합
리턴. (성공) 0, (실패) -1
함수 원형.
int sigfillsetsigset_t *set)
기능. 시그널 집합에 모든 시그널 설정
인자로 받은 시그널 집합을 시스템에서 정의한 모든 시그널을 포함하는 집합으로 만듭니다. 즉, 시그널 집합의 모든 비트를 1로 설정합니다.
헤더.signal.h
매개변수1.sigset_t *set
시그널 집합
리턴. (성공) 0, (실패) -1
함수 원형.
int sigaddset(sigset_t *set, int signo)
기능. 시그널 집합에 시그널 설정 추가
signo로 정의한 시그널을 set로 지정한 시그널 집합에 추가합니다.
헤더.signal.h
매개변수1.sigset_t *set
시그널 집합
매개변수2int signo
리턴. (성공) 0, (실패) -1
함수 원형.
int sigdelset(sigset_t *set, int signo)
기능. 시그널 집합에 시그널 설정 삭제
signo로 정의한 시그널을 set로 지정한 시그널 집합에 제거합니다.
헤더.signal.h
매개변수1.sigset_t *set
시그널 집합
매개변수2int signo
리턴. (성공) 0, (실패) -1
함수 원형.
int sigismember(sigset_t *set, int signo)
기능. 시그널 집합에 설정된 시그널 확인
signo로 정의한 시그널이 set로 지정한 시그널 집합에 포함되어 있는지 확인
헤더.signal.h
매개변수1.sigset_t *set
시그널 집합
매개변수2int signo
리턴. (signo가 set에 속하면) 1
(signo가 set에 속하지 않으면) 0
(오류 시) -1
sigaction 구조체 내 두번째 인자
siginfo_t {
int si_signo; /* 시그널 넘버 */
int si_errno; /* 에러 넘버 */
int si_code; /* 시그널 발생 이유 */
int si_trapno; /* 하드웨어 송신 시그널의 트랩넘버
(대부분 아키텍처에서 사용 x)*/
pid_t si_pid; /* 시그널을 보낸 프로세스의 pid */
uid_t si_uid; /* 시그널을 보낸 프로세스의 effective user id */
int si_status; /* EXIT 값 혹은 시그널 */
clock_t si_utime; /* 소요된 User time */
clock_t si_stime; /* 소요된 System time */
union sigval si_value; /* 시그널 발생시 전달할 값 */
int si_int; /* POSIX.1b signal */
void *si_ptr; /* POSIX.1b signal */
int si_overrun; /* Timer overrun count;
POSIX.1b timers */
int si_timerid; /* Timer ID; POSIX.1b timers */
void *si_addr; /* Memory location which caused fault */
long si_band; /* Band event (was int in
glibc 2.3.2 and earlier) */
int si_fd; /* File descriptor */
short si_addr_lsb; /* Least significant bit of address
(since Linux 2.6.32) */
void *si_lower; /* Lower bound when address violation
occurred (since Linux 3.19) */
void *si_upper; /* Upper bound when address violation
occurred (since Linux 3.19) */
int si_pkey; /* Protection key on PTE that caused
fault (since Linux 4.6) */
void *si_call_addr; /* Address of system call instruction
(since Linux 3.5) */
int si_syscall; /* Number of attempted system call
(since Linux 3.5) */
unsigned int si_arch; /* Architecture of attempted system call
(since Linux 3.5) */
}
안녕하세요. 정리를 굉장히 잘해놓으신 덕분에 c언어 함수들을 익히는데 큰 도움을 받고 있습니다. 거의, 메뉴얼 급으로 설명과 예시가 잘 정리되었네요. 감사합니다.