Home | History | Annotate | Download | only in fcntl
      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  */
     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  */
    125 void cleanup(void)
    126 {
    127 
    128 	tst_rmdir();
    129 
    130 }
    131 
    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 
    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 
    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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    281 void catch_child(void)
    282 {
    283 	tst_resm(TFAIL, "Unexpected death of child process");
    284 	cleanup();
    285 }
    286 
    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