Include atomic.h in sem_wait.c and sem_trywait.c
[platform/upstream/glibc.git] / nptl / tst-exec2.c
1 /* Thread with running thread calls exec.
2    Copyright (C) 2002-2014 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #include <errno.h>
21 #include <paths.h>
22 #include <pthread.h>
23 #include <signal.h>
24 #include <spawn.h>
25 #include <stdbool.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <unistd.h>
29 #include <sys/wait.h>
30
31
32 static void *
33 tf (void *arg)
34 {
35   pthread_t th = (pthread_t) arg;
36
37   if (pthread_join (th, NULL) == 0)
38     {
39       puts ("thread in parent joined!?");
40       exit (1);
41     }
42
43   puts ("join in thread in parent returned!?");
44   exit (1);
45 }
46
47
48 static int
49 do_test (void)
50 {
51   int fd[2];
52   if (pipe (fd) != 0)
53     {
54       puts ("pipe failed");
55       exit (1);
56     }
57
58   /* Not interested in knowing when the pipe is closed.  */
59   if (sigignore (SIGPIPE) != 0)
60     {
61       puts ("sigignore failed");
62       exit (1);
63     }
64
65   pid_t pid = fork ();
66   if (pid == -1)
67     {
68       puts ("fork failed");
69       exit (1);
70     }
71
72   if (pid == 0)
73     {
74       /* Use the fd for stdout.  This is kind of ugly because it
75          substitutes the fd of stdout but we know what we are doing
76          here...  */
77       if (dup2 (fd[1], STDOUT_FILENO) != STDOUT_FILENO)
78         {
79           puts ("dup2 failed");
80           exit (1);
81         }
82
83       close (fd[0]);
84
85       pthread_t th;
86       if (pthread_create (&th, NULL, tf, (void *) pthread_self ()) != 0)
87         {
88           puts ("create failed");
89           exit (1);
90         }
91
92       execl (_PATH_BSHELL, _PATH_BSHELL, "-c", "echo $$", NULL);
93
94       puts ("execl failed");
95       exit (1);
96     }
97
98   close (fd[1]);
99
100   char buf[200];
101   ssize_t n;
102   bool seen_pid = false;
103   while (TEMP_FAILURE_RETRY ((n = read (fd[0], buf, sizeof (buf)))) > 0)
104     {
105       /* We only expect to read the PID.  */
106       char *endp;
107       long int rpid = strtol (buf, &endp, 10);
108
109       if (*endp != '\n')
110         {
111           printf ("didn't parse whole line: \"%s\"\n", buf);
112           exit (1);
113         }
114       if (endp == buf)
115         {
116           puts ("read empty line");
117           exit (1);
118         }
119
120       if (rpid != pid)
121         {
122           printf ("found \"%s\", expected PID %ld\n", buf, (long int) pid);
123           exit (1);
124         }
125
126       if (seen_pid)
127         {
128           puts ("found more than one PID line");
129           exit (1);
130         }
131       seen_pid = true;
132     }
133
134   close (fd[0]);
135
136   int status;
137   int err = waitpid (pid, &status, 0);
138   if (err != pid)
139     {
140       puts ("waitpid failed");
141       exit (1);
142     }
143
144   if (!seen_pid)
145     {
146       puts ("didn't get PID");
147       exit (1);
148     }
149
150   return 0;
151 }
152
153 #define TEST_FUNCTION do_test ()
154 #include "../test-skeleton.c"