Update copyright notices with scripts/update-copyrights
[jlayton/glibc.git] / nptl / tst-atfork2.c
1 /* Copyright (C) 2003-2014 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 #include <dlfcn.h>
20 #include <errno.h>
21 #include <mcheck.h>
22 #include <pthread.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/wait.h>
27
28
29 /* Must be exported.  */
30 int val;
31
32 static void
33 prepare (void)
34 {
35   val *= 2;
36 }
37
38 static void
39 parent (void)
40 {
41   val += 4;
42 }
43
44 static void
45 child (void)
46 {
47   val += 8;
48 }
49
50
51 static int
52 do_test (void)
53 {
54   mtrace ();
55
56   if (pthread_atfork (prepare, parent, child) != 0)
57     {
58       puts ("do_test: atfork failed");
59       exit (1);
60     }
61
62   void *h = dlopen ("tst-atfork2mod.so", RTLD_LAZY);
63   if (h == NULL)
64     {
65       printf ("dlopen failed: %s\n", dlerror ());
66       exit (1);
67     }
68
69   /* First trial of fork.  */
70   pid_t pid = fork ();
71   if (pid == -1)
72     {
73       puts ("1st fork failed");
74       exit (1);
75     }
76
77   if (pid == 0)
78     {
79       /* Child.  */
80       if (val != 80)
81         {
82           printf ("1st: expected val=%d, got %d\n", 80, val);
83           exit (2);
84         }
85
86       exit (0);
87     }
88
89   /* Parent.  */
90   if (val != 24)
91     {
92       printf ("1st: expected val=%d, got %d\n", 24, val);
93       exit (1);
94     }
95
96   int status;
97   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
98     {
99       puts ("1st waitpid failed");
100       exit (1);
101     }
102
103   if (status != 0)
104     exit (status);
105
106   puts ("unloading now");
107
108   /* Unload the module.  */
109   if (dlclose (h) != 0)
110     {
111       puts ("dlclose failed");
112       exit (1);
113     }
114
115   puts ("2nd fork");
116
117   /* Second fork trial.   */
118   val = 1;
119   pid = fork ();
120   if (pid == -1)
121     {
122       puts ("2nd fork failed");
123       exit (1);
124     }
125
126   if (pid == 0)
127     {
128       /* Child.  */
129       if (val != 10)
130         {
131           printf ("2nd: expected val=%d, got %d\n", 10, val);
132           exit (3);
133         }
134
135       exit (0);
136     }
137
138   /* Parent.  */
139   if (val != 6)
140     {
141       printf ("2nd: expected val=%d, got %d\n", 6, val);
142       exit (1);
143     }
144
145   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
146     {
147       puts ("2nd waitpid failed");
148       exit (1);
149     }
150
151   if (status != 0)
152     exit (status);
153
154   return 0;
155 }
156
157 #define TEST_FUNCTION do_test ()
158 #include "../test-skeleton.c"