/* Test exit of a child of a TCB_EXITING child where the toplevel process starts
 * waiting on it.  The middle one gets detached and strace must update the
 * toplevel process'es number of attached children to 0.
 *
 * gcc -o test/childthread test/childthread.c -Wall -ggdb2 -pthread;./strace -f ./test/childthread
 * It must print: write(1, "OK\n", ...
 */

#include <pthread.h>
#include <assert.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/wait.h>

static void *start0(void *arg)
{
	pause();
	/* NOTREACHED */
	assert(0);
}

int main(int argc, char *argv[])
{
	pthread_t thread0;
	pid_t child, got_pid;
	int status;
	int i;

	child = fork();

	switch (child) {
	case -1:
		assert(0);
	case 0:
		i = pthread_create(&thread0, NULL, start0, NULL);
		assert(i == 0);
		/* The thread must be initialized, it becomes thread-child of this
		   process-child (child of a child of the toplevel process).  */
		sleep(1);
		/* Here the child TCB cannot be deallocated as there still exist
		 * children (the thread child in START0).  */
		exit(42);
		/* NOTREACHED */
		assert(0);
	default:
		/* We must not be waiting in WAITPID when the child double-exits.  */
		sleep(2);
		/* PID must be -1.  */
		got_pid = waitpid(-1, &status, 0);
		assert(got_pid == child);
		assert(WIFEXITED(status));
		assert(WEXITSTATUS(status) == 42);
		puts("OK");
		exit(0);
	}

	/* NOTREACHED */
	assert(0);
}
