• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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