1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Open operation C testcase */
28
29 #include "nfsgen.h"
30
31 /* Functions */
32 int scenarioA(int mode, int oflag, int expect[]);
33 int scenarioB(int mode, int oflag, int expect[]);
34 int scenarioC(int mode, int oflag, int expect[]);
35 int scenarioD(int mode, int oflag, int expect[]);
36 int scenarioE(int mode, int oflag, int expect[]);
37
38 /* Globals */
39
40 static char *filename = NULL;
41 char *buf = NULL;
42
43 /*
44 * Main test loop.
45 */
46
47 int
48 main(int argc, char **argv)
49 {
50 int i, j;
51 int ret = OK;
52 char *deleg, *scen, *mode_index, *oflag_index;
53 static int mode_set[] = {0600, 0400, 0200, 000},
54 mode_setC[] = {0660, 0600, 0440, 0400, 0220, 0200,
55 000},
56 oflag_set[] = {O_EXCL|O_RDWR, O_RDWR, O_WRONLY,
57 O_RDONLY};
58 static int expectA[4][4][4] =
59 {
60 { {OK, OK, OK, OK},
61 {OK, OK, OK, OK},
62 {OK, OK, EBADF, OK},
63 {OK, OK, OK, EBADF}},
64 { {EACCES, EBADF, EBADF, EBADF},
65 {EACCES, EBADF, EBADF, EBADF},
66 {EACCES, EBADF, EBADF, EBADF},
67 {OK, OK, OK, EBADF}},
68 { {EACCES, EBADF, EBADF, EBADF},
69 {EACCES, EBADF, EBADF, EBADF},
70 {OK, OK, EBADF, OK},
71 {EACCES, EBADF, EBADF, EBADF}},
72 { {EACCES, EBADF, EBADF, EBADF},
73 {EACCES, EBADF, EBADF, EBADF},
74 {EACCES, EBADF, EBADF, EBADF},
75 {EACCES, EBADF, EBADF, EBADF}}
76 };
77
78 static int expectB[4][4][4] =
79 {
80 { {OK, OK, OK, OK},
81 {OK, OK, OK, OK},
82 {OK, OK, EBADF, OK},
83 {OK, OK, OK, EBADF}},
84 { {EACCES, EBADF, EBADF, EBADF},
85 {EACCES, EBADF, EBADF, EBADF},
86 {EACCES, EBADF, EBADF, EBADF},
87 {OK, OK, OK, EBADF}},
88 { {EACCES, EBADF, EBADF, EBADF},
89 {EACCES, EBADF, EBADF, EBADF},
90 {OK, OK, EBADF, OK},
91 {EACCES, EBADF, EBADF, EBADF}},
92 { {EACCES, EBADF, EBADF, EBADF},
93 {EACCES, EBADF, EBADF, EBADF},
94 {EACCES, EBADF, EBADF, EBADF},
95 {EACCES, EBADF, EBADF, EBADF}}
96 };
97
98 static int expectC[7][4][6] =
99 {
100 { {OK, OK, OK, OK, OK, OK},
101 {OK, OK, OK, OK, OK, OK},
102 {OK, OK, EBADF, OK, EBADF, OK},
103 {OK, OK, OK, EBADF, OK, EBADF}},
104 { {OK, OK, OK, OK, EBADF, EBADF},
105 {OK, OK, OK, OK, EBADF, EBADF},
106 {OK, OK, EBADF, OK, EBADF, EBADF},
107 {OK, OK, OK, EBADF, EBADF, EBADF}},
108 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
109 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
110 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
111 {OK, OK, OK, EBADF, OK, EBADF}},
112 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
113 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
114 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
115 {OK, OK, OK, EBADF, EBADF, EBADF}},
116 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
117 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
118 {OK, OK, EBADF, OK, EBADF, OK},
119 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF}},
120 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
121 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
122 {OK, OK, EBADF, OK, EBADF, EBADF},
123 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF}},
124 { {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
125 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
126 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF},
127 {EACCES, EBADF, EBADF, EBADF, EBADF, EBADF}}
128 };
129
130 if ((buf = malloc(256)) == NULL) {
131 perror("main()- malloc() for buf");
132 return (NOOK);
133 }
134
135 parse_args(argc, argv);
136
137 filename = lfilename;
138
139 dprint("Try to remove test files, to avoid errors.\n");
140 unlink_file(filename);
141 unlink_file("olinkfile.txt");
142
143 /* modify name to include delgation policy */
144 if ((deleg = getenv("DELG")) != NULL) {
145 if (strcasecmp(deleg, "on") == 0) {
146 strcat(Testname, "_Deleg");
147 }
148 if (strcasecmp(deleg, "off") == 0) {
149 strcat(Testname, "_NoDeleg");
150 }
151 }
152
153 scen = getenv("SCENARIO");
154 if (!scen) {
155 printf("The scenario was not specified");
156 return (NOOK);
157 }
158
159 if ((mode_index = getenv("MODE_INDEX")) != NULL) {
160 i = atoi(mode_index);
161 if ((i > 3) && (strcmp(scen, "C") != 0)) {
162 printf("The mode index(%d) is more than 3 "\
163 "with scenario %s", i, scen);
164 return (NOOK);
165 } else if (i > 6) {
166 printf("The mode index(%d) is more than 6 "\
167 "with scenario %s", i, scen);
168 return (NOOK);
169 }
170 }
171
172 if ((oflag_index = getenv("OFLAG_INDEX")) != NULL) {
173 j = atoi(oflag_index);
174 if (j > 3) {
175 printf("The oflag index(%d) is more than 3 "\
176 "with scenario %s", i, scen);
177 return (NOOK);
178 }
179 }
180
181 /* run tests */
182 switch (*scen) {
183 case 'A':
184 ret = scenarioA(mode_set[i], oflag_set[j], expectA[i][j]);
185 break;
186 case 'B':
187 ret = scenarioB(mode_set[i], oflag_set[j], expectB[i][j]);
188 break;
189 case 'C':
190 ret = scenarioC(mode_setC[i], oflag_set[j], expectC[i][j]);
191 break;
192 case 'D':
193 ret = scenarioD(mode_set[i], oflag_set[j], NULL);
194 break;
195 case 'E':
196 ret = scenarioE(0755, O_TRUNC, OK);
197 break;
198 default:
199 printf("Set invalid scenario(%s)", scen);
200 return (NOOK);
201 }
202
203 if (buf != NULL)
204 free(buf);
205 if (GLOBdata != NULL)
206 free(GLOBdata);
207
208 exit_test(ret);
209 return (ret); /* unreachable, used to quiet lint */
210 }
211
212 int
213 scenarioA(int mode, int oflag, int expect[])
214 {
215 int fd1, fd2;
216 char *DD;
217 int ret = OK;
218
219 scen = "ScenA";
220 scen_mode = mode;
221 scen_flag = oflag;
222 expecterr = expect[0];
223
224 fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and "\
225 "oflag = %s\n\n", mode, oflagstr(oflag));
226
227 DD = strbackup("#123456789#123456789#123456789");
228
229 if (create_test_data_file(filename, mode)) {
230 printf("The scenario initialization failed, "\
231 "and other subassertions won't run.\n\n");
232 exit_test(NOOK);
233 }
234
235 /* assertion a) */
236 assertion("a", "Open a file (fd1)", "multiple");
237 fd1 = open_file(filename, oflag, mode);
238 tresult(expect[0], errno);
239 admerrors(ASSERT);
240 if (fd1 < 0) {
241 if (expect[0] == OK) {
242 printf("scenarioA{rest}: open call\n");
243 printf("\t Test OTHER: unexpected open failure\n");
244 ret = NOOK;
245 }
246 print("Scenario A, skipping rest of scenario.\n");
247 goto clean_up;
248 }
249
250 /* assertion a1) */
251 assertion("a1", "dup() fd1 desc on fd2", "multiple");
252 fd2 = dupfile(fd1);
253 tresult(expect[1], errno);
254 admerrors(ASSERT);
255
256 /* initialize pipes and create the child */
257 initialize();
258
259 if (me == PARENT) {
260 /* assertion b) */
261 assertion("b", "Parent close the first file desc (fd1)",
262 errtostr(expect[1]));
263 close_file(fd1, filename);
264 tresult(expect[1], errno);
265 admerrors(ASSERT);
266 contch();
267 waitp();
268 }
269
270 if (me == CHILD) {
271 waitch();
272
273 /* assertion c) */
274 assertion("c", "Child checks read/write on fd1 and fd2",
275 "multiple");
276 read_file(fd1, filename, buf, 0, 26);
277 tresult(expect[2], errno);
278 read_file(fd2, filename, buf, 0, 26);
279 tresult(expect[2], errno);
280
281 write_file(fd1, filename, DD, 0, 26);
282 tresult(expect[3], errno);
283 write_file(fd2, filename, DD, 0, 26);
284 tresult(expect[3], errno);
285 admerrors(ASSERT);
286 contp();
287 waitch();
288 }
289
290 if (me == PARENT) {
291 /* assertion d) */
292 assertion("d", "Parent checks read/write on fd1 and fd2",
293 "multiple");
294 read_file(fd1, filename, buf, 0, 26);
295 tresult(EBADF, errno);
296 read_file(fd2, filename, buf, 0, 26);
297 tresult(expect[2], errno);
298
299 write_file(fd1, filename, DD, 0, 26);
300 tresult(EBADF, errno);
301 write_file(fd2, filename, DD, 0, 26);
302 tresult(expect[3], errno);
303 admerrors(ASSERT);
304 contch();
305 waitp();
306 }
307
308 if (me == CHILD) {
309 /* assertion e) */
310 assertion("e", "Child closes both fd1 and fd2", "multiple");
311 close_file(fd1, filename);
312 tresult(expect[1], errno);
313 close_file(fd2, filename);
314 tresult(expect[1], errno);
315 admerrors(ASSERT);
316 contp();
317 wait_send_cresult();
318
319 while (1)
320 sleep(1);
321 }
322
323 if (me == PARENT) {
324 /* assertion f) */
325 assertion("f", "Parent checks read/write on fd1 and fd2,\n"
326 "\tand kill child proc", "multiple");
327 read_file(fd1, filename, buf, 0, 26);
328 tresult(EBADF, errno);
329 read_file(fd2, filename, buf, 0, 26);
330 tresult(expect[2], errno);
331
332 write_file(fd1, filename, DD, 0, 26);
333 tresult(EBADF, errno);
334 write_file(fd2, filename, DD, 0, 26);
335 tresult(expect[3], errno);
336 admerrors(ASSERT);
337
338 if (wait_get_cresult())
339 ret = NOOK;
340 kill_child(OK);
341
342 /* assertion g) */
343 assertion("g", "Parent checks read/write on fd1 and fd2",
344 "multiple");
345 read_file(fd1, filename, buf, 0, 26);
346 tresult(EBADF, errno);
347 read_file(fd2, filename, buf, 0, 26);
348 tresult(expect[2], errno);
349
350 write_file(fd1, filename, DD, 0, 26);
351 tresult(EBADF, errno);
352 write_file(fd2, filename, DD, 0, 26);
353 tresult(expect[3], errno);
354 admerrors(ASSERT);
355 goto clean_up;
356 }
357
358 if (me == CHILD) {
359 print("ERROR: child should be dead. Quitting ...\n");
360 exit_test(NOOK);
361 }
362
363 clean_up:
364 {
365 int tmp = debug;
366 int tme = showerror;
367
368 debug = 0;
369 showerror = 0;
370 close_file(fd1, filename);
371 showerror = tme;
372 debug = tmp;
373
374 close_file(fd2, filename);
375 unlink_file(filename);
376 }
377
378 if (admerrors(SCENARIO))
379 ret = NOOK;
380 print("Scenario A finished.\n\n\n");
381 return (ret);
382 }
383
384 int
385 scenarioB(int mode, int oflag, int expect[])
386 {
387 int fd1, fd2;
388 char *DD;
389 int ret = OK;
390
391 scen = "ScenB";
392 scen_mode = mode;
393 scen_flag = oflag;
394 expecterr = expect[0];
395
396 fprintf(stdout, "\n\nExecuting Scenario B, with mode = 0%o and "\
397 "oflag = %s\n\n", mode, oflagstr(oflag));
398
399 DD = strbackup("#123456789#123456789#123456789");
400
401 if ((create_test_data_file(filename, mode)) ||
402 link_file(filename, "olinkfile.txt")) {
403 printf("The scenario initialization failed, "\
404 "and other subassertions won't run.\n\n");
405 exit_test(NOOK);
406 }
407
408 /* assertion a) */
409 assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
410 fd1 = open_file(filename, oflag, mode);
411 tresult(expect[0], errno);
412 admerrors(ASSERT);
413
414 /* assertion b) */
415 assertion("b", "Open hardlink to original file using fd2",
416 errtostr(expect[0]));
417 fd2 = open_file("olinkfile.txt", oflag, mode);
418 tresult(expect[0], errno);
419 admerrors(ASSERT);
420 if (fd2 < 0) {
421 if (expect[0] == OK) {
422 printf("scenarioB{rest}: open calls\n");
423 printf("\t Test OTHER: unexpected open failure\n");
424 }
425 print("Scenario B, skipping rest of scenario.\n");
426 goto clean_up;
427 }
428
429 /* initialize pipes and create the child */
430 initialize();
431
432 if (me == PARENT) {
433 /* assertion c) */
434 assertion("c", "Parent close fd1", errtostr(expect[1]));
435 close_file(fd1, filename);
436 tresult(expect[1], errno);
437 admerrors(ASSERT);
438 contch();
439 waitp();
440 }
441
442 if (me == CHILD) {
443 waitch();
444
445 /* assertion d) */
446 assertion("d", "Child checks read/write on fd1 and fd2",
447 "multiple");
448 read_file(fd1, filename, buf, 0, 26);
449 tresult(expect[2], errno);
450 read_file(fd2, "olinkfile.txt", buf, 0, 26);
451 tresult(expect[2], errno);
452
453 write_file(fd1, filename, DD, 0, 26);
454 tresult(expect[3], errno);
455 write_file(fd2, "olinkfile.txt", DD, 0, 26);
456 tresult(expect[3], errno);
457 admerrors(ASSERT);
458 contp();
459 waitch();
460 }
461
462 if (me == PARENT) {
463 /* assertion e) */
464 assertion("e", "Parent checks read/write on fd1 and fd2",
465 "multiple");
466 read_file(fd1, filename, buf, 0, 26);
467 tresult(EBADF, errno);
468 read_file(fd2, "olinkfile.txt", buf, 0, 26);
469 tresult(expect[2], errno);
470
471 write_file(fd1, filename, DD, 0, 26);
472 tresult(EBADF, errno);
473 write_file(fd2, "olinkfile.txt", DD, 0, 26);
474 tresult(expect[3], errno);
475 admerrors(ASSERT);
476 contch();
477 waitp();
478 }
479
480 if (me == CHILD) {
481 /* assertion f) */
482 assertion("f", "Child closes fd1 and fd2", "multiple");
483 close_file(fd1, filename);
484 tresult(expect[1], errno);
485 close_file(fd2, "olinkfile.txt");
486 tresult(expect[1], errno);
487 admerrors(ASSERT);
488 contp();
489 wait_send_cresult();
490
491 while (1)
492 sleep(1);
493 }
494
495 if (me == PARENT) {
496 /* assertion g) */
497 assertion("g", "Parent checks read/write on fd1 and fd2,\n"
498 "\tand kills child proc", "multiple");
499 read_file(fd1, filename, buf, 0, 26);
500 tresult(EBADF, errno);
501 read_file(fd2, "olinkfile.txt", buf, 0, 26);
502 tresult(expect[2], errno);
503
504 write_file(fd1, filename, DD, 0, 26);
505 tresult(EBADF, errno);
506 write_file(fd2, "olinkfile.txt", DD, 0, 26);
507 tresult(expect[3], errno);
508 admerrors(ASSERT);
509
510 if (wait_get_cresult())
511 ret = NOOK;
512 kill_child(OK);
513
514 /* assertion h) */
515 assertion("h", "Parent checks read/write on fd1 and fd2",
516 "multiple");
517 read_file(fd1, filename, buf, 0, 26);
518 tresult(EBADF, errno);
519 read_file(fd2, "olinkfile.txt", buf, 0, 26);
520 tresult(expect[2], errno);
521
522 write_file(fd1, filename, DD, 0, 26);
523 tresult(EBADF, errno);
524 write_file(fd2, "olinkfile.txt", DD, 0, 26);
525 tresult(expect[3], errno);
526 admerrors(ASSERT);
527 goto clean_up;
528 }
529
530 if (me == CHILD) {
531 print("ERROR: child should be dead. Quitting ...\n");
532 exit_test(NOOK);
533 }
534
535 clean_up:
536 {
537 int tmp = debug;
538 int tme = showerror;
539
540 debug = 0;
541 showerror = 0;
542 close_file(fd1, filename);
543 showerror = tme;
544 debug = tmp;
545
546 close_file(fd2, "olinkfile.txt");
547 unlink_file(filename);
548 unlink_file("olinkfile.txt");
549 }
550
551 if (admerrors(SCENARIO))
552 ret = NOOK;
553 print("Scenario B finished.\n\n\n\n");
554 return (ret);
555 }
556
557 int
558 scenarioC(int mode, int oflag, int expect[])
559 {
560 int fd1, fd2, fd3;
561 char *DD;
562 char tmp[512];
563 int ret = OK;
564
565 scen = "ScenC";
566 scen_mode = mode;
567 scen_flag = oflag;
568 expecterr = expect[0];
569
570 fprintf(stdout, "\n\nExecuting Scenario C, with mode = 0%o and "\
571 "oflag = %s\n\n", mode, oflagstr(oflag));
572
573 DD = strbackup("#123456789#123456789#123456789");
574
575 if ((create_test_data_file(filename, mode)) ||
576 link_file(filename, "olinkfile.txt")) {
577 printf("The scenario initialization failed, "\
578 "and other subassertions won't run.\n\n");
579 exit_test(NOOK);
580 }
581
582 /* assertion a) */
583 assertion("a", "Open a file using file desc fd1", errtostr(expect[0]));
584 fd1 = open_file(filename, oflag, mode);
585 tresult(expect[0], errno);
586 admerrors(ASSERT);
587 if (fd1 < 0) {
588 if (expect[0] == OK) {
589 printf("scenarioC{rest}: open calls\n");
590 printf("\t Test OTHER: unexpected open failure\n");
591 }
592 print("Scenario C, skipping rest of scenario.\n");
593 goto clean_up;
594 }
595
596 /* assertion b) */
597 assertion("b", "Open hardlink to original file using fd2",
598 errtostr(expect[0]));
599 fd2 = open_file("olinkfile.txt", oflag, mode);
600 tresult(expect[0], errno);
601 admerrors(ASSERT);
602
603 /* assertion c) */
604 assertion("c", "dup() original file using fd3", errtostr(expect[1]));
605 fd3 = dupfile(fd1);
606 tresult(expect[1], errno);
607 admerrors(ASSERT);
608
609 /* initialize pipes and create the child */
610 initialize();
611
612 if (me == PARENT) {
613 /* assertion d) */
614 assertion("d", "Parent closes all file descriptors",
615 "multiple");
616 close_file(fd1, filename);
617 tresult(expect[1], errno);
618 close_file(fd2, "olinkfile.txt");
619 tresult(expect[1], errno);
620 close_file(fd3, filename);
621 tresult(expect[1], errno);
622 admerrors(ASSERT);
623
624 contch();
625 waitp();
626 }
627
628 if (me == CHILD) {
629 waitch();
630
631 close_file(fd1, filename);
632 close_file(fd2, "olinkfile.txt");
633
634 /* assertion e) */
635 sprintf(tmp, "Child change credentials to owner %ld,"
636 "\n\treopen file on fd1, hardlink on fd2, check read/write all"
637 "3 fds\n\tand close fd1 and fd2", uid2);
638 assertion("e", tmp, "multiple");
639
640 if (Seteuid(0) < 0) {
641 print("Scenario C, seteuid(root) failed, skipping"\
642 " rest of scenario\n");
643 goto child_end;
644 }
645 if (Seteuid(uid2) < 0) {
646 print("Scenario C, seteuid(%d) failed, skipping"\
647 " rest of scenario ...\n", uid2);
648 goto child_end;
649 }
650
651 expecterr = (expect[4] == EBADF) ? EACCES : OK;
652 fd1 = open_file(filename, oflag, mode);
653 fd2 = open_file("olinkfile.txt", oflag, mode);
654
655 read_file(fd1, filename, buf, 0, 26);
656 tresult(expect[4], errno);
657 read_file(fd2, "olinkfile.txt", buf, 0, 26);
658 tresult(expect[4], errno);
659 read_file(fd3, "olinkfile.txt", buf, 0, 26);
660 tresult(expect[2], errno);
661
662 write_file(fd1, filename, DD, 0, 26);
663 tresult(expect[5], errno);
664 write_file(fd2, "olinkfile.txt", DD, 0, 26);
665 tresult(expect[5], errno);
666 write_file(fd3, "olinkfile.txt", DD, 0, 26);
667 tresult(expect[3], errno);
668
669 close_file(fd1, filename);
670 close_file(fd2, "olinkfile.txt");
671
672 admerrors(ASSERT);
673
674
675 /* assertion f) */
676 sprintf(tmp, "Child change credentials to owner %ld, group %ld,"
677 "\n\treopen file on fd1, hardlink on fd2, check read/write all"
678 "3 fds\n\tand close fd1 and fd2", uid2, gid2);
679 assertion("f", tmp, "multiple");
680
681 if (Seteuid(0) < 0) {
682 print("Scenario C, seteuid(root) failed, skipping"\
683 " rest of scenario ...\n");
684 goto child_end;
685 }
686 if (Setegid(gid2) < 0) {
687 print("Scenario C, setegid(%d) failed, skipping"\
688 "rest of scenario ...\n", gid2);
689 goto child_end;
690 }
691 {
692 gid_t gid = gid2;
693
694 if (Setgroups(1, &gid) < 0) {
695 print("Scenario C, setgroups(1, %d) failed, "\
696 "skipping rest of scenario ...\n", gid);
697 goto child_end;
698 }
699 }
700 if (Seteuid(uid2) < 0) {
701 print("Scenario C, seteuid(%d) failed, skipping"\
702 " rest of scenario ...\n", uid2);
703 goto child_end;
704 }
705
706 expecterr = EACCES;
707 fd1 = open_file(filename, oflag, mode);
708 fd2 = open_file("olinkfile.txt", oflag, mode);
709
710 if (debug != 0)
711 system("ls -la *file.txt; id -ap");
712 read_file(fd1, filename, buf, 0, 26);
713 tresult(EBADF, errno);
714 read_file(fd2, "olinkfile.txt", buf, 0, 26);
715 tresult(EBADF, errno);
716 read_file(fd3, "olinkfile.txt", buf, 0, 26);
717 tresult(expect[2], errno);
718
719 write_file(fd1, filename, DD, 0, 26);
720 tresult(EBADF, errno);
721 write_file(fd2, "olinkfile.txt", DD, 0, 26);
722 tresult(EBADF, errno);
723 write_file(fd3, "olinkfile.txt", DD, 0, 26);
724 tresult(expect[3], errno);
725
726 close_file(fd1, filename);
727 close_file(fd2, "olinkfile.txt");
728
729 admerrors(ASSERT);
730
731 contp();
732 wait_send_cresult();
733
734 while (1)
735 sleep(1);
736 }
737
738 if (me == PARENT) {
739 if (wait_get_cresult())
740 ret = NOOK;
741
742 kill_child(OK);
743
744 goto clean_up;
745 }
746
747 if (me == CHILD) {
748 print("ERROR: child should be dead. Quitting ...\n");
749 exit_test(NOOK);
750 }
751
752 child_end:
753 tresult(OK, errno);
754 admerrors(ASSERT);
755
756 contp();
757 while (1)
758 sleep(1);
759
760 clean_up:
761 unlink_file(filename);
762 unlink_file("olinkfile.txt");
763
764 if (admerrors(SCENARIO))
765 ret = NOOK;
766 print("Scenario C finished.\n\n\n\n");
767 return (ret);
768 }
769
770 int
771 scenarioD(int mode, int oflag, int expect[])
772 {
773 int fd1, fd2, fd3;
774 char *DD;
775 int ret = OK;
776
777 scen = "ScenD";
778 scen_mode = mode;
779 scen_flag = oflag;
780 expecterr = NOOK;
781
782 fprintf(stdout, "\n\nExecuting Scenario D, with mode = 0%o and "\
783 "oflag = %s\n\n", mode, oflagstr(oflag));
784
785 DD = strbackup("#123456789#123456789#123456789");
786
787 if ((create_test_data_file(filename, mode)) ||
788 link_file(filename, "olinkfile.txt")) {
789 printf("The scenario initialization failed, "\
790 "and other subassertions won't run.\n\n");
791 exit_test(NOOK);
792 }
793
794 /* assertion a) */
795 assertion("a",
796 "Opens a file on file desc fd1 and change permissions to 0000",
797 "multiple");
798 fd1 = open_file(filename, oflag, mode);
799 tresult(OK, errno);
800 chmod_file(fd1, filename, 0000);
801 tresult(OK, errno);
802 admerrors(ASSERT);
803
804 expecterr = EACCES;
805
806 if (fd1 < 0) {
807 if (expect[0] == OK) {
808 printf("scenarioD{rest}: open calls\n");
809 printf("\t Test OTHER: unexpected open failure\n");
810 }
811 print("Scenario D, skipping rest of scenario.\n");
812 goto clean_up;
813 }
814
815 /* initialize pipes and create the child */
816 initialize();
817
818 if (me == PARENT) {
819 sleep(1); /* let child start */
820 contch();
821 waitp();
822 }
823
824 if (me == CHILD) {
825 waitch();
826
827 /* assertion b) */
828 assertion("b", "Child opens the file on file desc fd3",
829 errtostr(EACCES));
830 fd3 = open_file(filename, oflag, mode);
831 tresult(EACCES, errno);
832 admerrors(ASSERT);
833
834 /* assertion c) */
835 assertion("c", "Child opens the a hardlink to file on fd2",
836 errtostr(EACCES));
837 fd2 = open_file("olinkfile.txt", oflag, mode);
838 tresult(EACCES, errno);
839 admerrors(ASSERT);
840
841 contp();
842 wait_send_cresult();
843
844 while (1)
845 sleep(1);
846 }
847
848 if (me == PARENT) {
849 goto clean_up;
850 }
851
852 if (me == CHILD) {
853 print("ERROR: child should be dead. Quitting ...\n");
854 exit_test(NOOK);
855 }
856
857 clean_up:
858 close_file(fd1, filename);
859
860 if (wait_get_cresult())
861 ret = NOOK;
862 kill_child(OK);
863
864 unlink_file(filename);
865 unlink_file("olinkfile.txt");
866
867 if (admerrors(SCENARIO))
868 ret = NOOK;
869 print("Scenario D finished.\n\n\n\n");
870 return (ret);
871 }
872
873 int
874 scenarioE(int mode, int oflag, int expect[])
875 {
876 int fd1, fd2;
877
878 scen = "ScenE";
879 scen_mode = mode;
880 scen_flag = oflag;
881 expecterr = OK;
882 int ret = OK;
883
884 fprintf(stdout, "\n\nExecuting Scenario A, with mode = 0%o and " \
885 "oflag = %s\n\n", mode, oflagstr(oflag));
886
887 /* assertion a ) */
888 assertion("a", "open a file with trunc option after a success open \
889 will success", errtostr(expecterr));
890 errno = OK;
891 fd1 = open_file(filename, O_CREAT, scen_mode);
892 tresult(OK, errno);
893 fd2 = open_file(filename, scen_flag, scen_mode);
894 tresult(OK, errno);
895 admerrors(ASSERT);
896 if (fd1 > 0)
897 close_file(fd1, filename);
898 if (fd2 > 0)
899 close_file(fd2, filename);
900 unlink_file(filename);
901
902 if (admerrors(SCENARIO))
903 ret = NOOK;
904 print("Scenario E finished.\n\n\n");
905 return (ret);
906 }