1 /*
2  * Copyright (c) 2002, Intel Corporation. All rights reserved.
3  * Created by:  rolla.n.selbak REMOVE-THIS AT intel DOT com
4  * This file is licensed under the GPL license.  For the full content
5  * of this license, see the COPYING file at the top level of this
6  * source tree.
7  *
8  * int pthread_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void))
9  *
10  *  shall declare fork handlers to be called before and after a fork() command, in the context
11  *  of the thread that called the fork().  The 'prepare' fork handler shall be called before
12  *  fork() processing commences.  The 'parent' fork handle shall be called after fork()
13  *  processing completes in the parent process.  The 'child' fork shall be called after
14  *  fork() processing completes in the child process.
15  *
16  * STEPS:
17  * 1. Call pthread_atfork() before a fork() call, setting all three fork handlers for
18  *    prepare, parent and child.
19  * 2. Call fork()
20  * 3. Verify that all three fork handlers were called
21  *
22  */
23 
24 #include <pthread.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <errno.h>
29 #include <unistd.h>
30 #include <sys/wait.h>
31 #include <sys/types.h>
32 #include "posixtest.h"
33 
34 # define HANDLER_NOTCALLED 0
35 # define HANDLER_CALLED 1
36 
37 int prep_val;
38 int parent_val;
39 int child_val;
40 
prepare_handler()41 static void prepare_handler()
42 {
43 	prep_val = HANDLER_CALLED;
44 	return;
45 }
46 
parent_handler()47 static void parent_handler()
48 {
49 	parent_val = HANDLER_CALLED;
50 	return;
51 }
52 
child_handler()53 static void child_handler()
54 {
55 	child_val = HANDLER_CALLED;
56 	return;
57 }
58 
main()59 int main ()
60 {
61 	pid_t pid;
62 
63 	/* Initialize values */
64 	prep_val = HANDLER_NOTCALLED;
65 	parent_val = HANDLER_NOTCALLED;
66 	child_val = HANDLER_NOTCALLED;
67 
68 	/* Set up the fork handlers */
69 	if(pthread_atfork(prepare_handler, parent_handler, child_handler) != 0)
70 	{
71 		printf("Error in pthread_atfork\n");
72 		return PTS_UNRESOLVED;
73 	}
74 
75 	/* Now call fork() */
76 	pid = fork();
77 
78 	if(pid < 0)
79 	{
80 		perror("Error in fork()\n");
81 		return PTS_UNRESOLVED;
82 	}
83 	if(pid == 0)
84 	{
85 		/* Child process */
86 		pthread_exit(0);
87 	} else
88 	{
89 		/* Parent process */
90 		wait(NULL);
91 	}
92 
93 	/* Check if fork handlers were called */
94 	if(prep_val == 1)
95 	{
96 		if(parent_val == 1)
97 		{
98 			if(parent_val == 1)
99 			{
100 				printf("Test PASSED\n");
101 				return PTS_PASS;
102 			} else
103 			{
104 				printf("Test FAILED: child handler not called\n");
105 				return PTS_FAIL;
106 			}
107 		} else
108 		{
109 			printf("Test FAILED: parent handler not called\n");
110 			return PTS_FAIL;
111 		}
112 	}
113 	else
114 	{
115 		printf("Test FAILED: prepare handler not called\n");
116 		return PTS_FAIL;
117 	}
118 
119 	/* Should not reach here */
120 	printf("Error: control should not reach here\n");
121 	return PTS_UNRESOLVED;
122 }
123 
124