xref: /minix3/minix/tests/test5.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc /* test 5 */
2*433d6423SLionel Sambuc 
3*433d6423SLionel Sambuc #include <sys/types.h>
4*433d6423SLionel Sambuc #include <sys/wait.h>
5*433d6423SLionel Sambuc #include <errno.h>
6*433d6423SLionel Sambuc #include <fcntl.h>
7*433d6423SLionel Sambuc #include <signal.h>
8*433d6423SLionel Sambuc #include <stdlib.h>
9*433d6423SLionel Sambuc #include <unistd.h>
10*433d6423SLionel Sambuc #include <stdio.h>
11*433d6423SLionel Sambuc #include <string.h>
12*433d6423SLionel Sambuc 
13*433d6423SLionel Sambuc #define ITERATIONS 2
14*433d6423SLionel Sambuc int max_error = 3;
15*433d6423SLionel Sambuc #include "common.h"
16*433d6423SLionel Sambuc 
17*433d6423SLionel Sambuc 
18*433d6423SLionel Sambuc int subtest;
19*433d6423SLionel Sambuc int zero[1024];
20*433d6423SLionel Sambuc int sigmap[5] = {SIGKILL, SIGUSR1, SIGSEGV};
21*433d6423SLionel Sambuc 
22*433d6423SLionel Sambuc 
23*433d6423SLionel Sambuc int main(int argc, char *argv[]);
24*433d6423SLionel Sambuc void test5a(void);
25*433d6423SLionel Sambuc void parent(int childpid);
26*433d6423SLionel Sambuc void child(int parpid);
27*433d6423SLionel Sambuc void func1(int s);
28*433d6423SLionel Sambuc void func8(int s);
29*433d6423SLionel Sambuc void func10(int s);
30*433d6423SLionel Sambuc void func11(int s);
31*433d6423SLionel Sambuc void test5b(void);
32*433d6423SLionel Sambuc void test5c(void);
33*433d6423SLionel Sambuc void test5d(void);
34*433d6423SLionel Sambuc void test5e(void);
35*433d6423SLionel Sambuc void test5f(void);
36*433d6423SLionel Sambuc void test5g(void);
37*433d6423SLionel Sambuc void funcalrm(int s);
38*433d6423SLionel Sambuc void test5h(void);
39*433d6423SLionel Sambuc void test5i(void);
40*433d6423SLionel Sambuc void ex(void);
41*433d6423SLionel Sambuc 
42*433d6423SLionel Sambuc volatile int childsigs, parsigs, alarms;
43*433d6423SLionel Sambuc 
main(argc,argv)44*433d6423SLionel Sambuc int main(argc, argv)
45*433d6423SLionel Sambuc int argc;
46*433d6423SLionel Sambuc char *argv[];
47*433d6423SLionel Sambuc {
48*433d6423SLionel Sambuc   int i, m = 0x7777;
49*433d6423SLionel Sambuc 
50*433d6423SLionel Sambuc   start(5);
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc   for (i = 0; i < ITERATIONS; i++) {
53*433d6423SLionel Sambuc 	if (m & 0001) test5a();
54*433d6423SLionel Sambuc 	if (m & 0002) test5b();
55*433d6423SLionel Sambuc 	if (m & 0004) test5c();
56*433d6423SLionel Sambuc 	if (m & 0010) test5d();
57*433d6423SLionel Sambuc 	if (m & 0020) test5e();
58*433d6423SLionel Sambuc 	if (m & 0040) test5f();
59*433d6423SLionel Sambuc 	if (m & 0100) test5g();
60*433d6423SLionel Sambuc 	if (m & 0200) test5h();
61*433d6423SLionel Sambuc 	if (m & 0400) test5i();
62*433d6423SLionel Sambuc   }
63*433d6423SLionel Sambuc   quit();
64*433d6423SLionel Sambuc   return(-1);			/* impossible */
65*433d6423SLionel Sambuc }
66*433d6423SLionel Sambuc 
test5a()67*433d6423SLionel Sambuc void test5a()
68*433d6423SLionel Sambuc {
69*433d6423SLionel Sambuc   int parpid, childpid, flag, *zp;
70*433d6423SLionel Sambuc 
71*433d6423SLionel Sambuc   subtest = 0;
72*433d6423SLionel Sambuc   flag = 0;
73*433d6423SLionel Sambuc   for (zp = &zero[0]; zp < &zero[1024]; zp++)
74*433d6423SLionel Sambuc 	if (*zp != 0) flag = 1;
75*433d6423SLionel Sambuc   if (flag) e(0);		/* check if bss is cleared to 0 */
76*433d6423SLionel Sambuc   if (signal(SIGHUP, func1) ==  SIG_ERR) e(1);
77*433d6423SLionel Sambuc   if (signal(SIGUSR1, func10) == SIG_ERR) e(2);
78*433d6423SLionel Sambuc   parpid = getpid();
79*433d6423SLionel Sambuc   if ((childpid = fork()) != 0) {
80*433d6423SLionel Sambuc 	if (childpid < 0) ex();
81*433d6423SLionel Sambuc 	parent(childpid);
82*433d6423SLionel Sambuc   } else {
83*433d6423SLionel Sambuc 	child(parpid);
84*433d6423SLionel Sambuc   }
85*433d6423SLionel Sambuc   if (signal(SIGHUP, SIG_DFL) == SIG_ERR) e(4);
86*433d6423SLionel Sambuc   if (signal(SIGUSR1, SIG_DFL) == SIG_ERR) e(5);
87*433d6423SLionel Sambuc }
88*433d6423SLionel Sambuc 
parent(childpid)89*433d6423SLionel Sambuc void parent(childpid)
90*433d6423SLionel Sambuc int childpid;
91*433d6423SLionel Sambuc {
92*433d6423SLionel Sambuc   int i, pid;
93*433d6423SLionel Sambuc 
94*433d6423SLionel Sambuc   for (i = 0; i < 3; i++) {
95*433d6423SLionel Sambuc 	if (kill(childpid, SIGHUP) < 0) e(6);
96*433d6423SLionel Sambuc 	while (parsigs == 0);
97*433d6423SLionel Sambuc 	parsigs--;
98*433d6423SLionel Sambuc   }
99*433d6423SLionel Sambuc   if ( (pid = wait(&i)) < 0) e(7);
100*433d6423SLionel Sambuc   if (i != 256 * 6) e(8);
101*433d6423SLionel Sambuc }
102*433d6423SLionel Sambuc 
child(parpid)103*433d6423SLionel Sambuc void child(parpid)
104*433d6423SLionel Sambuc int parpid;
105*433d6423SLionel Sambuc {
106*433d6423SLionel Sambuc 
107*433d6423SLionel Sambuc   int i;
108*433d6423SLionel Sambuc 
109*433d6423SLionel Sambuc   for (i = 0; i < 3; i++) {
110*433d6423SLionel Sambuc 	while (childsigs == 0);
111*433d6423SLionel Sambuc 	childsigs--;
112*433d6423SLionel Sambuc 	if (kill(parpid, SIGUSR1) < 0) e(9);
113*433d6423SLionel Sambuc   }
114*433d6423SLionel Sambuc   exit(6);
115*433d6423SLionel Sambuc }
116*433d6423SLionel Sambuc 
func1(s)117*433d6423SLionel Sambuc void func1(s)
118*433d6423SLionel Sambuc int s;				/* for ANSI */
119*433d6423SLionel Sambuc {
120*433d6423SLionel Sambuc   if (signal(SIGHUP, func1) == SIG_ERR) e(10);
121*433d6423SLionel Sambuc   childsigs++;
122*433d6423SLionel Sambuc }
123*433d6423SLionel Sambuc 
func8(s)124*433d6423SLionel Sambuc void func8(s)
125*433d6423SLionel Sambuc int s;
126*433d6423SLionel Sambuc {
127*433d6423SLionel Sambuc }
128*433d6423SLionel Sambuc 
func10(s)129*433d6423SLionel Sambuc void func10(s)
130*433d6423SLionel Sambuc int s;				/* for ANSI */
131*433d6423SLionel Sambuc {
132*433d6423SLionel Sambuc   if (signal(SIGUSR1, func10) == SIG_ERR) e(11);
133*433d6423SLionel Sambuc   parsigs++;
134*433d6423SLionel Sambuc }
135*433d6423SLionel Sambuc 
func11(s)136*433d6423SLionel Sambuc void func11(s)
137*433d6423SLionel Sambuc int s;				/* for ANSI */
138*433d6423SLionel Sambuc {
139*433d6423SLionel Sambuc   e(38);
140*433d6423SLionel Sambuc }
141*433d6423SLionel Sambuc 
test5b()142*433d6423SLionel Sambuc void test5b()
143*433d6423SLionel Sambuc {
144*433d6423SLionel Sambuc   int cpid, n, pid;
145*433d6423SLionel Sambuc 
146*433d6423SLionel Sambuc   subtest = 1;
147*433d6423SLionel Sambuc   if ((pid = fork()) != 0) {
148*433d6423SLionel Sambuc 	if (pid < 0) ex();
149*433d6423SLionel Sambuc 	if ((pid = fork()) != 0) {
150*433d6423SLionel Sambuc 		if (pid < 0) ex();
151*433d6423SLionel Sambuc 		if ((cpid = fork()) != 0) {
152*433d6423SLionel Sambuc 			if (cpid < 0) ex();
153*433d6423SLionel Sambuc 			if (kill(cpid, SIGKILL) < 0) e(12);
154*433d6423SLionel Sambuc 			if (wait(&n) < 0) e(13);
155*433d6423SLionel Sambuc 			if (wait(&n) < 0) e(14);
156*433d6423SLionel Sambuc 			if (wait(&n) < 0) e(15);
157*433d6423SLionel Sambuc 		} else {
158*433d6423SLionel Sambuc 			pause();
159*433d6423SLionel Sambuc 			while (1);
160*433d6423SLionel Sambuc 		}
161*433d6423SLionel Sambuc 	} else {
162*433d6423SLionel Sambuc 		exit(0);
163*433d6423SLionel Sambuc 	}
164*433d6423SLionel Sambuc   } else {
165*433d6423SLionel Sambuc 	exit(0);
166*433d6423SLionel Sambuc   }
167*433d6423SLionel Sambuc }
168*433d6423SLionel Sambuc 
test5c()169*433d6423SLionel Sambuc void test5c()
170*433d6423SLionel Sambuc {
171*433d6423SLionel Sambuc   int n, i, pid, wpid;
172*433d6423SLionel Sambuc 
173*433d6423SLionel Sambuc   /* Test exit status codes for processes killed by signals. */
174*433d6423SLionel Sambuc   subtest = 3;
175*433d6423SLionel Sambuc   for (i = 0; i < 2; i++) {
176*433d6423SLionel Sambuc 	if ((pid = fork()) != 0) {
177*433d6423SLionel Sambuc 		if (pid < 0) ex();
178*433d6423SLionel Sambuc 		sleep(2);	/* wait for child to pause */
179*433d6423SLionel Sambuc 		if (kill(pid, sigmap[i]) < 0) {
180*433d6423SLionel Sambuc 			e(20);
181*433d6423SLionel Sambuc 			exit(1);
182*433d6423SLionel Sambuc 		}
183*433d6423SLionel Sambuc 		if ((wpid = wait(&n)) < 0) e(21);
184*433d6423SLionel Sambuc 		if ((n & 077) != sigmap[i]) e(22);
185*433d6423SLionel Sambuc 		if (pid != wpid) e(23);
186*433d6423SLionel Sambuc 	} else {
187*433d6423SLionel Sambuc 		pause();
188*433d6423SLionel Sambuc 		exit(0);
189*433d6423SLionel Sambuc 	}
190*433d6423SLionel Sambuc   }
191*433d6423SLionel Sambuc }
192*433d6423SLionel Sambuc 
test5d()193*433d6423SLionel Sambuc void test5d()
194*433d6423SLionel Sambuc {
195*433d6423SLionel Sambuc /* Test alarm */
196*433d6423SLionel Sambuc 
197*433d6423SLionel Sambuc   int i;
198*433d6423SLionel Sambuc 
199*433d6423SLionel Sambuc   subtest = 4;
200*433d6423SLionel Sambuc   alarms = 0;
201*433d6423SLionel Sambuc   for (i = 0; i < 8; i++) {
202*433d6423SLionel Sambuc 	signal(SIGALRM, funcalrm);
203*433d6423SLionel Sambuc 	alarm(1);
204*433d6423SLionel Sambuc 	pause();
205*433d6423SLionel Sambuc 	if (alarms != i + 1) e(24);
206*433d6423SLionel Sambuc   }
207*433d6423SLionel Sambuc }
208*433d6423SLionel Sambuc 
test5e()209*433d6423SLionel Sambuc void test5e()
210*433d6423SLionel Sambuc {
211*433d6423SLionel Sambuc /* When a signal knocks a processes out of WAITPID or PAUSE, it is supposed to
212*433d6423SLionel Sambuc  * get EINTR as error status.  Check that.
213*433d6423SLionel Sambuc  */
214*433d6423SLionel Sambuc   int n;
215*433d6423SLionel Sambuc 
216*433d6423SLionel Sambuc   subtest = 5;
217*433d6423SLionel Sambuc   if (signal(SIGFPE, func8) == SIG_ERR) e(25);
218*433d6423SLionel Sambuc   if ((n = fork()) != 0) {
219*433d6423SLionel Sambuc 	/* Parent must delay to give child a chance to pause. */
220*433d6423SLionel Sambuc 	if (n < 0) ex();
221*433d6423SLionel Sambuc 	sleep(1);
222*433d6423SLionel Sambuc 	if (kill(n, SIGFPE) < 0) e(26);
223*433d6423SLionel Sambuc 	if (wait(&n) < 0) e(27);
224*433d6423SLionel Sambuc 	if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(28);
225*433d6423SLionel Sambuc   } else {
226*433d6423SLionel Sambuc 	(void) pause();
227*433d6423SLionel Sambuc 	if (errno != EINTR && -errno != EINTR) e(29);
228*433d6423SLionel Sambuc 	exit(0);
229*433d6423SLionel Sambuc   }
230*433d6423SLionel Sambuc }
231*433d6423SLionel Sambuc 
test5f()232*433d6423SLionel Sambuc void test5f()
233*433d6423SLionel Sambuc {
234*433d6423SLionel Sambuc   int i, j, k, n;
235*433d6423SLionel Sambuc 
236*433d6423SLionel Sambuc   subtest = 6;
237*433d6423SLionel Sambuc   if (getuid() != 0) return;
238*433d6423SLionel Sambuc   n = fork();
239*433d6423SLionel Sambuc   if (n < 0) ex();
240*433d6423SLionel Sambuc   if (n) {
241*433d6423SLionel Sambuc 	wait(&i);
242*433d6423SLionel Sambuc 	i = (i >> 8) & 0377;
243*433d6423SLionel Sambuc 	if (i != (n & 0377)) e(30);
244*433d6423SLionel Sambuc   } else {
245*433d6423SLionel Sambuc 	i = getgid();
246*433d6423SLionel Sambuc 	j = getegid();
247*433d6423SLionel Sambuc 	k = (i + j + 7) & 0377;
248*433d6423SLionel Sambuc 	if (setgid(k) < 0) e(31);
249*433d6423SLionel Sambuc 	if (getgid() != k) e(32);
250*433d6423SLionel Sambuc 	if (getegid() != k) e(33);
251*433d6423SLionel Sambuc 	i = getuid();
252*433d6423SLionel Sambuc 	j = geteuid();
253*433d6423SLionel Sambuc 	k = (i + j + 1) & 0377;
254*433d6423SLionel Sambuc 	if (setuid(k) < 0) e(34);
255*433d6423SLionel Sambuc 	if (getuid() != k) e(35);
256*433d6423SLionel Sambuc 	if (geteuid() != k) e(36);
257*433d6423SLionel Sambuc 	i = getpid() & 0377;
258*433d6423SLionel Sambuc 	if (wait(&j) != -1) e(37);
259*433d6423SLionel Sambuc 	exit(i);
260*433d6423SLionel Sambuc   }
261*433d6423SLionel Sambuc }
262*433d6423SLionel Sambuc 
test5g()263*433d6423SLionel Sambuc void test5g()
264*433d6423SLionel Sambuc {
265*433d6423SLionel Sambuc   int n;
266*433d6423SLionel Sambuc 
267*433d6423SLionel Sambuc   subtest = 7;
268*433d6423SLionel Sambuc   signal(SIGSEGV, func11);
269*433d6423SLionel Sambuc   signal(SIGSEGV, SIG_IGN);
270*433d6423SLionel Sambuc   n = getpid();
271*433d6423SLionel Sambuc   if (kill(n, SIGSEGV) != 0) e(1);
272*433d6423SLionel Sambuc   signal(SIGSEGV, SIG_DFL);
273*433d6423SLionel Sambuc }
274*433d6423SLionel Sambuc 
funcalrm(s)275*433d6423SLionel Sambuc void funcalrm(s)
276*433d6423SLionel Sambuc int s;				/* for ANSI */
277*433d6423SLionel Sambuc {
278*433d6423SLionel Sambuc   alarms++;
279*433d6423SLionel Sambuc }
280*433d6423SLionel Sambuc 
test5h()281*433d6423SLionel Sambuc void test5h()
282*433d6423SLionel Sambuc {
283*433d6423SLionel Sambuc /* When a signal knocks a processes out of PIPE, it is supposed to
284*433d6423SLionel Sambuc  * get EINTR as error status.  Check that.
285*433d6423SLionel Sambuc  */
286*433d6423SLionel Sambuc   int n, fd[2];
287*433d6423SLionel Sambuc 
288*433d6423SLionel Sambuc   subtest = 8;
289*433d6423SLionel Sambuc   unlink("XXX.test5");
290*433d6423SLionel Sambuc   if (signal(SIGFPE, func8) == SIG_ERR) e(1);
291*433d6423SLionel Sambuc   pipe(fd);
292*433d6423SLionel Sambuc   if ((n = fork()) != 0) {
293*433d6423SLionel Sambuc 	/* Parent must delay to give child a chance to pause. */
294*433d6423SLionel Sambuc 	if (n < 0) ex();
295*433d6423SLionel Sambuc 	while (access("XXX.test5", 0) != 0) /* just wait */ ;
296*433d6423SLionel Sambuc 	sleep(1);
297*433d6423SLionel Sambuc  	unlink("XXX.test5");
298*433d6423SLionel Sambuc 	if (kill(n, SIGFPE) < 0) e(2);
299*433d6423SLionel Sambuc 	if (wait(&n) < 0) e(3);
300*433d6423SLionel Sambuc 	if (signal(SIGFPE, SIG_DFL) == SIG_ERR) e(4);
301*433d6423SLionel Sambuc 	if (close(fd[0]) != 0) e(5);
302*433d6423SLionel Sambuc 	if (close(fd[1]) != 0) e(6);
303*433d6423SLionel Sambuc   } else {
304*433d6423SLionel Sambuc 	if (creat("XXX.test5", 0777) < 0) e(7);
305*433d6423SLionel Sambuc 	(void) read(fd[0], (char *) &n, 1);
306*433d6423SLionel Sambuc 	if (errno != EINTR) e(8);
307*433d6423SLionel Sambuc 	exit(0);
308*433d6423SLionel Sambuc   }
309*433d6423SLionel Sambuc }
310*433d6423SLionel Sambuc 
test5i()311*433d6423SLionel Sambuc void test5i()
312*433d6423SLionel Sambuc {
313*433d6423SLionel Sambuc   int fd[2], pid, buf[10], n;
314*433d6423SLionel Sambuc 
315*433d6423SLionel Sambuc   subtest = 9;
316*433d6423SLionel Sambuc   pipe(fd);
317*433d6423SLionel Sambuc   unlink("XXXxxxXXX");
318*433d6423SLionel Sambuc 
319*433d6423SLionel Sambuc   if ((pid = fork()) != 0) {
320*433d6423SLionel Sambuc 	/* Parent */
321*433d6423SLionel Sambuc 	/* Wait until child has started and has created the XXXxxxXXX file. */
322*433d6423SLionel Sambuc 	while (access("XXXxxxXXX", 0) != 0) /* loop */ ;
323*433d6423SLionel Sambuc 	sleep(1);
324*433d6423SLionel Sambuc 	if (kill(pid, SIGKILL) != 0) e(1);
325*433d6423SLionel Sambuc 	if (wait(&n) < 0) e(2);
326*433d6423SLionel Sambuc 	if (close(fd[0]) != 0) e(3);
327*433d6423SLionel Sambuc 	if (close(fd[1]) != 0) e(4);
328*433d6423SLionel Sambuc   } else {
329*433d6423SLionel Sambuc 	if (creat("XXXxxxXXX", 0777) < 0) e(5);
330*433d6423SLionel Sambuc 	read(fd[0], (char *) buf, 1);
331*433d6423SLionel Sambuc 	e(5);		/* should be killed by signal and not get here */
332*433d6423SLionel Sambuc   }
333*433d6423SLionel Sambuc   unlink("XXXxxxXXX");
334*433d6423SLionel Sambuc }
335*433d6423SLionel Sambuc 
ex()336*433d6423SLionel Sambuc void ex()
337*433d6423SLionel Sambuc {
338*433d6423SLionel Sambuc   int e = errno;
339*433d6423SLionel Sambuc   printf("Fork failed: %s (%d)\n", strerror(e), e);
340*433d6423SLionel Sambuc   exit(1);
341*433d6423SLionel Sambuc }
342*433d6423SLionel Sambuc 
343