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
53int parent_pipe[2];
54int child_pipe[2];
55int fd;
56pid_t parent_pid, child_pid;
57
58void parent_put();
59void parent_get();
60void child_put();
61void child_get();
62void stop_child();
63void compare_lock(struct flock *, short, short, int, int, pid_t);
64void unlock_file();
65void do_test(struct flock *, short, short, int, int);
66void catch_child();
67char *str_type();
68int do_lock(int, short, short, int, int);
69
70char *TCID = "fcntl21";
71int TST_TOTAL = 1;
72
73void setup(void);
74void cleanup(void);
75int fail;
76
77/*
78 * setup
79 *	performs all ONE TIME setup for this test
80 */
81void 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 */
125void cleanup(void)
126{
127
128	tst_rmdir();
129
130}
131
132void 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
149int 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
160void 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
172void
173compare_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
208void 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
220char *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
237void 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
245void 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
253void 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
261void 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
271void 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
281void catch_child(void)
282{
283	tst_resm(TFAIL, "Unexpected death of child process");
284	cleanup();
285}
286
287int 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