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 sleep(20);
349 rand_next += 1;
350 }
351 }