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