Smack: add the execute lable to ldconfig
[platform/upstream/glibc.git] / posix / tst-vfork3.c
1 /* Test for vfork functions.
2    Copyright (C) 2007-2015 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Jakub Jelinek <jakub@redhat.com>, 2007.
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 <fcntl.h>
22 #include <mcheck.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/wait.h>
27
28 static int do_test (void);
29 static void do_prepare (void);
30 char *tmpdirname;
31
32 #define TEST_FUNCTION do_test ()
33 #define PREPARE(argc, argv) do_prepare ()
34 #include "../test-skeleton.c"
35
36 static int
37 do_test (void)
38 {
39   mtrace ();
40
41   const char *path = getenv ("PATH");
42   if (path == NULL)
43     path = "/bin";
44   char pathbuf[strlen (tmpdirname) + 1 + strlen (path) + 1];
45   strcpy (stpcpy (stpcpy (pathbuf, tmpdirname), ":"), path);
46   if (setenv ("PATH", pathbuf, 1) < 0)
47     {
48       puts ("setenv failed");
49       return 1;
50     }
51
52   size_t i;
53   char *argv[3] = { (char *) "script1.sh", (char *) "1", NULL };
54   for (i = 0; i < 5; i++)
55     {
56       pid_t pid = vfork ();
57       if (pid < 0)
58         {
59           printf ("vfork failed: %m\n");
60           return 1;
61         }
62       else if (pid == 0)
63         {
64           execvp ("script1.sh", argv);
65           _exit (errno);
66         }
67       int status;
68       if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
69         {
70           puts ("waitpid failed");
71           return 1;
72         }
73       else if (status != 0)
74         {
75           if (WIFEXITED (status))
76             printf ("script1.sh failed with status %d\n",
77                     WEXITSTATUS (status));
78           else
79             printf ("script1.sh kill by signal %d\n",
80                     WTERMSIG (status));
81           return 1;
82         }
83     }
84
85   argv[0] = (char *) "script2.sh";
86   argv[1] = (char *) "2";
87   for (i = 0; i < 5; i++)
88     {
89       pid_t pid = vfork ();
90       if (pid < 0)
91         {
92           printf ("vfork failed: %m\n");
93           return 1;
94         }
95       else if (pid == 0)
96         {
97           execvp ("script2.sh", argv);
98           _exit (errno);
99         }
100       int status;
101       if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
102         {
103           puts ("waitpid failed");
104           return 1;
105         }
106       else if (status != 0)
107         {
108           printf ("script2.sh failed with status %d\n", status);
109           return 1;
110         }
111     }
112
113   for (i = 0; i < 5; i++)
114     {
115       pid_t pid = vfork ();
116       if (pid < 0)
117         {
118           printf ("vfork failed: %m\n");
119           return 1;
120         }
121       else if (pid == 0)
122         {
123           execlp ("script2.sh", "script2.sh", "3", NULL);
124           _exit (errno);
125         }
126       int status;
127       if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
128         {
129           puts ("waitpid failed");
130           return 1;
131         }
132       else if (status != 0)
133         {
134           printf ("script2.sh failed with status %d\n", status);
135           return 1;
136         }
137     }
138
139   unsetenv ("PATH");
140   argv[0] = (char *) "echo";
141   argv[1] = (char *) "script 4";
142   for (i = 0; i < 5; i++)
143     {
144       pid_t pid = vfork ();
145       if (pid < 0)
146         {
147           printf ("vfork failed: %m\n");
148           return 1;
149         }
150       else if (pid == 0)
151         {
152           execvp ("echo", argv);
153           _exit (errno);
154         }
155       int status;
156       if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
157         {
158           puts ("waitpid failed");
159           return 1;
160         }
161       else if (status != 0)
162         {
163           printf ("echo failed with status %d\n", status);
164           return 1;
165         }
166     }
167
168   return 0;
169 }
170
171 static void
172 do_prepare (void)
173 {
174   size_t len = strlen (test_dir) + sizeof ("/tst-vfork3.XXXXXX");
175   tmpdirname = malloc (len);
176   char *script1 = malloc (len + sizeof "/script1.sh");
177   char *script2 = malloc (len + sizeof "/script2.sh");
178   if (tmpdirname == NULL || script1 == NULL || script2 == NULL)
179     {
180       puts ("out of memory");
181       exit (1);
182     }
183   strcpy (stpcpy (tmpdirname, test_dir), "/tst-vfork3.XXXXXX");
184
185   tmpdirname = mkdtemp (tmpdirname);
186   if (tmpdirname == NULL)
187     {
188       puts ("could not create temporary directory");
189       exit (1);
190     }
191
192   strcpy (stpcpy (script1, tmpdirname), "/script1.sh");
193   strcpy (stpcpy (script2, tmpdirname), "/script2.sh");
194
195   /* Need to make sure tmpdirname is at the end of the linked list.  */
196   add_temp_file (script1);
197   add_temp_file (tmpdirname);
198   add_temp_file (script2);
199
200   const char content1[] = "#!/bin/sh\necho script $1\n";
201   int fd = open (script1, O_WRONLY | O_CREAT, 0700);
202   if (fd < 0
203       || TEMP_FAILURE_RETRY (write (fd, content1, sizeof content1))
204          != sizeof content1
205       || fchmod (fd, S_IRUSR | S_IXUSR) < 0)
206     {
207       printf ("Could not write %s\n", script1);
208       exit (1);
209     }
210   close (fd);
211
212   const char content2[] = "echo script $1\n";
213   fd = open (script2, O_WRONLY | O_CREAT, 0700);
214   if (fd < 0
215       || TEMP_FAILURE_RETRY (write (fd, content2, sizeof content2))
216          != sizeof content2
217       || fchmod (fd, S_IRUSR | S_IXUSR) < 0)
218     {
219       printf ("Could not write %s\n", script2);
220       exit (1);
221     }
222   close (fd);
223 }