시그널 처리

programming/C_C++ 2011. 8. 10. 17:53
반응형

시그널 처리


/* 프로그램 시그널 처리 설정 */
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;
}


 

반응형
Posted by 공간사랑
,