/*
 * Has-Zombies.01.c
 *		Test for whether this o/s has a BSD-like zombie problem
 *
 * Author	Stuart Herbert
 *		(stuart@gnqs.org)
 *
 * Copyright	(c) 1998 Stuart Herbert
 *		Released under v2 of the GNU GPL
 */

/*
 * So, just how do you detect a zombie?  Good question.
 *
 * A zombie is a child process which is hanging around waiting for the
 * parent process to acknowledge that it is dead.  If the parent is slow
 * to acknowledge them, zombies have a habit of quickly filling up your
 * local process table and choking the life out of the machine.
 *
 * Some o/s's, such as SVr4 (e.g. Solaris) and Linux will happily kill
 * the buggers off for you if you ignore SIGCHLD.  It's not really a
 * POSIX.1 thing - POSIX.1-1990 says that the results of ignoring SIGCHLD
 * are undefined.
 *
 * We must create a child process, ignore SIGCHLD, sleep a bit, and then
 * see if the child process (which will have terminated in the meantime)
 * is there waiting for us.  If it is, we have ourselves a zombie.
 *
 * We must try this for both the POSIX.1 and BSD wait-style functions.
 */

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

 int main (void)
 {
 	signal(SIGCHLD, SIG_IGN);

 	switch (fork())
	{
	case 0:	/* we are the child */
		exit(0);
		break;

	case -1: /* something went wrong */
		printf("fork failed\n");
		exit(1);
		break;

	default: /* we are the proud parent */
		sleep(10);

		wait(NULL);
		if (errno == ECHILD)
		{
			printf("no zombie\n");
			exit(0);
		}
		else
		{
			printf("zombie process\n");
			exit(0);
		}
	}
 }

