This source file includes following definitions.
- do_rand
- rand
- go
- iter
- main
1
2
3
4
5 #include "kernel/param.h"
6 #include "kernel/types.h"
7 #include "kernel/stat.h"
8 #include "user/user.h"
9 #include "kernel/fs.h"
10 #include "kernel/fcntl.h"
11 #include "kernel/syscall.h"
12 #include "kernel/memlayout.h"
13 #include "kernel/riscv.h"
14
15
16 int
17 do_rand(unsigned long *ctx)
18 {
19
20
21
22
23
24
25
26
27 long hi, lo, x;
28
29
30 x = (*ctx % 0x7ffffffe) + 1;
31 hi = x / 127773;
32 lo = x % 127773;
33 x = 16807 * lo - 2836 * hi;
34 if (x < 0)
35 x += 0x7fffffff;
36
37 x--;
38 *ctx = x;
39 return (x);
40 }
41
42 unsigned long rand_next = 1;
43
44 int
45 rand(void)
46 {
47 return (do_rand(&rand_next));
48 }
49
50 void
51 go(int which_child)
52 {
53 int fd = -1;
54 static char buf[999];
55 char *break0 = sbrk(0);
56 uint64 iters = 0;
57
58 mkdir("grindir");
59 if (chdir("grindir") != 0) {
60 printf("grind: chdir grindir failed\n");
61 exit(1);
62 }
63 chdir("/");
64
65 while (1) {
66 iters++;
67 if ((iters % 500) == 0)
68 write(1, which_child ? "B" : "A", 1);
69 int what = rand() % 23;
70 if (what == 1) {
71 close(open("grindir/../a", O_CREATE | O_RDWR));
72 } else if (what == 2) {
73 close(open("grindir/../grindir/../b", O_CREATE | O_RDWR));
74 } else if (what == 3) {
75 unlink("grindir/../a");
76 } else if (what == 4) {
77 if (chdir("grindir") != 0) {
78 printf("grind: chdir grindir failed\n");
79 exit(1);
80 }
81 unlink("../b");
82 chdir("/");
83 } else if (what == 5) {
84 close(fd);
85 fd = open("/grindir/../a", O_CREATE | O_RDWR);
86 } else if (what == 6) {
87 close(fd);
88 fd = open("/./grindir/./../b", O_CREATE | O_RDWR);
89 } else if (what == 7) {
90 write(fd, buf, sizeof(buf));
91 } else if (what == 8) {
92 read(fd, buf, sizeof(buf));
93 } else if (what == 9) {
94 mkdir("grindir/../a");
95 close(open("a/../a/./a", O_CREATE | O_RDWR));
96 unlink("a/a");
97 } else if (what == 10) {
98 mkdir("/../b");
99 close(open("grindir/../b/b", O_CREATE | O_RDWR));
100 unlink("b/b");
101 } else if (what == 11) {
102 unlink("b");
103 link("../grindir/./../a", "../b");
104 } else if (what == 12) {
105 unlink("../grindir/../a");
106 link(".././b", "/grindir/../a");
107 } else if (what == 13) {
108 int pid = fork();
109 if (pid == 0) {
110 exit(0);
111 } else if (pid < 0) {
112 printf("grind: fork failed\n");
113 exit(1);
114 }
115 wait(0);
116 } else if (what == 14) {
117 int pid = fork();
118 if (pid == 0) {
119 fork();
120 fork();
121 exit(0);
122 } else if (pid < 0) {
123 printf("grind: fork failed\n");
124 exit(1);
125 }
126 wait(0);
127 } else if (what == 15) {
128 sbrk(6011);
129 } else if (what == 16) {
130 if (sbrk(0) > break0)
131 sbrk(-(sbrk(0) - break0));
132 } else if (what == 17) {
133 int pid = fork();
134 if (pid == 0) {
135 close(open("a", O_CREATE | O_RDWR));
136 exit(0);
137 } else if (pid < 0) {
138 printf("grind: fork failed\n");
139 exit(1);
140 }
141 if (chdir("../grindir/..") != 0) {
142 printf("grind: chdir failed\n");
143 exit(1);
144 }
145 kill(pid);
146 wait(0);
147 } else if (what == 18) {
148 int pid = fork();
149 if (pid == 0) {
150 kill(getpid());
151 exit(0);
152 } else if (pid < 0) {
153 printf("grind: fork failed\n");
154 exit(1);
155 }
156 wait(0);
157 } else if (what == 19) {
158 int fds[2];
159 if (pipe(fds) < 0) {
160 printf("grind: pipe failed\n");
161 exit(1);
162 }
163 int pid = fork();
164 if (pid == 0) {
165 fork();
166 fork();
167 if (write(fds[1], "x", 1) != 1)
168 printf("grind: pipe write failed\n");
169 char c;
170 if (read(fds[0], &c, 1) != 1)
171 printf("grind: pipe read failed\n");
172 exit(0);
173 } else if (pid < 0) {
174 printf("grind: fork failed\n");
175 exit(1);
176 }
177 close(fds[0]);
178 close(fds[1]);
179 wait(0);
180 } else if (what == 20) {
181 int pid = fork();
182 if (pid == 0) {
183 unlink("a");
184 mkdir("a");
185 chdir("a");
186 unlink("../a");
187 fd = open("x", O_CREATE | O_RDWR);
188 unlink("x");
189 exit(0);
190 } else if (pid < 0) {
191 printf("grind: fork failed\n");
192 exit(1);
193 }
194 wait(0);
195 } else if (what == 21) {
196 unlink("c");
197
198
199 int fd1 = open("c", O_CREATE | O_RDWR);
200 if (fd1 < 0) {
201 printf("grind: create c failed\n");
202 exit(1);
203 }
204 if (write(fd1, "x", 1) != 1) {
205 printf("grind: write c failed\n");
206 exit(1);
207 }
208 struct stat st;
209 if (fstat(fd1, &st) != 0) {
210 printf("grind: fstat failed\n");
211 exit(1);
212 }
213 if (st.size != 1) {
214 printf("grind: fstat reports wrong size %d\n", (int)st.size);
215 exit(1);
216 }
217 if (st.ino > 200) {
218 printf("grind: fstat reports crazy i-number %d\n", st.ino);
219 exit(1);
220 }
221 close(fd1);
222 unlink("c");
223 } else if (what == 22) {
224
225 int aa[2], bb[2];
226 if (pipe(aa) < 0) {
227 fprintf(2, "grind: pipe failed\n");
228 exit(1);
229 }
230 if (pipe(bb) < 0) {
231 fprintf(2, "grind: pipe failed\n");
232 exit(1);
233 }
234 int pid1 = fork();
235 if (pid1 == 0) {
236 close(bb[0]);
237 close(bb[1]);
238 close(aa[0]);
239 close(1);
240 if (dup(aa[1]) != 1) {
241 fprintf(2, "grind: dup failed\n");
242 exit(1);
243 }
244 close(aa[1]);
245 char *args[3] = {"echo", "hi", 0};
246 exec("grindir/../echo", args);
247 fprintf(2, "grind: echo: not found\n");
248 exit(2);
249 } else if (pid1 < 0) {
250 fprintf(2, "grind: fork failed\n");
251 exit(3);
252 }
253 int pid2 = fork();
254 if (pid2 == 0) {
255 close(aa[1]);
256 close(bb[0]);
257 close(0);
258 if (dup(aa[0]) != 0) {
259 fprintf(2, "grind: dup failed\n");
260 exit(4);
261 }
262 close(aa[0]);
263 close(1);
264 if (dup(bb[1]) != 1) {
265 fprintf(2, "grind: dup failed\n");
266 exit(5);
267 }
268 close(bb[1]);
269 char *args[2] = {"cat", 0};
270 exec("/cat", args);
271 fprintf(2, "grind: cat: not found\n");
272 exit(6);
273 } else if (pid2 < 0) {
274 fprintf(2, "grind: fork failed\n");
275 exit(7);
276 }
277 close(aa[0]);
278 close(aa[1]);
279 close(bb[1]);
280 char buf[4] = {0, 0, 0, 0};
281 read(bb[0], buf + 0, 1);
282 read(bb[0], buf + 1, 1);
283 read(bb[0], buf + 2, 1);
284 close(bb[0]);
285 int st1, st2;
286 wait(&st1);
287 wait(&st2);
288 if (st1 != 0 || st2 != 0 || strcmp(buf, "hi\n") != 0) {
289 printf("grind: exec pipeline failed %d %d \"%s\"\n", st1, st2, buf);
290 exit(1);
291 }
292 }
293 }
294 }
295
296 void
297 iter()
298 {
299 unlink("a");
300 unlink("b");
301
302 int pid1 = fork();
303 if (pid1 < 0) {
304 printf("grind: fork failed\n");
305 exit(1);
306 }
307 if (pid1 == 0) {
308 rand_next ^= 31;
309 go(0);
310 exit(0);
311 }
312
313 int pid2 = fork();
314 if (pid2 < 0) {
315 printf("grind: fork failed\n");
316 exit(1);
317 }
318 if (pid2 == 0) {
319 rand_next ^= 7177;
320 go(1);
321 exit(0);
322 }
323
324 int st1 = -1;
325 wait(&st1);
326 if (st1 != 0) {
327 kill(pid1);
328 kill(pid2);
329 }
330 int st2 = -1;
331 wait(&st2);
332
333 exit(0);
334 }
335
336 int
337 main()
338 {
339 while (1) {
340 int pid = fork();
341 if (pid == 0) {
342 iter();
343 exit(0);
344 }
345 if (pid > 0) {
346 wait(0);
347 }
348 pause(20);
349 rand_next += 1;
350 }
351 }