@n.m. .
chps (TLPI) , wait()/waitpid(), , int .
:
- 1 , wait()/waitpid(),
- 2 LSB,
:
event byte 1 byte 0
============================================================
* normal termination exit status (0 ~ 255) 0
* killed by signal 0 termination signal (!=0)
* stopped by signal stop signal 0x7F
* continued by signal 0xFFFF
*
:
header 'sys/wait.h', defines a set of macros that help to dissect a wait status,
macros:
* WIFEXITED(status)
return true if child process exit normally,
*
* WIFSIGNALED(status)
return true if child process killed by signal,
* WTERMSIG(status)
return signal number that terminate the process,
* WCOREDUMP(status)
returns ture if child process produced a core dump file,
tip:
this macro is not in SUSv3, might absent on some system,
thus better check whether it exists first, via:
#ifdef WCOREDUMP
// ...
#endif
*
* WIFSTOPPED(status)
return true if child process stopped by signal,
* WSTOPSIG(status)
return signal number that stopp the process,
*
* WIFCONTINUED(status)
return true if child process resumed by signal SIGCONT,
tip:
this macro is part of SUSv3, but some old linux or some unix might didn't impl it,
thus better check whether it exists first, via:
#ifdef WIFCONTINUED
// ...
#endif
*
wait_status_test.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/wait.h>
#define SLEEP_SEC 10
int wait_status_test() {
pid_t cpid;
switch(cpid=fork()) {
case -1:
printf("error while fork()\n");
exit(errno);
case 0:
sleep(SLEEP_SEC);
printf("child [%d], going to exit\n",(int)getpid());
_exit(EXIT_SUCCESS);
break;
default:
printf("parent [%d], child created [%d]\n", (int)getpid(), (int)cpid);
break;
}
int status;
int wait_flag = WUNTRACED | WCONTINUED;
while(1) {
if((cpid = waitpid(-1, &status, wait_flag)) == -1) {
if(errno == ECHILD) {
printf("no more child\n");
exit(EXIT_SUCCESS);
} else {
printf("error while wait()\n");
exit(-1);
}
}
printf("parent [%d], child [%d] ", (int)getpid(), (int)cpid);
if(WIFEXITED(status)) {
printf("exit normally with [%d]\n", status);
} else if(WIFSIGNALED(status)) {
char *dumpinfo = "unknow";
#ifdef WCOREDUMP
dumpinfo = WCOREDUMP(status)?"true":"false";
#endif
printf("killed by signal [%d], has dump [%s]\n", WTERMSIG(status), dumpinfo);
} else if(WIFSTOPPED(status)) {
printf("stopped by signal [%d]\n", WSTOPSIG(status));
#ifdef WIFCONTINUED
} else if(WIFCONTINUED(status)) {
printf("continued by signal SIGCONT\n", WSTOPSIG(status));
#endif
} else {
printf("unknow event\n");
}
}
return 0;
}
int main(int argc, char *argv[]) {
wait_status_test();
return 0;
}
Compile:
gcc -Wall wait_status_test.c
Execute:
./a.out , , fork(),./a.out, kill -9 <child_process_id>, ,./a.out, kill -STOP <child_process_id> , kill -CONT <child_process_id>, ,