1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2001
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /*
21 * NAME
22 * fcntl21.c
23 *
24 * DESCRIPTION
25 * Check locking of regions of a file
26 *
27 * ALGORITHM
28 * Test changing lock sections around a read lock
29 *
30 * USAGE
31 * fcntl21
32 *
33 * HISTORY
34 * 07/2001 Ported by Wayne Boyer
35 *
36 * RESTRICTIONS
37 * None
38 */
39
40 #include <fcntl.h>
41 #include <errno.h>
42 #include <signal.h>
43 #include <sys/types.h>
44 #include <sys/stat.h>
45 #include <sys/wait.h>
46 #include <inttypes.h>
47 #include "test.h"
48
49 #define STRINGSIZE 27
50 #define STRING "abcdefghijklmnopqrstuvwxyz\n"
51 #define STOP 0xFFF0
52
53 int parent_pipe[2];
54 int child_pipe[2];
55 int fd;
56 pid_t parent_pid, child_pid;
57
58 void parent_put();
59 void parent_get();
60 void child_put();
61 void child_get();
62 void stop_child();
63 void compare_lock(struct flock *, short, short, int, int, pid_t);
64 void unlock_file();
65 void do_test(struct flock *, short, short, int, int);
66 void catch_child();
67 char *str_type();
68 int do_lock(int, short, short, int, int);
69
70 char *TCID = "fcntl21";
71 int TST_TOTAL = 1;
72
73 void setup(void);
74 void cleanup(void);
75 int fail;
76
77 /*
78 * setup
79 * performs all ONE TIME setup for this test
80 */
setup(void)81 void setup(void)
82 {
83 char *buf = STRING;
84 char template[PATH_MAX];
85 struct sigaction act;
86
87 tst_sig(FORK, DEF_HANDLER, cleanup);
88
89 umask(0);
90
91 TEST_PAUSE;
92
93 pipe(parent_pipe);
94 pipe(child_pipe);
95 parent_pid = getpid();
96
97 tst_tmpdir();
98
99 snprintf(template, PATH_MAX, "fcntl21XXXXXX");
100
101 if ((fd = mkstemp(template)) < 0) {
102 tst_resm(TFAIL, "Couldn't open temp file! errno = %d", errno);
103 }
104
105 if (write(fd, buf, STRINGSIZE) < 0) {
106 tst_resm(TFAIL, "Couldn't write to temp file! errno = %d",
107 errno);
108 }
109
110 memset(&act, 0, sizeof(act));
111 act.sa_handler = catch_child;
112 sigemptyset(&act.sa_mask);
113 sigaddset(&act.sa_mask, SIGCHLD);
114 if ((sigaction(SIGCHLD, &act, NULL)) < 0) {
115 tst_resm(TFAIL, "SIGCHLD signal setup failed, errno: %d", errno);
116 fail = 1;
117 }
118 }
119
120 /*
121 * cleanup()
122 * performs all ONE TIME cleanup for this test at completion or
123 * premature exit
124 */
cleanup(void)125 void cleanup(void)
126 {
127
128 tst_rmdir();
129
130 }
131
do_child(void)132 void do_child(void)
133 {
134 struct flock fl;
135
136 close(parent_pipe[1]);
137 close(child_pipe[0]);
138 while (1) {
139 child_get(&fl);
140 if (fcntl(fd, F_GETLK, &fl) < 0) {
141 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
142 errno);
143 fail = 1;
144 }
145 child_put(&fl);
146 }
147 }
148
do_lock(int cmd,short type,short whence,int start,int len)149 int do_lock(int cmd, short type, short whence, int start, int len)
150 {
151 struct flock fl;
152
153 fl.l_type = type;
154 fl.l_whence = whence;
155 fl.l_start = start;
156 fl.l_len = len;
157 return (fcntl(fd, cmd, &fl));
158 }
159
do_test(struct flock * fl,short type,short whence,int start,int len)160 void do_test(struct flock *fl, short type, short whence, int start, int len)
161 {
162 fl->l_type = type;
163 fl->l_whence = whence;
164 fl->l_start = start;
165 fl->l_len = len;
166 fl->l_pid = (short)0;
167
168 parent_put(fl);
169 parent_get(fl);
170 }
171
172 void
compare_lock(struct flock * fl,short type,short whence,int start,int len,pid_t pid)173 compare_lock(struct flock *fl, short type, short whence, int start, int len,
174 pid_t pid)
175 {
176 if (fl->l_type != type) {
177 tst_resm(TFAIL, "lock type is wrong should be %s is %s",
178 str_type(type), str_type(fl->l_type));
179 fail = 1;
180 }
181
182 if (fl->l_whence != whence) {
183 tst_resm(TFAIL, "lock whence is wrong should be %d is %d",
184 whence, fl->l_whence);
185 fail = 1;
186 }
187
188 if (fl->l_start != start) {
189 tst_resm(TFAIL, "region starts in wrong place, should be"
190 "%d is %" PRId64, start, (int64_t) fl->l_start);
191 fail = 1;
192 }
193
194 if (fl->l_len != len) {
195 tst_resm(TFAIL,
196 "region length is wrong, should be %d is %" PRId64,
197 len, (int64_t) fl->l_len);
198 fail = 1;
199 }
200
201 if (fl->l_pid != pid) {
202 tst_resm(TFAIL, "locking pid is wrong, should be %d is %d",
203 pid, fl->l_pid);
204 fail = 1;
205 }
206 }
207
unlock_file(void)208 void unlock_file(void)
209 {
210 struct flock fl;
211
212 if (do_lock(F_SETLK, (short)F_UNLCK, (short)0, 0, 0) < 0) {
213 tst_resm(TFAIL, "fcntl on file failed, errno =%d", errno);
214 fail = 1;
215 }
216 do_test(&fl, F_WRLCK, 0, 0, 0);
217 compare_lock(&fl, (short)F_UNLCK, (short)0, 0, 0, (pid_t) 0);
218 }
219
str_type(int type)220 char *str_type(int type)
221 {
222 static char buf[20];
223
224 switch (type) {
225 case F_RDLCK:
226 return ("F_RDLCK");
227 case F_WRLCK:
228 return ("F_WRLCK");
229 case F_UNLCK:
230 return ("F_UNLCK");
231 default:
232 sprintf(buf, "BAD VALUE: %d", type);
233 return (buf);
234 }
235 }
236
parent_put(struct flock * l)237 void parent_put(struct flock *l)
238 {
239 if (write(parent_pipe[1], l, sizeof(*l)) != sizeof(*l)) {
240 tst_resm(TFAIL, "couldn't send message to child");
241 fail = 1;
242 }
243 }
244
parent_get(struct flock * l)245 void parent_get(struct flock *l)
246 {
247 if (read(child_pipe[0], l, sizeof(*l)) != sizeof(*l)) {
248 tst_resm(TFAIL, "couldn't get message from child");
249 fail = 1;
250 }
251 }
252
child_put(struct flock * l)253 void child_put(struct flock *l)
254 {
255 if (write(child_pipe[1], l, sizeof(*l)) != sizeof(*l)) {
256 tst_resm(TFAIL, "couldn't send message to parent");
257 fail = 1;
258 }
259 }
260
child_get(struct flock * l)261 void child_get(struct flock *l)
262 {
263 if (read(parent_pipe[0], l, sizeof(*l)) != sizeof(*l)) {
264 tst_resm(TFAIL, "couldn't get message from parent");
265 cleanup();
266 } else if (l->l_type == (short)STOP) {
267 exit(0);
268 }
269 }
270
stop_child(void)271 void stop_child(void)
272 {
273 struct flock fl;
274
275 signal(SIGCHLD, SIG_DFL);
276 fl.l_type = STOP;
277 parent_put(&fl);
278 wait(0);
279 }
280
catch_child(void)281 void catch_child(void)
282 {
283 tst_resm(TFAIL, "Unexpected death of child process");
284 cleanup();
285 }
286
main(int ac,char ** av)287 int main(int ac, char **av)
288 {
289 struct flock tl;
290
291 int lc;
292
293 tst_parse_opts(ac, av, NULL, NULL);
294 setup(); /* global setup */
295
296 /* Check for looping state if -i option is given */
297 for (lc = 0; TEST_LOOPING(lc); lc++) {
298 /* reset tst_count in case we are looping */
299 tst_count = 0;
300
301 if ((child_pid = tst_fork()) == 0)
302 do_child();
303
304 if (child_pid < 0) {
305 tst_resm(TFAIL, "Fork failed");
306 cleanup();
307 }
308
309 (void)close(parent_pipe[0]);
310 (void)close(child_pipe[1]);
311
312 /* //block1: */
313 tst_resm(TINFO, "Enter block 1");
314 fail = 0;
315 /*
316 * Set a read lock on the whole file
317 */
318 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 0, 0) < 0) {
319 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
320 errno);
321 fail = 1;
322 }
323
324 /*
325 * Test to make sure it's there.
326 */
327 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
328 compare_lock(&tl, (short)F_RDLCK, (short)0, 0, 0, parent_pid);
329
330 /*
331 * remove the lock set above
332 */
333 unlock_file();
334
335 if (fail) {
336 tst_resm(TINFO, "Test block 1: FAILED");
337 } else {
338 tst_resm(TINFO, "Test block 1: PASSED");
339 }
340 tst_resm(TINFO, "Exit block 1");
341
342 /* //block2: */
343 tst_resm(TINFO, "Enter block 2");
344 fail = 0;
345
346 /*
347 * Set a write lock on the whole file
348 */
349 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 0, 0) < 0) {
350 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
351 errno);
352 fail = 1;
353 }
354
355 /*
356 * Test to make sure its there
357 */
358 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
359 compare_lock(&tl, (short)F_WRLCK, (short)0, 0, 0, parent_pid);
360
361 /*
362 * remove the lock set above
363 */
364 unlock_file();
365
366 if (fail) {
367 tst_resm(TINFO, "Test block 2: FAILED");
368 } else {
369 tst_resm(TINFO, "Test block 2: PASSED");
370 }
371
372 tst_resm(TINFO, "Exit block 2");
373
374 /* //block3: */
375 tst_resm(TINFO, "Enter block 3");
376 fail = 0;
377
378 /*
379 * Add a read lock to the middle of the file and a write
380 * at the begining
381 */
382 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
383 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
384 errno);
385 fail = 1;
386 }
387
388 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 1, 5) < 0) {
389 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
390 errno);
391 fail = 1;
392 }
393
394 /*
395 * Test write lock
396 */
397 do_test(&tl, F_WRLCK, 0, 0, 0);
398 compare_lock(&tl, (short)F_WRLCK, (short)0, 1, 5, parent_pid);
399
400 /*
401 * Test read lock
402 */
403 do_test(&tl, F_WRLCK, 0, 6, 0);
404 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
405
406 /*
407 * Test that the rest of the file is unlocked
408 */
409 do_test(&tl, F_WRLCK, 0, 15, 0);
410 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
411
412 /*
413 * remove all the locks set above
414 */
415 unlock_file();
416
417 if (fail) {
418 tst_resm(TINFO, "Test block 3: FAILED");
419 } else {
420 tst_resm(TINFO, "Test block 3 : PASSED");
421 }
422 tst_resm(TINFO, "Exit block 3");
423
424 /* //block4: */
425 tst_resm(TINFO, "Enter block 4");
426 fail = 0;
427
428 /*
429 * Set a read lock at the middle of the file and a
430 * write lock just before
431 */
432 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
433 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
434 errno);
435 fail = 1;
436 }
437
438 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 5) < 0) {
439 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
440 errno);
441 fail = 1;
442 }
443
444 /*
445 * Test the write lock
446 */
447 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
448 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 5, parent_pid);
449
450 /*
451 * Test the read lock.
452 */
453 do_test(&tl, (short)F_WRLCK, (short)0, 10, 0);
454 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
455
456 /*
457 * Test to make sure the rest of the file is unlocked.
458 */
459 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
460 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
461
462 /*
463 * remove all the locks set above
464 */
465 unlock_file();
466
467 if (fail) {
468 tst_resm(TINFO, "Test block 4: FAILED");
469 } else {
470 tst_resm(TINFO, "Test block 4: PASSED");
471 }
472 tst_resm(TINFO, "Exit block 4");
473
474 /* //block5: */
475 tst_resm(TINFO, "Enter block 5");
476 fail = 0;
477
478 /*
479 * Set a read lock in the middle and a write lock that
480 * ends at the first byte of the read lock
481 */
482 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
483 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
484 errno);
485 fail = 1;
486 }
487
488 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 6) < 0) {
489 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
490 errno);
491 fail = 1;
492 }
493
494 /*
495 * Test write lock
496 */
497 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
498 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 6, parent_pid);
499
500 /*
501 * Test read lock
502 */
503 do_test(&tl, (short)F_WRLCK, (short)0, 11, 0);
504 compare_lock(&tl, (short)F_RDLCK, (short)0, 11, 4, parent_pid);
505
506 /*
507 * Test to make sure the rest of the file is unlocked.
508 */
509 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
510 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
511
512 /*
513 * remove all the locks set above
514 */
515 unlock_file();
516
517 if (fail) {
518 tst_resm(TINFO, "Test block 5: FAILED");
519 } else {
520 tst_resm(TINFO, "Test block 5: PASSED");
521 }
522 tst_resm(TINFO, "Exit block 5");
523
524 /* //block6: */
525 tst_resm(TINFO, "Enter block 6");
526 fail = 0;
527
528 /*
529 * Set a read lock on the middle of the file and a write
530 * lock that overlaps the front of the read.
531 */
532 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
533 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
534 errno);
535 fail = 1;
536 }
537
538 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 8) < 0) {
539 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
540 errno);
541 fail = 1;
542 }
543
544 /*
545 * Test the write lock
546 */
547 do_test(&tl, (short)F_WRLCK, (short)0, 5, 0);
548 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 8, parent_pid);
549
550 /*
551 * Test the read lock
552 */
553 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
554 compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 2, parent_pid);
555
556 /*
557 * Test to make sure the rest of the file is unlocked.
558 */
559 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
560 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
561
562 /*
563 * remove all the locks set above
564 */
565 unlock_file();
566
567 if (fail) {
568 tst_resm(TINFO, "Test block 6 FAILED");
569 } else {
570 tst_resm(TINFO, "Test block 6 PASSED");
571 }
572 tst_resm(TINFO, "Exit block 6");
573
574 /* //block7: */
575 tst_resm(TINFO, "Enter block 7");
576 fail = 0;
577
578 /*
579 * Set a read lock in the middle of a file and a write
580 * lock in the middle of it
581 */
582 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 10) < 0) {
583 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
584 errno);
585 fail = 1;
586 }
587
588 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
589 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
590 errno);
591 fail = 1;
592 }
593
594 /*
595 * Test the first read lock
596 */
597 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
598 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
599
600 /*
601 * Test the write lock
602 */
603 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
604 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
605
606 /*
607 * Test the second read lock
608 */
609 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
610 compare_lock(&tl, (short)F_RDLCK, (short)0, 18, 2, parent_pid);
611
612 /*
613 * Test to make sure the rest of the file is unlocked
614 */
615 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
616 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
617
618 /*
619 * remove all the locks set above.
620 */
621 unlock_file();
622 if (fail) {
623 tst_resm(TINFO, "Test block 7: FAILED");
624 } else {
625 tst_resm(TINFO, "Test block 7: PASSED");
626 }
627 tst_resm(TINFO, "Exit block 7");
628
629 /* //block8: */
630 tst_resm(TINFO, "Enter block 8");
631 fail = 0;
632 /*
633 * Set a read lock in the middle of the file and a write
634 * lock that overlaps the end
635 */
636 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
637 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
638 errno);
639 fail = 1;
640 }
641
642 /*
643 * Set a write lock on the whole file
644 */
645 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
646 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
647 errno);
648 fail = 1;
649 }
650
651 /*
652 * Test the read lock
653 */
654 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
655 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
656
657 /*
658 * Test the write lock
659 */
660 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
661 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
662
663 /*
664 * Test to make sure the rest of the file is unlocked
665 */
666 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
667 compare_lock(&tl, (short)F_UNLCK, (short)0, 18, 0, 0);
668
669 /*
670 * remove all the locks set above
671 */
672 unlock_file();
673
674 if (fail) {
675 tst_resm(TINFO, "Test block 8: FAILED");
676 } else {
677 tst_resm(TINFO, "Test block 8: PASSED");
678 }
679 tst_resm(TINFO, "Exit block 8");
680
681 /* //block9: */
682 tst_resm(TINFO, "Enter block 9");
683 fail = 0;
684
685 /*
686 * Set a read lock in the middle of the file and a write
687 * lock starting at the last byte of the read lock
688 */
689 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
690 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
691 errno);
692 fail = 1;
693 }
694
695 /*
696 * Set a write lock on the whole file.
697 */
698 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 14, 5) < 0) {
699 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
700 errno);
701 fail = 1;
702 }
703
704 /*
705 * Test read lock
706 */
707 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
708 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 4, parent_pid);
709
710 /*
711 * Test the write lock
712 */
713 do_test(&tl, (short)F_WRLCK, (short)0, 14, 0);
714 compare_lock(&tl, (short)F_WRLCK, (short)0, 14, 5, parent_pid);
715
716 /*
717 * Test to make sure the end of the file is unlocked
718 */
719 do_test(&tl, (short)F_WRLCK, (short)0, 19, 0);
720 compare_lock(&tl, (short)F_UNLCK, (short)0, 19, 0, 0);
721
722 /*
723 * remove all the locks set above
724 */
725 unlock_file();
726
727 if (fail) {
728 tst_resm(TINFO, "Test block 9: FAILED");
729 } else {
730 tst_resm(TINFO, "Test block 9: PASSED");
731 }
732 tst_resm(TINFO, "Exit block 9");
733
734 /* //block10: */
735 tst_resm(TINFO, "Enter block 10");
736 fail = 0;
737
738 /*
739 * Set a read lock in the middle of the file and a write
740 * lock that starts just after the last byte of the
741 * read lock.
742 */
743 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
744 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
745 errno);
746 fail = 1;
747 }
748
749 /*
750 * Set a write lock on the whole file
751 */
752 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 15, 5) < 0) {
753 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
754 errno);
755 fail = 1;
756 }
757
758 /*
759 * Test the read lock
760 */
761 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
762 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
763
764 /*
765 * Test the write lock
766 */
767 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
768 compare_lock(&tl, (short)F_WRLCK, (short)0, 15, 5, parent_pid);
769
770 /*
771 * Test to make sure the rest of the file is unlocked
772 */
773 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
774 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
775
776 /*
777 * remove all the locks set above
778 */
779 unlock_file();
780
781 if (fail) {
782 tst_resm(TINFO, "Test block 10: FAILED");
783 } else {
784 tst_resm(TINFO, "Test block 10: PASSED");
785 }
786 tst_resm(TINFO, "Exit block 10");
787
788 /* //block11: */
789 tst_resm(TINFO, "Enter block 11");
790 fail = 0;
791
792 /*
793 * Set a read lock at the middle of the file and a write
794 * lock that starts past the end of the read lock.
795 */
796 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
797 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
798 errno);
799 fail = 1;
800 }
801
802 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 16, 5) < 0) {
803 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
804 errno);
805 fail = 1;
806 }
807
808 /*
809 * Test the read lock
810 */
811 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
812 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
813
814 /*
815 * Test that byte in between is unlocked
816 */
817 do_test(&tl, (short)F_WRLCK, (short)0, 15, 1);
818 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 1, 0);
819
820 /*
821 * Test the write lock
822 */
823 do_test(&tl, (short)F_WRLCK, (short)0, 16, 0);
824 compare_lock(&tl, (short)F_WRLCK, (short)0, 16, 5, parent_pid);
825
826 /*
827 * Test to make sure the rest of the file is unlocked
828 */
829 do_test(&tl, (short)F_WRLCK, (short)0, 21, 0);
830 compare_lock(&tl, (short)F_UNLCK, (short)0, 21, 0, 0);
831
832 /*
833 * remove all the locks set above
834 */
835 unlock_file();
836
837 if (fail) {
838 tst_resm(TINFO, "Test block 11: FAILED");
839 } else {
840 tst_resm(TINFO, "Test block 11: PASSED");
841 }
842 tst_resm(TINFO, "Exit block 11");
843
844 stop_child();
845 close(fd);
846 }
847 cleanup();
848 tst_exit();
849 }
850