xref: /minix/minix/tests/test2.c (revision 7f5f010b)
1 /* test 2 */
2 
3 #include <sys/types.h>
4 #include <sys/times.h>
5 #include <sys/wait.h>
6 #include <errno.h>
7 #include <signal.h>
8 #include <stdlib.h>
9 #include <unistd.h>
10 #include <time.h>
11 #include <stdio.h>
12 
13 #define ITERATIONS 5
14 int max_error = 4;
15 #include "common.h"
16 
17 
18 int is, array[4], parsigs, parcum, sigct, cumsig, subtest;
19 int iteration, kk = 0;
20 char buf[2048];
21 
22 
23 int main(int argc, char *argv []);
24 void test2a(void);
25 void test2b(void);
26 void test2c(void);
27 void test2d(void);
28 void test2e(void);
29 void test2f(void);
30 void test2g(void);
31 void sigpip(int s);
32 
33 int main(argc, argv)
34 int argc;
35 char *argv[];
36 {
37   int i, m = 0xFFFF;
38 
39   start(2);
40 
41   for (i = 0; i < ITERATIONS; i++) {
42 	iteration = i;
43 	if (m & 0001) test2a();
44 	if (m & 0002) test2b();
45 	if (m & 0004) test2c();
46 	if (m & 0010) test2d();
47 	if (m & 0020) test2e();
48 	if (m & 0040) test2f();
49 	if (m & 0100) test2g();
50   }
51   subtest = 100;
52   if (cumsig != ITERATIONS) e(101);
53   quit();
54   return(-1);			/* impossible */
55 }
56 
57 void test2a()
58 {
59 /* Test pipes */
60 
61   int fd[2];
62   int n, i, j, q = 0;
63 
64   subtest = 1;
65   if (pipe(fd) < 0) {
66 	printf("pipe error.  errno= %d\n", errno);
67 	e(10);
68 	quit();
69   }
70   i = fork();
71   if (i < 0) {
72 	printf("fork failed\n");
73 	e(11);
74 	quit();
75   }
76   if (i != 0) {
77 	/* Parent code */
78 	close(fd[0]);
79 	for (i = 0; i < 2048; i++) buf[i] = i & 0377;
80 	for (q = 0; q < 8; q++) {
81 		if (write(fd[1], buf, 2048) < 0) {
82 			printf("write pipe err.  errno=%d\n", errno);
83 			e(12);
84 			quit();
85 		}
86 	}
87 	close(fd[1]);
88 	wait(&q);
89 	if (q != 256 * 58) {
90 		printf("wrong exit code %d\n", q);
91 		e(13);
92 		quit();
93 	}
94   } else {
95 	/* Child code */
96 	close(fd[1]);
97 	for (q = 0; q < 32; q++) {
98 		n = read(fd[0], buf, 512);
99 		if (n != 512) {
100 			printf("read yielded %d bytes, not 512\n", n);
101 			e(14);
102 			quit();
103 		}
104 		for (j = 0; j < n; j++)
105 			if ((buf[j] & 0377) != (kk & 0377)) {
106 				printf("wrong data: %d %d %d \n ",
107 						j, buf[j] & 0377, kk & 0377);
108 			} else {
109 				kk++;
110 			}
111 	}
112 	exit(58);
113   }
114 }
115 
116 void test2b()
117 {
118   int fd[2], n;
119   char buf[4];
120 
121   subtest = 2;
122   sigct = 0;
123   signal(SIGPIPE, sigpip);
124   pipe(fd);
125   if (fork()) {
126 	/* Parent */
127 	close(fd[0]);
128 	while (sigct == 0) {
129 		write(fd[1], buf, 1);
130 	}
131 	wait(&n);
132   } else {
133 	/* Child */
134 	close(fd[0]);
135 	close(fd[1]);
136 	exit(0);
137   }
138 }
139 
140 void test2c()
141 {
142   int n;
143 
144   subtest = 3;
145   signal(SIGINT, SIG_DFL);
146   is = 0;
147   if ((array[is++] = fork()) > 0) {
148 	if ((array[is++] = fork()) > 0) {
149 		if ((array[is++] = fork()) > 0) {
150 			if ((array[is++] = fork()) > 0) {
151 				signal(SIGINT, SIG_IGN);
152 				kill(array[0], SIGINT);
153 				kill(array[1], SIGINT);
154 				kill(array[2], SIGINT);
155 				kill(array[3], SIGINT);
156 				wait(&n);
157 				wait(&n);
158 				wait(&n);
159 				wait(&n);
160 			} else {
161 				pause();
162 			}
163 		} else {
164 			pause();
165 		}
166 	} else {
167 		pause();
168 	}
169   } else {
170 	pause();
171   }
172 }
173 
174 void test2d()
175 {
176 
177   int pid, stat_loc, s;
178 
179   /* Test waitpid. */
180   subtest = 4;
181 
182   /* Test waitpid(pid, arg2, 0) */
183   pid = fork();
184   if (pid < 0) e(1);
185   if (pid > 0) {
186 	/* Parent. */
187 	s = waitpid(pid, &stat_loc, 0);
188 	if (s != pid) e(2);
189 	if (WIFEXITED(stat_loc) == 0) e(3);
190 	if (WIFSIGNALED(stat_loc) != 0) e(4);
191 	if (WEXITSTATUS(stat_loc) != 22) e(5);
192   } else {
193 	/* Child */
194 	exit(22);
195   }
196 
197   /* Test waitpid(-1, arg2, 0) */
198   pid = fork();
199   if (pid < 0) e(6);
200   if (pid > 0) {
201 	/* Parent. */
202 	s = waitpid(-1, &stat_loc, 0);
203 	if (s != pid) e(7);
204 	if (WIFEXITED(stat_loc) == 0) e(8);
205 	if (WIFSIGNALED(stat_loc) != 0) e(9);
206 	if (WEXITSTATUS(stat_loc) != 33) e(10);
207   } else {
208 	/* Child */
209 	exit(33);
210   }
211 
212   /* Test waitpid(0, arg2, 0) */
213   pid = fork();
214   if (pid < 0) e(11);
215   if (pid > 0) {
216 	/* Parent. */
217 	s = waitpid(0, &stat_loc, 0);
218 	if (s != pid) e(12);
219 	if (WIFEXITED(stat_loc) == 0) e(13);
220 	if (WIFSIGNALED(stat_loc) != 0) e(14);
221 	if (WEXITSTATUS(stat_loc) != 44) e(15);
222   } else {
223 	/* Child */
224 	exit(44);
225   }
226 
227   /* Test waitpid(0, arg2, WNOHANG) */
228   signal(SIGTERM, SIG_DFL);
229   pid = fork();
230   if (pid < 0) e(16);
231   if (pid > 0) {
232 	/* Parent. */
233 	s = waitpid(0, &stat_loc, WNOHANG);
234 	if (s != 0) e(17);
235 	if (kill(pid, SIGTERM) != 0) e(18);
236 	if (waitpid(pid, &stat_loc, 0) != pid) e(19);
237 	if (WIFEXITED(stat_loc) != 0) e(20);
238 	if (WIFSIGNALED(stat_loc) == 0) e(21);
239 	if (WTERMSIG(stat_loc) != SIGTERM) e(22);
240   } else {
241 	/* Child */
242 	pause();
243   }
244 
245   /* Test some error conditions. */
246   errno = 9999;
247   if (waitpid(0, &stat_loc, 0) != -1) e(23);
248   if (errno != ECHILD) e(24);
249   errno = 9999;
250   if (waitpid(0, &stat_loc, WNOHANG) != -1) e(25);
251   if (errno != ECHILD) e(26);
252 }
253 
254 void test2e()
255 {
256 
257   int pid1, pid2, stat_loc, s;
258 
259   /* Test waitpid with two children. */
260   subtest = 5;
261   if (iteration > 1) return;		/* slow test, don't do it too much */
262   if ( (pid1 = fork())) {
263 	/* Parent. */
264 	if ( (pid2 = fork()) ) {
265 		/* Parent. Collect second child first. */
266 		s = waitpid(pid2, &stat_loc, 0);
267 		if (s != pid2) e(1);
268 		if (WIFEXITED(stat_loc) == 0) e(2);
269 		if (WIFSIGNALED(stat_loc) != 0) e(3);
270 		if (WEXITSTATUS(stat_loc) != 222) e(4);
271 
272 		/* Now collect first child. */
273 		s = waitpid(pid1, &stat_loc, 0);
274 		if (s != pid1) e(5);
275 		if (WIFEXITED(stat_loc) == 0) e(6);
276 		if (WIFSIGNALED(stat_loc) != 0) e(7);
277 		if (WEXITSTATUS(stat_loc) != 111) e(8);
278 	} else {
279 		/* Child 2. */
280 		sleep(2);		/* child 2 delays before exiting. */
281 		exit(222);
282 	}
283   } else {
284 	/* Child 1. */
285 	exit(111);			/* child 1 exits immediately */
286   }
287 
288 }
289 
290 void test2f()
291 {
292 /* test getpid, getppid, getuid, etc. */
293 
294   pid_t pid, pid1, ppid, cpid, stat_loc, err;
295 
296   subtest = 6;
297   errno = -2000;
298   err = 0;
299   pid = getpid();
300   if ( (pid1 = fork())) {
301 	/* Parent.  Do nothing. */
302 	if (wait(&stat_loc) != pid1) e(1);
303 	if (WEXITSTATUS(stat_loc) != (pid1 & 0377)) e(2);
304   } else {
305 	/* Child.  Get ppid. */
306 	cpid = getpid();
307 	ppid = getppid();
308 	if (ppid != pid) err = 3;
309 	if (cpid == ppid) err = 4;
310 	exit(cpid & 0377);
311   }
312   if (err != 0) e(err);
313 }
314 
315 void test2g()
316 {
317 /* test time(), times() */
318 
319   time_t t1, t2;
320   clock_t t3, t4;
321   long clocks_per_sec;
322   struct tms tmsbuf;
323 
324   subtest = 7;
325   errno = -7000;
326 
327   clocks_per_sec = sysconf(_SC_CLK_TCK);
328 
329   /* First time(). */
330   t1 = -1;
331   t2 = -2;
332   t1 = time(&t2);
333   if (t1 < 650000000L) e(1);	/* 650000000 is Sept. 1990 */
334   if (t1 != t2) e(2);
335   t1 = -1;
336   t1 = time( (time_t *) NULL);
337   if (t1 < 650000000L) e(3);
338   t3 = times(&tmsbuf);
339   sleep(1);
340   t2 = time( (time_t *) NULL);
341   if (t2 < 0L) e(4);
342   if (t2 - t1 < 1) e(5);
343 
344   /* Now times(). */
345   t4 = times(&tmsbuf);
346   if (t4 == (clock_t) -1) e(6);
347   if (t4 - t3 < clocks_per_sec) e(7);
348 }
349 
350 void sigpip(s)
351 int s;				/* for ANSI */
352 {
353   sigct++;
354   cumsig++;
355 }
356 
357