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