본문 바로가기

Programming/Linux_Kernel

wati(), wait4(), waitpid() 함수의 status 반환값


원문 : http://forum.falinux.com/zbxe/?mid=C_LIB&page=4&document_srl=408551

안그래도 strace 소스 분석하는데 status 에 따라 상당히 많은 분기문이 있어서 정확한 의미를 파악해야 했다. 이 문서가 상당히 많은 도움이 된다.


wati()나 waitpid()에서 자식 프로세스의 종료 상태를 확인하기 위해서 인수로 전달했던 변수 status 값을 직접 확인해야 했습니다. 이값은 아래와 같이 값이 구성된다고 했지만 앞으로 시스템이 발전하면, 이와 같은 내용이 바뀌지 않는다는 보장이 없습니다. 즉, 8비트 2개에서 16비트 2개로 늘려질 수 있다는 것이죠.

8비트 8비트
정상 종료 프로세스 반환 값 0
비정상 종료 0 종료 시킨 시그널 번호

또한 직접 비트를 이동하거나 확인하는 것 보다는 조금 더 편리한 방법이 있었으면 좋겠습니다. 즉, 컴파일러 버저업 걱정을 없애고 더 편리한 방법 말이죠. 이를 위해 wait.h에는 아래와 같은 매크로를 준비해 놓았습니다.

매크로 설명
WIFEXITED( status) 자식 프로세스가 정상적으로 종료되었다면 TRUE
WIFSIGNALED( status) 자식 프로세스가 시그널에 의해 종료되었다면 TRUE
WIFSTOPPED( status) 자식 프로세스가 중단되었다면 TRUE
WEXITSTATUS( status) 자식 프로세스가 정상 종료되었을 때 반환한 값

이 매크로는 컴파일러에 따라 변경되므로 버전업했을 때의 문제점을 피할 수 있고, status >> 8과 같은 코드 보다는 WEXITSTATUS( status)와 같이 사용하는 것이 가독성에도 좋아 디버깅에도 유리합니다.

이 매크로를 사용하면 아래와 같이 코드를 수정할 수 있습니다.

// 정상 종료를 확인하는 코드는 다음과 같이 수정할 수 있습니다.
if ( 255 < status)  ->     if ( WIFEXITED( status))
   
// 자식이 반환한 코드를 아래와 같이 바꿀 수 있습니다.   
status >> 8    ->    WEXITSTATUS( status)
            
헤더 wait.h
예제
#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
   int   counter  = 1;
   int   status;
   pid_t pid;
   pid_t pid_child;

   pid   = fork();

   switch( pid)
   {
      case -1  :
      {
         printf( "자식 프로세스 생성 실패n");
         return -1;
      }
      case 0   :
      {
         printf( "저는 자식 프로세스로 5까지 카운트하고 종료하겠습니다.n");
         while( 6 > counter )
         {
            printf( "자식: %dn", counter++);
            sleep( 1);
         }
         return 99;
      }
      default  :
      {
         printf( "저는 부모 프로세스로 자식 프로세스 작업이 
끝날 때 까지 대기합니다..n");

         pid_child   = wait( &status);

         printf( "종료된 자식 프로세스 ID는 %d이며,", pid_child);
         if ( WIFEXITED( status))
         {
            printf( "정상적으로 종료되었고 반환값은 %d입니다n", WEXITSTATUS( status));
         }
         else
         {
            printf( "비 정상으로 종료되었고 종료 시그널 번호는 %d입니다n", status);
         }
         printf( "이제 제일을 처리하겠습니다.n");

         while( 1 )
         {
            printf( "부모: %dn", counter++);
            sleep( 1);
         }
      }
   }
}
]$ ./a.out
저는 자식 프로세스로 5까지 카운트하고 종료하겠습니다.
자식: 1
저는 부모 프로세스로 자식 프로세스 작업이 끝날 때 까지 대기합니다..
자식: 2
자식: 3
자식: 4
자식: 5
종료된 자식 프로세스 ID는 5484이며,정상적으로 종료되었고 반환값은 99입니다
이제 제일을 처리하겠습니다.
부모: 1
부모: 2
부모: 3
부모: 4
부모: 5
부모: 6
부모: 7
부모: 8

'Programming > Linux_Kernel' 카테고리의 다른 글

fallocate system call  (0) 2008.11.20
wait 를 이용한 프로세스 종료 상태  (0) 2008.11.17
Playing with ptrace, Part I  (0) 2008.11.14
Playing with ptrace, Part II  (0) 2008.11.14
paper on debugging kernel oops or hang  (0) 2008.11.12