시그널 처리
/* 프로그램 시그널 처리 설정 */
void SetSignal()
{
sigset_t set;
struct sigaction act;
sigfillset(&set);
sigprocmask(SIG_SETMASK, &set, NULL);
memset(&act, 0x00, sizeof(act));
sigfillset(&act.sa_mask);
/* 무시할 신호 목록 */
act.sa_handler = SIG_IGN;
/* 파이프 디스크립터 오류 발생시 Listener 가 죽는 것은 방지하기 위하여 설정 */
sigaction( SIGPIPE, &act, NULL);
/* Process를 기동시킨 관리자의 로그아웃시 발생 시그널 */
sigaction( SIGHUP , &act, NULL);
/* ^C 키를 누른 경우 받는 신호 => demon 으로 기동되기 땜시 이 신호 못받음 */
sigaction( SIGINT , &act, NULL);
/* 키보드에 의한 Abort 신호 처리 => ? */
sigaction( SIGQUIT, &act, NULL);
/* SIGCHLD 신호를 처리합시다. */
act.sa_handler = SigChld;
sigaction( SIGCHLD, &act, NULL);
/* 각종 에러나 사용자의 종료 신호 처리 */
act.sa_handler = SigTerm;
/* kill -TERM 에 의한 프로세스 종료시 */
sigaction( SIGTERM, &act, NULL);
sigaction( SIGBUS , &act, NULL); /* Access to undefined portion of a memory object */
sigaction( SIGFPE , &act, NULL); /* Erroneout arithmetic operation */
sigaction( SIGILL , &act, NULL); /* Illegal instruction */
sigaction( SIGSEGV, &act, NULL); /* Invalid memory reference */
sigaction( SIGSYS , &act, NULL); /* Bad System Call */
sigaction( SIGXCPU, &act, NULL); /* CPU-time limit exceeded */
sigaction( SIGXFSZ, &act, NULL); /* File-size limit exceeded */
sigemptyset(&set); /* 신호 처리기 처리 설정 위한 블록 해제 */
sigprocmask(SIG_SETMASK, &set, NULL);
}
// Process 종료시 호출 되는 함수.
static void SigTerm( int iSigNo)
{
// 정상 종료와 오류에 의한 종료로 구분한다.
if( iSigNo == SIGTERM)
fprintf(stderr, "Exit processing start by normal user signal");
else // 오류에 의한 종료인 경우.
fprintf(stderr, "Exit processing start by abnormal signal[%d]", iSigNo);
_exit(1);
}
// Child Process 즉 Handler 가 죽은 경우 호출되는 함수.
static void SigChld(int iSigNo)
{
pid_t killPid;
int killStatus;
while( (killPid = waitpid(-1, &killStatus, WNOHANG)) > 0 )
{
// Handler가 Signal에 의해 종료되었는지 검사하는 로직
if( WIFSIGNALED( killStatus ) )
{
fprintf(stderr, "Signal[SIG_CHLD] occured => PID[%d], Terminate Signal[%d]" , killPid, WTERMSIG(killStatus));
}
else
{
fprintf(stderr, "Signal[SIG_CHLD] occured => PID[%d], Terminate No Signal.", killPid);
}
}
// waitpid return error
if( killPid < 0)
{
int errorNum = errno;
fprintf(stderr, "Signal[SIG_CHLD] occured, But waitpid() return error[%d][%s] ""=> Unknown killed child PID", errorNum, strerror(errorNum));
}
return;
}