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