Fix unnecessary overallocation due to incomplete character
[platform/upstream/glibc.git] / posix / tst-vfork2.c
1 /* Test for vfork functions.
2    Copyright (C) 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@redhat.com>, 2004.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <errno.h>
22 #include <signal.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include <sys/time.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31
32 int raise_fail;
33
34 static void
35 alrm (int sig)
36 {
37   if (raise (SIGUSR1) < 0)
38     raise_fail = 1;
39 }
40
41 /* This test relies on non-POSIX functionality since the child
42    processes call write, nanosleep and getpid.  */
43 static int
44 do_test (void)
45 {
46   int result = 0;
47   int fd[2];
48
49   signal (SIGUSR1, SIG_IGN);
50
51   struct sigaction sa;
52   sa.sa_handler = alrm;
53   sigemptyset (&sa.sa_mask);
54   sa.sa_flags = 0;
55   if (sigaction (SIGALRM, &sa, NULL) < 0)
56     {
57       puts ("couldn't set up SIGALRM handler");
58       return 1;
59     }
60
61   if (pipe (fd) == -1)
62     {
63       puts ("pipe failed");
64       return 1;
65     }
66
67   struct itimerval it;
68   it.it_value.tv_sec = 0;
69   it.it_value.tv_usec = 200 * 1000;
70   it.it_interval = it.it_value;
71   if (setitimer (ITIMER_REAL, &it, NULL) < 0)
72     {
73       puts ("couldn't set up timer");
74       return 1;
75     }
76
77   /* First vfork() without previous getpid().  */
78   pid_t p1;
79   if ((p1 = vfork ()) == 0)
80     {
81       pid_t p = getpid ();
82
83       struct timespec ts;
84       ts.tv_sec = 1;
85       ts.tv_nsec = 0;
86       TEMP_FAILURE_RETRY (nanosleep (&ts, &ts));
87       _exit (TEMP_FAILURE_RETRY (write (fd[1], &p, sizeof (p))) != sizeof (p));
88     }
89   else if (p1 == -1)
90     {
91       puts ("1st vfork failed");
92       result = 1;
93     }
94
95   memset (&it, 0, sizeof (it));
96   setitimer (ITIMER_REAL, &it, NULL);
97
98   pid_t p2 = 0;
99   if (TEMP_FAILURE_RETRY (read (fd[0], &p2, sizeof (pid_t))) != sizeof (pid_t))
100     {
101       puts ("1st read failed");
102       result = 1;
103     }
104   int r;
105   if (TEMP_FAILURE_RETRY (waitpid (p1, &r, 0)) != p1)
106     {
107       puts ("1st waitpid failed");
108       result = 1;
109     }
110   else if (r != 0)
111     {
112       puts ("write in 1st child failed");
113       result = 1;
114     }
115
116   /* Main process' ID.  */
117   pid_t p0 = getpid ();
118
119   /* vfork() again, but after a getpid() in the main process.  */
120   pid_t p3;
121   if ((p3 = vfork ()) == 0)
122     {
123       pid_t p = getpid ();
124       _exit (TEMP_FAILURE_RETRY (write (fd[1], &p, sizeof (p))) != sizeof (p));
125     }
126   else if (p1 == -1)
127     {
128       puts ("2nd vfork failed");
129       result = 1;
130     }
131
132   pid_t p4;
133   if (TEMP_FAILURE_RETRY (read (fd[0], &p4, sizeof (pid_t))) != sizeof (pid_t))
134     {
135       puts ("2nd read failed");
136       result = 1;
137     }
138   if (TEMP_FAILURE_RETRY (waitpid (p3, &r, 0)) != p3)
139     {
140       puts ("2nd waitpid failed");
141       result = 1;
142     }
143   else if (r != 0)
144     {
145       puts ("write in 2nd child failed");
146       result = 1;
147     }
148
149   /* And getpid in the main process again.  */
150   pid_t p5 = getpid ();
151
152   /* Analysis of the results.  */
153   if (p0 != p5)
154     {
155       printf ("p0(%ld) != p5(%ld)\n", (long int) p0, (long int) p5);
156       result = 1;
157     }
158
159   if (p0 == p1)
160     {
161       printf ("p0(%ld) == p1(%ld)\n", (long int) p0, (long int) p1);
162       result = 1;
163     }
164
165   if (p1 != p2)
166     {
167       printf ("p1(%ld) != p2(%ld)\n", (long int) p1, (long int) p2);
168       result = 1;
169     }
170
171   if (p0 == p3)
172     {
173       printf ("p0(%ld) == p3(%ld)\n", (long int) p0, (long int) p3);
174       result = 1;
175     }
176
177   if (p3 != p4)
178     {
179       printf ("p3(%ld) != p4(%ld)\n", (long int) p3, (long int) p4);
180       result = 1;
181     }
182
183   close (fd[0]);
184   close (fd[1]);
185
186   if (raise_fail)
187     {
188       puts ("raise failed");
189       result = 1;
190     }
191
192   if (result == 0)
193     puts ("All OK");
194
195   return result;
196 }
197
198 #define TEST_FUNCTION do_test ()
199 #include "../test-skeleton.c"