1/* Test exit of a child of a TCB_EXITING child where the toplevel process starts
2 * waiting on it.  The middle one gets detached and strace must update the
3 * toplevel process'es number of attached children to 0.
4 *
5 * gcc -o test/childthread test/childthread.c -Wall -ggdb2 -pthread;./strace -f ./test/childthread
6 * It must print: write(1, "OK\n", ...
7 */
8
9#include <pthread.h>
10#include <assert.h>
11#include <unistd.h>
12#include <stdlib.h>
13#include <stdio.h>
14#include <sys/wait.h>
15
16static void *start0(void *arg)
17{
18	pause();
19	/* NOTREACHED */
20	assert(0);
21}
22
23int main(int argc, char *argv[])
24{
25	pthread_t thread0;
26	pid_t child, got_pid;
27	int status;
28	int i;
29
30	child = fork();
31
32	switch (child) {
33	case -1:
34		assert(0);
35	case 0:
36		i = pthread_create(&thread0, NULL, start0, NULL);
37		assert(i == 0);
38		/* The thread must be initialized, it becomes thread-child of this
39		   process-child (child of a child of the toplevel process).  */
40		sleep(1);
41		/* Here the child TCB cannot be deallocated as there still exist
42		 * children (the thread child in START0).  */
43		exit(42);
44		/* NOTREACHED */
45		assert(0);
46	default:
47		/* We must not be waiting in WAITPID when the child double-exits.  */
48		sleep(2);
49		/* PID must be -1.  */
50		got_pid = waitpid(-1, &status, 0);
51		assert(got_pid == child);
52		assert(WIFEXITED(status));
53		assert(WEXITSTATUS(status) == 42);
54		puts("OK");
55		exit(0);
56	}
57
58	/* NOTREACHED */
59	assert(0);
60}
61