xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/fcntl/fcntl21.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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