1*433d6423SLionel Sambuc #include <unistd.h>
2*433d6423SLionel Sambuc #include <stdio.h>
3*433d6423SLionel Sambuc #include <stdlib.h>
4*433d6423SLionel Sambuc #include <sys/types.h>
5*433d6423SLionel Sambuc #include <sys/wait.h>
6*433d6423SLionel Sambuc #include <signal.h>
7*433d6423SLionel Sambuc #include <math.h>
8*433d6423SLionel Sambuc
9*433d6423SLionel Sambuc #define ROUNDS 20
10*433d6423SLionel Sambuc #define SWAPS 40
11*433d6423SLionel Sambuc int max_error = 5;
12*433d6423SLionel Sambuc #include "common.h"
13*433d6423SLionel Sambuc
14*433d6423SLionel Sambuc
15*433d6423SLionel Sambuc
16*433d6423SLionel Sambuc int pipefdc[2];
17*433d6423SLionel Sambuc int pipefdp[2];
18*433d6423SLionel Sambuc int subtest = 0;
19*433d6423SLionel Sambuc int child_is_dead = 0;
20*433d6423SLionel Sambuc
21*433d6423SLionel Sambuc void dead_child(int n);
22*433d6423SLionel Sambuc void do_child(void);
23*433d6423SLionel Sambuc void do_parent(void);
24*433d6423SLionel Sambuc void do_calcs(void);
25*433d6423SLionel Sambuc void err(int n);
26*433d6423SLionel Sambuc void quit(void);
27*433d6423SLionel Sambuc
err(int n)28*433d6423SLionel Sambuc void err(int n)
29*433d6423SLionel Sambuc {
30*433d6423SLionel Sambuc e(n);
31*433d6423SLionel Sambuc }
32*433d6423SLionel Sambuc
do_calcs(void)33*433d6423SLionel Sambuc void do_calcs(void)
34*433d6423SLionel Sambuc {
35*433d6423SLionel Sambuc float a, b, c, d, e;
36*433d6423SLionel Sambuc float foo, bar;
37*433d6423SLionel Sambuc int i;
38*433d6423SLionel Sambuc subtest = 3;
39*433d6423SLionel Sambuc
40*433d6423SLionel Sambuc a = 1.1;
41*433d6423SLionel Sambuc b = 2.2;
42*433d6423SLionel Sambuc c = 3.3;
43*433d6423SLionel Sambuc d = 4.4;
44*433d6423SLionel Sambuc e = 5.5;
45*433d6423SLionel Sambuc
46*433d6423SLionel Sambuc foo = a * b; /* 2.42 */
47*433d6423SLionel Sambuc bar = c * d; /* 14.52 */
48*433d6423SLionel Sambuc
49*433d6423SLionel Sambuc i = 0;
50*433d6423SLionel Sambuc while(i < ROUNDS) {
51*433d6423SLionel Sambuc foo += c; /* 5.72 */
52*433d6423SLionel Sambuc foo *= d; /* 25.168 */
53*433d6423SLionel Sambuc foo /= e; /* 4.5760 */
54*433d6423SLionel Sambuc bar -= a; /* 13.42 */
55*433d6423SLionel Sambuc bar *= b; /* 29.524 */
56*433d6423SLionel Sambuc bar /= e; /* 5.3680 */
57*433d6423SLionel Sambuc
58*433d6423SLionel Sambuc /* Undo */
59*433d6423SLionel Sambuc foo *= e;
60*433d6423SLionel Sambuc foo /= d;
61*433d6423SLionel Sambuc foo -= c;
62*433d6423SLionel Sambuc
63*433d6423SLionel Sambuc bar *= e;
64*433d6423SLionel Sambuc bar /= b;
65*433d6423SLionel Sambuc bar += a;
66*433d6423SLionel Sambuc
67*433d6423SLionel Sambuc i++;
68*433d6423SLionel Sambuc }
69*433d6423SLionel Sambuc
70*433d6423SLionel Sambuc if (fabs(foo - (a * b)) > 0.0001) err(1);
71*433d6423SLionel Sambuc if (fabs(bar - (c * d)) > 0.0001) err(2);
72*433d6423SLionel Sambuc }
73*433d6423SLionel Sambuc
dead_child(int n)74*433d6423SLionel Sambuc void dead_child(int n)
75*433d6423SLionel Sambuc {
76*433d6423SLionel Sambuc int status;
77*433d6423SLionel Sambuc subtest = 4;
78*433d6423SLionel Sambuc
79*433d6423SLionel Sambuc (void) n; /* Avoid warning about unused parameter */
80*433d6423SLionel Sambuc
81*433d6423SLionel Sambuc if (wait(&status) == -1) err(1);
82*433d6423SLionel Sambuc
83*433d6423SLionel Sambuc if (!WIFEXITED(status)) {
84*433d6423SLionel Sambuc err(2);
85*433d6423SLionel Sambuc quit();
86*433d6423SLionel Sambuc } else {
87*433d6423SLionel Sambuc errct += WEXITSTATUS(status);
88*433d6423SLionel Sambuc child_is_dead = 1;
89*433d6423SLionel Sambuc }
90*433d6423SLionel Sambuc }
91*433d6423SLionel Sambuc
do_child(void)92*433d6423SLionel Sambuc void do_child(void)
93*433d6423SLionel Sambuc {
94*433d6423SLionel Sambuc char buf[2];
95*433d6423SLionel Sambuc int s;
96*433d6423SLionel Sambuc
97*433d6423SLionel Sambuc s = 0;
98*433d6423SLionel Sambuc close(pipefdp[0]);
99*433d6423SLionel Sambuc close(pipefdc[1]);
100*433d6423SLionel Sambuc
101*433d6423SLionel Sambuc while(s < SWAPS) {
102*433d6423SLionel Sambuc do_calcs();
103*433d6423SLionel Sambuc
104*433d6423SLionel Sambuc /* Wake up parent */
105*433d6423SLionel Sambuc write(pipefdp[1], buf, 1);
106*433d6423SLionel Sambuc
107*433d6423SLionel Sambuc /* Wait for parent to wake me up */
108*433d6423SLionel Sambuc read(pipefdc[0], buf, 1);
109*433d6423SLionel Sambuc
110*433d6423SLionel Sambuc s++;
111*433d6423SLionel Sambuc }
112*433d6423SLionel Sambuc exit(0);
113*433d6423SLionel Sambuc }
114*433d6423SLionel Sambuc
do_parent(void)115*433d6423SLionel Sambuc void do_parent(void)
116*433d6423SLionel Sambuc {
117*433d6423SLionel Sambuc int s;
118*433d6423SLionel Sambuc char buf[2];
119*433d6423SLionel Sambuc struct sigaction sa;
120*433d6423SLionel Sambuc subtest = 2;
121*433d6423SLionel Sambuc
122*433d6423SLionel Sambuc sa.sa_handler = dead_child;
123*433d6423SLionel Sambuc sa.sa_flags = 0;
124*433d6423SLionel Sambuc if (sigaction(SIGCHLD, &sa, NULL) == -1) err(1);
125*433d6423SLionel Sambuc
126*433d6423SLionel Sambuc s = 0;
127*433d6423SLionel Sambuc close(pipefdp[1]);
128*433d6423SLionel Sambuc close(pipefdc[0]);
129*433d6423SLionel Sambuc
130*433d6423SLionel Sambuc while(s < SWAPS) {
131*433d6423SLionel Sambuc /* Wait for child to wake me up */
132*433d6423SLionel Sambuc read(pipefdp[0], buf, 1);
133*433d6423SLionel Sambuc
134*433d6423SLionel Sambuc do_calcs();
135*433d6423SLionel Sambuc
136*433d6423SLionel Sambuc /* Wake up child */
137*433d6423SLionel Sambuc write(pipefdc[1], buf, 1);
138*433d6423SLionel Sambuc s++;
139*433d6423SLionel Sambuc }
140*433d6423SLionel Sambuc
141*433d6423SLionel Sambuc while(child_is_dead == 0) { fflush(stdout); } /* Busy wait */
142*433d6423SLionel Sambuc
143*433d6423SLionel Sambuc quit();
144*433d6423SLionel Sambuc }
145*433d6423SLionel Sambuc
main(void)146*433d6423SLionel Sambuc int main(void)
147*433d6423SLionel Sambuc {
148*433d6423SLionel Sambuc pid_t r;
149*433d6423SLionel Sambuc subtest = 1;
150*433d6423SLionel Sambuc
151*433d6423SLionel Sambuc start(52);
152*433d6423SLionel Sambuc
153*433d6423SLionel Sambuc if (pipe(pipefdc) == -1) err(1);
154*433d6423SLionel Sambuc if (pipe(pipefdp) == -1) err(2);
155*433d6423SLionel Sambuc
156*433d6423SLionel Sambuc r = fork();
157*433d6423SLionel Sambuc if(r < 0) {
158*433d6423SLionel Sambuc err(3);
159*433d6423SLionel Sambuc } else if(r == 0) {
160*433d6423SLionel Sambuc /* Child */
161*433d6423SLionel Sambuc do_child();
162*433d6423SLionel Sambuc } else {
163*433d6423SLionel Sambuc /* Parent */
164*433d6423SLionel Sambuc do_parent();
165*433d6423SLionel Sambuc }
166*433d6423SLionel Sambuc
167*433d6423SLionel Sambuc return(0); /* Never reached */
168*433d6423SLionel Sambuc
169*433d6423SLionel Sambuc }
170*433d6423SLionel Sambuc
171