wait和waitpid返回状态解析

wait和waitpid返回状态解析

众所周知,在shell中函数的返回状态或者退出码是一个介于0~255之间的数字,0表示命令执行成功,其他表示失败。但是我们在用wait或waitpid直接获取子进程的退出状态status却不是一个0~255的值,准确的说是一个int类型。那如何让我们自己写的程序表现的和shell的行为一致? 今天主要讲解和wait,waitpid相关的几个宏。

   WIFEXITED(status)
          returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().

   WEXITSTATUS(status)
          returns  the  exit  status of the child.  This consists of the least significant 8 bits of the status argument that the child specified in a
          call to exit(3) or _exit(2) or as the argument for a return statement in main().  This macro should be employed only if  WIFEXITED  returned
          true.

   WIFSIGNALED(status)
          returns true if the child process was terminated by a signal.

   WTERMSIG(status)
          returns  the  number  of  the signal that caused the child process to terminate.  This macro should be employed only if WIFSIGNALED returned
          true.

   WCOREDUMP(status)
          returns true if the child produced a core dump.  This macro should be employed only if WIFSIGNALED returned true.  This macro is not  speci‐
          fied  in  POSIX.1-2001 and is not available on some UNIX implementations (e.g., AIX, SunOS).  Only use this enclosed in #ifdef WCOREDUMP ...
          #endif.

   WIFSTOPPED(status)
          returns true if the child process was stopped by delivery of a signal; this is possible only if the call was done using  WUNTRACED  or  when
          the child is being traced (see ptrace(2)).

   WSTOPSIG(status)
          returns the number of the signal which caused the child to stop.  This macro should be employed only if WIFSTOPPED returned true.

大概解释一下:
1、WIFEXITED: 用于子进程正常退出,一般是子进程调用了exit 或 _exit,或者在main函数中return。
2、WEXITSTATUS: 返回子进程的退出码,该值为退出状态status的最低有效8位,其实就是子进程在exit、_exit或return时返回的值,被wait捕获存储在status中。这个宏当且仅当WIFEXITED在返回true中调用。这样我们就可以拿到一个0~255之间的值。
3、WIFSIGNALED: 代表子进程是否被信号终止。
4、WTERMSIG: 返回引起子进程终止的信号的对应num。这个宏当且仅当WIFSIGNALED返回true时调用。
5、WCOREDUMP: 判断子进程是否产生一个core dump。这个宏当且仅当WIFSIGNALED返回true时调用。这个在一些Unix平台上不可用,所以必须在#ifdef WCOREDUMP … #endif中使用。
6、WIFSTOPPED: 判断子进程是否被信号量暂停。
7、WSTOPSIG: 返回暂停子进程的信号量的值,当且仅当在WIFSTOPPED返回true时调用。

看代码:


	#include <stdio.h>
	#include <sys/types.h>
	#include <sys/wait.h>
	#include <stdlib.h>
	#include <unistd.h>
	#include <errno.h>
	#include <string.h>
	
	//C99 bring in this macros
	#define LOG_V(...) {\
	    fprintf(stderr,"%s: Line %d:\t",__FILE__,__LINE__);\
	    fprintf(stderr,__VA_ARGS__);\
	    fprintf(stderr,"\n");\
	}
	
	void err_sys(const char* info)
	{
	    LOG_V("error_info: %s, errno: %d, reason: %s",info,errno,strerror(errno));
	}
	
	void parse_exit(int status)
	{
	    if(WIFEXITED(status)){
	        LOG_V("normal termination, exit status = %d",WEXITSTATUS(status));
	    }else if(WIFSIGNALED(status)){
	        LOG_V("abnormal termination, signal number = %d,%s",WTERMSIG(status),
	#ifdef WCOREDUMP
	                WCOREDUMP(status) ? "core dump generated" : ""
	#else
	                ""
	#endif
	                );
	    }else if(WIFSTOPPED(status)){
	        LOG_V("child stopped, signal number = %d",WSTOPSIG(status));
	    }
	}
	
	
	int main(void)
	{
	    pid_t pid;
	    int status;
	    if((pid = fork()) < 0){
	        err_sys("fork error");
	    }else if(pid == 0){
	        exit(7); //child exit
	    }
	    if(wait(&status) != pid){
	        err_sys("wait error");        
	    }
	    parse_exit(status);
	
	    if((pid = fork()) < 0){
	        err_sys("fork error");
	    }else if(pid == 0){
	        abort(); //child generates SIGABRT
	    }
	    if(wait(&status) != pid){
	        err_sys("wait error");
	    }
	    parse_exit(status);
	
	    if((pid = fork()) < 0){
	        err_sys("fork error");
	    }else if(pid == 0){
	        status /= 0; //divide by 0,generates SIGFPE
	    }
	    if(wait(&status) != pid){
	        err_sys("wait error");
	    }
	    parse_exit(status);
	
	    exit(0);
	}

运行结果如下:

wait_exam.c: Line 24:   normal termination, exit status = 7
wait_exam.c: Line 32:   abnormal termination, signal number = 6,core dump generated
wait_exam.c: Line 32:   abnormal termination, signal number = 8,core dump generated

以前每次写程序时,用到这几个宏都要man 2 wait一下,今天索性做个笔记,加深一下理解和记忆。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值