C: Notes on waitpid() and Supporting Macro's
Wednesday, 05 May 2010 19:26

Skim reading 'man waitpid' it is easy assume that the 'status' returned by this function is the 'return/exit code' of the child process. Fortunately, 'status' provides not only the 'return/exit code' of a process, but also information like 'was the program terminated due to a signal?', 'what signal terminated the process?', 'was a core file generated?', etc

The below example uses 'waitpid()', 'kill()', and macros like 'WIFSIGNALED' to correctly query exactly how a process died.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(void) {

	pid_t pid = fork();

	if (pid < 0) {
		printf("ERROR: could not fork error: %d\n", pid);
		return EXIT_FAILURE;
	} else if (pid == 0) {
		printf("CHILD: Running New Process\n");
		sleep(5);
		return EXIT_SUCCESS;
	} else {
		int childstatus = 0;
		printf("PARENT: Created new process %d\n", pid);

		kill(pid, SIGKILL);

		if (-1 == waitpid(pid, &childstatus, 0)) {
			perror("PARENT: Wait for child pid failed");
			return EXIT_FAILURE;
		}

		printf("PARENT: Child status = %d (0x%x)\n", childstatus, childstatus);

		if (0 != WIFEXITED(childstatus)) {
			printf("PARENT: Child terminated normally.");
		}

		printf("PARENT: Child exited with %d\n", WEXITSTATUS(childstatus));

		if (0 != WIFSIGNALED(childstatus)) {
			printf("PARENT: Child process was terminated by a signal %d\n",
			WTERMSIG(childstatus));
		}

		if (0 != WCOREDUMP(childstatus)) {
			printf("PARENT: Child core dumped\n");
		}

		if (0 != WIFSTOPPED(childstatus)) {
			printf("PARENT: Child process has been stopped %d\n",
			WSTOPSIG(childstatus));
		}

		if (0 != WIFCONTINUED(childstatus)) {
			printf("PARENT: Child has been continued\n");
		}

		return EXIT_SUCCESS;
	}
	return EXIT_SUCCESS;
}

Note: Signals available to be used by 'kill' can be listed like below. It may be a good idea to try modifying the above program to use different signals.

$ kill -l
 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX