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 1:
226 return ("F_RDLCK");
227 case 2:
228 return ("F_WRLCK");
229 case 3:
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 #ifdef UCLINUX
295 maybe_run_child(&do_child, "ddddd", &parent_pipe[0], &parent_pipe[1],
296 &child_pipe[0], &child_pipe[1], &fd);
297 #endif
298
299 setup(); /* global setup */
300
301 /* Check for looping state if -i option is given */
302 for (lc = 0; TEST_LOOPING(lc); lc++) {
303 /* reset tst_count in case we are looping */
304 tst_count = 0;
305
306 if ((child_pid = FORK_OR_VFORK()) == 0) {
307 #ifdef UCLINUX
308 if (self_exec
309 (av[0], "ddddd", parent_pipe[0], parent_pipe[1],
310 child_pipe[0], child_pipe[1], fd) < 0) {
311 tst_resm(TFAIL, "self_exec failed");
312 cleanup();
313 }
314 #else
315 do_child();
316 #endif
317 }
318 if (child_pid < 0) {
319 tst_resm(TFAIL, "Fork failed");
320 cleanup();
321 }
322
323 (void)close(parent_pipe[0]);
324 (void)close(child_pipe[1]);
325
326 /* //block1: */
327 tst_resm(TINFO, "Enter block 1");
328 fail = 0;
329 /*
330 * Set a read lock on the whole file
331 */
332 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 0, 0) < 0) {
333 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
334 errno);
335 fail = 1;
336 }
337
338 /*
339 * Test to make sure it's there.
340 */
341 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
342 compare_lock(&tl, (short)F_RDLCK, (short)0, 0, 0, parent_pid);
343
344 /*
345 * remove the lock set above
346 */
347 unlock_file();
348
349 if (fail) {
350 tst_resm(TINFO, "Test block 1: FAILED");
351 } else {
352 tst_resm(TINFO, "Test block 1: PASSED");
353 }
354 tst_resm(TINFO, "Exit block 1");
355
356 /* //block2: */
357 tst_resm(TINFO, "Enter block 2");
358 fail = 0;
359
360 /*
361 * Set a write lock on the whole file
362 */
363 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 0, 0) < 0) {
364 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
365 errno);
366 fail = 1;
367 }
368
369 /*
370 * Test to make sure its there
371 */
372 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
373 compare_lock(&tl, (short)F_WRLCK, (short)0, 0, 0, parent_pid);
374
375 /*
376 * remove the lock set above
377 */
378 unlock_file();
379
380 if (fail) {
381 tst_resm(TINFO, "Test block 2: FAILED");
382 } else {
383 tst_resm(TINFO, "Test block 2: PASSED");
384 }
385
386 tst_resm(TINFO, "Exit block 2");
387
388 /* //block3: */
389 tst_resm(TINFO, "Enter block 3");
390 fail = 0;
391
392 /*
393 * Add a read lock to the middle of the file and a write
394 * at the begining
395 */
396 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
397 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
398 errno);
399 fail = 1;
400 }
401
402 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 1, 5) < 0) {
403 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
404 errno);
405 fail = 1;
406 }
407
408 /*
409 * Test write lock
410 */
411 do_test(&tl, F_WRLCK, 0, 0, 0);
412 compare_lock(&tl, (short)F_WRLCK, (short)0, 1, 5, parent_pid);
413
414 /*
415 * Test read lock
416 */
417 do_test(&tl, F_WRLCK, 0, 6, 0);
418 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
419
420 /*
421 * Test that the rest of the file is unlocked
422 */
423 do_test(&tl, F_WRLCK, 0, 15, 0);
424 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
425
426 /*
427 * remove all the locks set above
428 */
429 unlock_file();
430
431 if (fail) {
432 tst_resm(TINFO, "Test block 3: FAILED");
433 } else {
434 tst_resm(TINFO, "Test block 3 : PASSED");
435 }
436 tst_resm(TINFO, "Exit block 3");
437
438 /* //block4: */
439 tst_resm(TINFO, "Enter block 4");
440 fail = 0;
441
442 /*
443 * Set a read lock at the middle of the file and a
444 * write lock just before
445 */
446 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
447 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
448 errno);
449 fail = 1;
450 }
451
452 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 5) < 0) {
453 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
454 errno);
455 fail = 1;
456 }
457
458 /*
459 * Test the write lock
460 */
461 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
462 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 5, parent_pid);
463
464 /*
465 * Test the read lock.
466 */
467 do_test(&tl, (short)F_WRLCK, (short)0, 10, 0);
468 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
469
470 /*
471 * Test to make sure the rest of the file is unlocked.
472 */
473 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
474 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
475
476 /*
477 * remove all the locks set above
478 */
479 unlock_file();
480
481 if (fail) {
482 tst_resm(TINFO, "Test block 4: FAILED");
483 } else {
484 tst_resm(TINFO, "Test block 4: PASSED");
485 }
486 tst_resm(TINFO, "Exit block 4");
487
488 /* //block5: */
489 tst_resm(TINFO, "Enter block 5");
490 fail = 0;
491
492 /*
493 * Set a read lock in the middle and a write lock that
494 * ends at the first byte of the read lock
495 */
496 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
497 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
498 errno);
499 fail = 1;
500 }
501
502 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 6) < 0) {
503 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
504 errno);
505 fail = 1;
506 }
507
508 /*
509 * Test write lock
510 */
511 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
512 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 6, parent_pid);
513
514 /*
515 * Test read lock
516 */
517 do_test(&tl, (short)F_WRLCK, (short)0, 11, 0);
518 compare_lock(&tl, (short)F_RDLCK, (short)0, 11, 4, parent_pid);
519
520 /*
521 * Test to make sure the rest of the file is unlocked.
522 */
523 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
524 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
525
526 /*
527 * remove all the locks set above
528 */
529 unlock_file();
530
531 if (fail) {
532 tst_resm(TINFO, "Test block 5: FAILED");
533 } else {
534 tst_resm(TINFO, "Test block 5: PASSED");
535 }
536 tst_resm(TINFO, "Exit block 5");
537
538 /* //block6: */
539 tst_resm(TINFO, "Enter block 6");
540 fail = 0;
541
542 /*
543 * Set a read lock on the middle of the file and a write
544 * lock that overlaps the front of the read.
545 */
546 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
547 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
548 errno);
549 fail = 1;
550 }
551
552 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 8) < 0) {
553 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
554 errno);
555 fail = 1;
556 }
557
558 /*
559 * Test the write lock
560 */
561 do_test(&tl, (short)F_WRLCK, (short)0, 5, 0);
562 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 8, parent_pid);
563
564 /*
565 * Test the read lock
566 */
567 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
568 compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 2, parent_pid);
569
570 /*
571 * Test to make sure the rest of the file is unlocked.
572 */
573 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
574 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
575
576 /*
577 * remove all the locks set above
578 */
579 unlock_file();
580
581 if (fail) {
582 tst_resm(TINFO, "Test block 6 FAILED");
583 } else {
584 tst_resm(TINFO, "Test block 6 PASSED");
585 }
586 tst_resm(TINFO, "Exit block 6");
587
588 /* //block7: */
589 tst_resm(TINFO, "Enter block 7");
590 fail = 0;
591
592 /*
593 * Set a read lock in the middle of a file and a write
594 * lock in the middle of it
595 */
596 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 10) < 0) {
597 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
598 errno);
599 fail = 1;
600 }
601
602 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
603 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
604 errno);
605 fail = 1;
606 }
607
608 /*
609 * Test the first read lock
610 */
611 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
612 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
613
614 /*
615 * Test the write lock
616 */
617 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
618 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
619
620 /*
621 * Test the second read lock
622 */
623 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
624 compare_lock(&tl, (short)F_RDLCK, (short)0, 18, 2, parent_pid);
625
626 /*
627 * Test to make sure the rest of the file is unlocked
628 */
629 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
630 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
631
632 /*
633 * remove all the locks set above.
634 */
635 unlock_file();
636 if (fail) {
637 tst_resm(TINFO, "Test block 7: FAILED");
638 } else {
639 tst_resm(TINFO, "Test block 7: PASSED");
640 }
641 tst_resm(TINFO, "Exit block 7");
642
643 /* //block8: */
644 tst_resm(TINFO, "Enter block 8");
645 fail = 0;
646 /*
647 * Set a read lock in the middle of the file and a write
648 * lock that overlaps the end
649 */
650 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
651 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
652 errno);
653 fail = 1;
654 }
655
656 /*
657 * Set a write lock on the whole file
658 */
659 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) {
660 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
661 errno);
662 fail = 1;
663 }
664
665 /*
666 * Test the read lock
667 */
668 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
669 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid);
670
671 /*
672 * Test the write lock
673 */
674 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
675 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid);
676
677 /*
678 * Test to make sure the rest of the file is unlocked
679 */
680 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
681 compare_lock(&tl, (short)F_UNLCK, (short)0, 18, 0, 0);
682
683 /*
684 * remove all the locks set above
685 */
686 unlock_file();
687
688 if (fail) {
689 tst_resm(TINFO, "Test block 8: FAILED");
690 } else {
691 tst_resm(TINFO, "Test block 8: PASSED");
692 }
693 tst_resm(TINFO, "Exit block 8");
694
695 /* //block9: */
696 tst_resm(TINFO, "Enter block 9");
697 fail = 0;
698
699 /*
700 * Set a read lock in the middle of the file and a write
701 * lock starting at the last byte of the read lock
702 */
703 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
704 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
705 errno);
706 fail = 1;
707 }
708
709 /*
710 * Set a write lock on the whole file.
711 */
712 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 14, 5) < 0) {
713 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
714 errno);
715 fail = 1;
716 }
717
718 /*
719 * Test read lock
720 */
721 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
722 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 4, parent_pid);
723
724 /*
725 * Test the write lock
726 */
727 do_test(&tl, (short)F_WRLCK, (short)0, 14, 0);
728 compare_lock(&tl, (short)F_WRLCK, (short)0, 14, 5, parent_pid);
729
730 /*
731 * Test to make sure the end of the file is unlocked
732 */
733 do_test(&tl, (short)F_WRLCK, (short)0, 19, 0);
734 compare_lock(&tl, (short)F_UNLCK, (short)0, 19, 0, 0);
735
736 /*
737 * remove all the locks set above
738 */
739 unlock_file();
740
741 if (fail) {
742 tst_resm(TINFO, "Test block 9: FAILED");
743 } else {
744 tst_resm(TINFO, "Test block 9: PASSED");
745 }
746 tst_resm(TINFO, "Exit block 9");
747
748 /* //block10: */
749 tst_resm(TINFO, "Enter block 10");
750 fail = 0;
751
752 /*
753 * Set a read lock in the middle of the file and a write
754 * lock that starts just after the last byte of the
755 * read lock.
756 */
757 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
758 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
759 errno);
760 fail = 1;
761 }
762
763 /*
764 * Set a write lock on the whole file
765 */
766 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 15, 5) < 0) {
767 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
768 errno);
769 fail = 1;
770 }
771
772 /*
773 * Test the read lock
774 */
775 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
776 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
777
778 /*
779 * Test the write lock
780 */
781 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
782 compare_lock(&tl, (short)F_WRLCK, (short)0, 15, 5, parent_pid);
783
784 /*
785 * Test to make sure the rest of the file is unlocked
786 */
787 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
788 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
789
790 /*
791 * remove all the locks set above
792 */
793 unlock_file();
794
795 if (fail) {
796 tst_resm(TINFO, "Test block 10: FAILED");
797 } else {
798 tst_resm(TINFO, "Test block 10: PASSED");
799 }
800 tst_resm(TINFO, "Exit block 10");
801
802 /* //block11: */
803 tst_resm(TINFO, "Enter block 11");
804 fail = 0;
805
806 /*
807 * Set a read lock at the middle of the file and a write
808 * lock that starts past the end of the read lock.
809 */
810 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) {
811 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
812 errno);
813 fail = 1;
814 }
815
816 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 16, 5) < 0) {
817 tst_resm(TFAIL, "fcntl on file failed, errno =%d",
818 errno);
819 fail = 1;
820 }
821
822 /*
823 * Test the read lock
824 */
825 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
826 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid);
827
828 /*
829 * Test that byte in between is unlocked
830 */
831 do_test(&tl, (short)F_WRLCK, (short)0, 15, 1);
832 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 1, 0);
833
834 /*
835 * Test the write lock
836 */
837 do_test(&tl, (short)F_WRLCK, (short)0, 16, 0);
838 compare_lock(&tl, (short)F_WRLCK, (short)0, 16, 5, parent_pid);
839
840 /*
841 * Test to make sure the rest of the file is unlocked
842 */
843 do_test(&tl, (short)F_WRLCK, (short)0, 21, 0);
844 compare_lock(&tl, (short)F_UNLCK, (short)0, 21, 0, 0);
845
846 /*
847 * remove all the locks set above
848 */
849 unlock_file();
850
851 if (fail) {
852 tst_resm(TINFO, "Test block 11: FAILED");
853 } else {
854 tst_resm(TINFO, "Test block 11: PASSED");
855 }
856 tst_resm(TINFO, "Exit block 11");
857
858 stop_child();
859 close(fd);
860 }
861 cleanup();
862 tst_exit();
863 }
864