fcntl21.c revision 54f7a718c05ce3e0c51950e1a6d2243513366076
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 <wait.h> 44#include <sys/types.h> 45#include <sys/stat.h> 46#include "test.h" 47#include "usctest.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; 72extern int Tst_count; 73 74void setup(void); 75void cleanup(void); 76int fail; 77 78 79/* 80 * setup 81 * performs all ONE TIME setup for this test 82 */ 83void 84setup() 85{ 86 char *buf = STRING; 87 char template[PATH_MAX]; 88 89 90 /* capture signals */ 91 tst_sig(FORK, DEF_HANDLER, cleanup); 92 93 umask(0); 94 95 /* Pause if that option was specified */ 96 TEST_PAUSE; 97 98 pipe(parent_pipe); 99 pipe(child_pipe); 100 parent_pid = getpid(); 101 102 tst_tmpdir(); 103 104 snprintf(template, PATH_MAX, "fcntl21XXXXXX"); 105 106 if ((fd = mkstemp(template)) < 0) { 107 tst_resm(TFAIL, "Couldn't open temp file! errno = %d", errno); 108 } 109 110 if (write(fd, buf, STRINGSIZE) < 0) { 111 tst_resm(TFAIL, "Couldn't write to temp file! errno = %d", errno); 112 } 113 114 if ((signal(SIGCLD, catch_child)) == SIG_ERR) { 115 tst_resm(TFAIL, "SIGCLD signal setup failed, errno: %d", 116 errno); 117 fail = 1; 118 } 119} 120 121/* 122 * cleanup() 123 * performs all ONE TIME cleanup for this test at completion or 124 * premature exit 125 */ 126void 127cleanup() 128{ 129 /* 130 * print timing stats if that option was specified 131 * print errno log if that option was specified 132 */ 133 TEST_CLEANUP; 134 135 136 tst_rmdir(); 137 138 /* exit with return code appropriate for results */ 139 tst_exit(); 140} 141 142void do_child() 143{ 144 struct flock fl; 145 146 close(parent_pipe[1]); 147 close(child_pipe[0]); 148 while(1) { 149 child_get(&fl); 150 if (fcntl(fd, F_GETLK, &fl) < 0) { 151 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 152 errno); 153 fail = 1; 154 } 155 child_put(&fl); 156 } 157} 158 159int do_lock(int cmd, short type, short whence, int start, int len) 160{ 161 struct flock fl; 162 163 fl.l_type = type; 164 fl.l_whence = whence; 165 fl.l_start = start; 166 fl.l_len = len; 167 return(fcntl(fd, cmd, &fl)); 168} 169 170void 171do_test(struct flock *fl, short type, short whence, int start, int len) 172{ 173 fl->l_type = type; 174 fl->l_whence = whence; 175 fl->l_start = start; 176 fl->l_len = len; 177 fl->l_pid = (short)0; 178 179 parent_put(fl); 180 parent_get(fl); 181} 182 183void 184compare_lock(struct flock *fl, short type, short whence, int start, int len, 185 pid_t pid) 186{ 187 if (fl->l_type != type) { 188 tst_resm(TFAIL, "lock type is wrong should be %s is %s", 189 str_type(type), str_type(fl->l_type)); 190 fail = 1; 191 } 192 193 if (fl->l_whence != whence) { 194 tst_resm(TFAIL, "lock whence is wrong should be %d is %d", 195 whence, fl->l_whence); 196 fail = 1; 197 } 198 199 if (fl->l_start != start) { 200 tst_resm(TFAIL, "region starts in wrong place, should be" 201 "%d is %d", start, fl->l_start); 202 fail = 1; 203 } 204 205 if (fl->l_len != len) { 206 tst_resm(TFAIL, "region length is wrong, should be %d is %d", 207 len, fl->l_len); 208 fail = 1; 209 } 210 211 if (fl->l_pid != pid) { 212 tst_resm(TFAIL, "locking pid is wrong, should be %d is %d", 213 pid, fl->l_pid); 214 fail = 1; 215 } 216} 217 218void 219unlock_file() 220{ 221 struct flock fl; 222 223 if (do_lock(F_SETLK, (short)F_UNLCK, (short)0, 0, 0) < 0) { 224 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 225 errno); 226 fail = 1; 227 } 228 do_test(&fl, F_WRLCK, 0, 0, 0); 229 compare_lock(&fl, (short)F_UNLCK, (short)0, 0, 0, (pid_t)0); 230} 231 232char * 233str_type(int type) 234{ 235 static char buf[20]; 236 237 switch (type) { 238 case 1: 239 return("F_RDLCK"); 240 case 2: 241 return("F_WRLCK"); 242 case 3: 243 return("F_UNLCK"); 244 default: 245 sprintf(buf, "BAD VALUE: %d", type); 246 return(buf); 247 } 248} 249 250void 251parent_put(struct flock *l) 252{ 253 if (write(parent_pipe[1], l, sizeof(*l)) != sizeof(*l)) { 254 tst_resm(TFAIL, "couldn't send message to child"); 255 fail = 1; 256 } 257} 258 259void 260parent_get(struct flock *l) 261{ 262 if (read(child_pipe[0], l, sizeof(*l)) != sizeof(*l)) { 263 tst_resm(TFAIL, "couldn't get message from child"); 264 fail = 1; 265 } 266} 267 268void 269child_put(struct flock *l) 270{ 271 if (write(child_pipe[1], l, sizeof(*l)) != sizeof(*l)) { 272 tst_resm(TFAIL, "couldn't send message to parent"); 273 fail = 1; 274 } 275} 276 277void 278child_get(struct flock *l) 279{ 280 if (read(parent_pipe[0], l, sizeof(*l)) != sizeof(*l)) { 281 tst_resm(TFAIL, "couldn't get message from parent"); 282 cleanup(); 283 } else if (l->l_type == (short)STOP) { 284 exit(0); 285 } 286} 287 288void 289stop_child() 290{ 291 struct flock fl; 292 293 (void) signal(SIGCLD, (void (*)())SIG_DFL); 294 fl.l_type = STOP; 295 parent_put(&fl); 296 wait(0); 297} 298 299void 300catch_child() 301{ 302 tst_resm(TFAIL, "Unexpected death of child process"); 303 cleanup(); 304} 305 306int main(int ac, char **av) 307{ 308 struct flock tl; 309 310 int lc; /* loop counter */ 311 char *msg; /* message returned from parse_opts */ 312 313 /* parse standard options */ 314 if ((msg = parse_opts(ac, av, (option_t *)NULL, NULL)) != (char *)NULL){ 315 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg); 316 } 317 318 setup(); /* global setup */ 319 320 /* Check for looping state if -i option is given */ 321 for (lc = 0; TEST_LOOPING(lc); lc++) { 322 /* reset Tst_count in case we are looping */ 323 Tst_count = 0; 324 325 if ((child_pid = fork()) == 0) { 326 do_child(); 327 } 328 if (child_pid < 0) { 329 tst_resm(TFAIL, "Fork failed"); 330 cleanup(); 331 } 332 333 (void)close(parent_pipe[0]); 334 (void)close(child_pipe[1]); 335 336//block1: 337 tst_resm(TINFO, "Enter block 1"); 338 fail = 0; 339 /* 340 * Set a read lock on the whole file 341 */ 342 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 0, 0) < 0) { 343 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 344 errno); 345 fail = 1; 346 } 347 348 /* 349 * Test to make sure it's there. 350 */ 351 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 352 compare_lock(&tl, (short)F_RDLCK, (short)0, 0, 0, parent_pid); 353 354 /* 355 * remove the lock set above 356 */ 357 unlock_file(); 358 359 if (fail) { 360 tst_resm(TINFO, "Test block 1: FAILED"); 361 } else { 362 tst_resm(TINFO, "Test block 1: PASSED"); 363 } 364 tst_resm(TINFO, "Exit block 1"); 365 366//block2: 367 tst_resm(TINFO, "Enter block 2"); 368 fail = 0; 369 370 /* 371 * Set a write lock on the whole file 372 */ 373 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 0, 0) < 0) { 374 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 375 errno); 376 fail = 1; 377 } 378 379 /* 380 * Test to make sure its there 381 */ 382 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 383 compare_lock(&tl, (short)F_WRLCK, (short)0, 0, 0, parent_pid); 384 385 /* 386 * remove the lock set above 387 */ 388 unlock_file(); 389 390 if (fail) { 391 tst_resm(TINFO, "Test block 2: FAILED"); 392 } else { 393 tst_resm(TINFO, "Test block 2: PASSED"); 394 } 395 396 tst_resm(TINFO, "Exit block 2"); 397 398//block3: 399 tst_resm(TINFO, "Enter block 3"); 400 fail = 0; 401 402 /* 403 * Add a read lock to the middle of the file and a write 404 * at the begining 405 */ 406 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 407 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 408 errno); 409 fail = 1; 410 } 411 412 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 1, 5) < 0) { 413 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 414 errno); 415 fail = 1; 416 } 417 418 /* 419 * Test write lock 420 */ 421 do_test(&tl, F_WRLCK, 0, 0, 0); 422 compare_lock(&tl, (short)F_WRLCK, (short)0, 1, 5, parent_pid); 423 424 /* 425 * Test read lock 426 */ 427 do_test(&tl, F_WRLCK, 0, 6, 0); 428 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid); 429 430 /* 431 * Test that the rest of the file is unlocked 432 */ 433 do_test(&tl, F_WRLCK, 0, 15, 0); 434 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0); 435 436 /* 437 * remove all the locks set above 438 */ 439 unlock_file(); 440 441 if (fail) { 442 tst_resm(TINFO, "Test block 3: FAILED"); 443 } else { 444 tst_resm(TINFO, "Test block 3 : PASSED"); 445 } 446 tst_resm(TINFO, "Exit block 3"); 447 448//block4: 449 tst_resm(TINFO, "Enter block 4"); 450 fail = 0; 451 452 /* 453 * Set a read lock at the middle of the file and a 454 * write lock just before 455 */ 456 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 457 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 458 errno); 459 fail = 1; 460 } 461 462 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 5) < 0) { 463 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 464 errno); 465 fail = 1; 466 } 467 468 /* 469 * Test the write lock 470 */ 471 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 472 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 5, parent_pid); 473 474 /* 475 * Test the read lock. 476 */ 477 do_test(&tl, (short)F_WRLCK, (short)0, 10, 0); 478 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid); 479 480 /* 481 * Test to make sure the rest of the file is unlocked. 482 */ 483 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0); 484 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0); 485 486 /* 487 * remove all the locks set above 488 */ 489 unlock_file(); 490 491 if (fail) { 492 tst_resm(TINFO, "Test block 4: FAILED"); 493 } else { 494 tst_resm(TINFO, "Test block 4: PASSED"); 495 } 496 tst_resm(TINFO, "Exit block 4"); 497 498//block5: 499 tst_resm(TINFO, "Enter block 5"); 500 fail = 0; 501 502 /* 503 * Set a read lock in the middle and a write lock that 504 * ends at the first byte of the read lock 505 */ 506 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 507 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 508 errno); 509 fail = 1; 510 } 511 512 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 6) < 0) { 513 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 514 errno); 515 fail = 1; 516 } 517 518 /* 519 * Test write lock 520 */ 521 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 522 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 6, parent_pid); 523 524 /* 525 * Test read lock 526 */ 527 do_test(&tl, (short)F_WRLCK, (short)0, 11, 0); 528 compare_lock(&tl, (short)F_RDLCK, (short)0, 11, 4, parent_pid); 529 530 /* 531 * Test to make sure the rest of the file is unlocked. 532 */ 533 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0); 534 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0); 535 536 /* 537 * remove all the locks set above 538 */ 539 unlock_file(); 540 541 if (fail) { 542 tst_resm(TINFO, "Test block 5: FAILED"); 543 } else { 544 tst_resm(TINFO, "Test block 5: PASSED"); 545 } 546 tst_resm(TINFO, "Exit block 5"); 547 548//block6: 549 tst_resm(TINFO, "Enter block 6"); 550 fail = 0; 551 552 /* 553 * Set a read lock on the middle of the file and a write 554 * lock that overlaps the front of the read. 555 */ 556 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 557 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 558 errno); 559 fail = 1; 560 } 561 562 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 5, 8) < 0) { 563 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 564 errno); 565 fail = 1; 566 } 567 568 /* 569 * Test the write lock 570 */ 571 do_test(&tl, (short)F_WRLCK, (short)0, 5, 0); 572 compare_lock(&tl, (short)F_WRLCK, (short)0, 5, 8, parent_pid); 573 574 /* 575 * Test the read lock 576 */ 577 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0); 578 compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 2, parent_pid); 579 580 /* 581 * Test to make sure the rest of the file is unlocked. 582 */ 583 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0); 584 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0); 585 586 /* 587 * remove all the locks set above 588 */ 589 unlock_file(); 590 591 if (fail) { 592 tst_resm(TINFO, "Test block 6 FAILED"); 593 } else { 594 tst_resm(TINFO, "Test block 6 PASSED"); 595 } 596 tst_resm(TINFO, "Exit block 6"); 597 598//block7: 599 tst_resm(TINFO, "Enter block 7"); 600 fail = 0; 601 602 /* 603 * Set a read lock in the middle of a file and a write 604 * lock in the middle of it 605 */ 606 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 10) < 0) { 607 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 608 errno); 609 fail = 1; 610 } 611 612 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) { 613 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 614 errno); 615 fail = 1; 616 } 617 618 /* 619 * Test the first read lock 620 */ 621 do_test(&tl, (short)F_WRLCK, (short)0 , 0, 0); 622 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid); 623 624 /* 625 * Test the write lock 626 */ 627 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0); 628 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid); 629 630 /* 631 * Test the second read lock 632 */ 633 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0); 634 compare_lock(&tl, (short)F_RDLCK, (short)0, 18, 2, parent_pid); 635 636 /* 637 * Test to make sure the rest of the file is unlocked 638 */ 639 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0); 640 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0); 641 642 /* 643 * remove all the locks set above. 644 */ 645 unlock_file(); 646 if (fail) { 647 tst_resm(TINFO, "Test block 7: FAILED"); 648 } else { 649 tst_resm(TINFO, "Test block 7: PASSED"); 650 } 651 tst_resm(TINFO, "Exit block 7"); 652 653//block8: 654 tst_resm(TINFO, "Enter block 8"); 655 fail = 0; 656 /* 657 * Set a read lock in the middle of the file and a write 658 * lock that overlaps the end 659 */ 660 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 661 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 662 errno); 663 fail = 1; 664 } 665 666 /* 667 * Set a write lock on the whole file 668 */ 669 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 13, 5) < 0) { 670 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 671 errno); 672 fail = 1; 673 } 674 675 /* 676 * Test the read lock 677 */ 678 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 679 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 3, parent_pid); 680 681 /* 682 * Test the write lock 683 */ 684 do_test(&tl, (short)F_WRLCK, (short)0, 13, 0); 685 compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 5, parent_pid); 686 687 /* 688 * Test to make sure the rest of the file is unlocked 689 */ 690 do_test(&tl, (short)F_WRLCK, (short)0, 18, 0); 691 compare_lock(&tl, (short)F_UNLCK, (short)0, 18, 0, 0); 692 693 /* 694 * remove all the locks set above 695 */ 696 unlock_file(); 697 698 if (fail) { 699 tst_resm(TINFO, "Test block 8: FAILED"); 700 } else { 701 tst_resm(TINFO, "Test block 8: PASSED"); 702 } 703 tst_resm(TINFO, "Exit block 8"); 704 705//block9: 706 tst_resm(TINFO, "Enter block 9"); 707 fail = 0; 708 709 /* 710 * Set a read lock in the middle of the file and a write 711 * lock starting at the last byte of the read lock 712 */ 713 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 714 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 715 errno); 716 fail = 1; 717 } 718 719 /* 720 * Set a write lock on the whole file. 721 */ 722 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 14, 5) < 0) { 723 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 724 errno); 725 fail = 1; 726 } 727 728 /* 729 * Test read lock 730 */ 731 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 732 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 4, parent_pid); 733 734 /* 735 * Test the write lock 736 */ 737 do_test(&tl, (short)F_WRLCK, (short)0, 14, 0); 738 compare_lock(&tl, (short)F_WRLCK, (short)0, 14, 5, parent_pid); 739 740 /* 741 * Test to make sure the end of the file is unlocked 742 */ 743 do_test(&tl, (short)F_WRLCK, (short)0, 19, 0); 744 compare_lock(&tl, (short)F_UNLCK, (short)0, 19, 0, 0); 745 746 /* 747 * remove all the locks set above 748 */ 749 unlock_file(); 750 751 if (fail) { 752 tst_resm(TINFO, "Test block 9: FAILED"); 753 } else { 754 tst_resm(TINFO, "Test block 9: PASSED"); 755 } 756 tst_resm(TINFO, "Exit block 9"); 757 758//block10: 759 tst_resm(TINFO, "Enter block 10"); 760 fail = 0; 761 762 /* 763 * Set a read lock in the middle of the file and a write 764 * lock that starts just after the last byte of the 765 * read lock. 766 */ 767 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 768 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 769 errno); 770 fail = 1; 771 } 772 773 /* 774 * Set a write lock on the whole file 775 */ 776 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 15, 5) < 0) { 777 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 778 errno); 779 fail = 1; 780 } 781 782 /* 783 * Test the read lock 784 */ 785 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 786 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid); 787 788 /* 789 * Test the write lock 790 */ 791 do_test(&tl, (short)F_WRLCK, (short)0, 15, 0); 792 compare_lock(&tl, (short)F_WRLCK, (short)0, 15, 5, parent_pid); 793 794 /* 795 * Test to make sure the rest of the file is unlocked 796 */ 797 do_test(&tl, (short)F_WRLCK, (short)0, 20, 0); 798 compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0); 799 800 /* 801 * remove all the locks set above 802 */ 803 unlock_file(); 804 805 if (fail) { 806 tst_resm(TINFO, "Test block 10: FAILED"); 807 } else { 808 tst_resm(TINFO, "Test block 10: PASSED"); 809 } 810 tst_resm(TINFO, "Exit block 10"); 811 812//block11: 813 tst_resm(TINFO, "Enter block 11"); 814 fail = 0; 815 816 /* 817 * Set a read lock at the middle of the file and a write 818 * lock that starts past the end of the read lock. 819 */ 820 if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 10, 5) < 0) { 821 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 822 errno); 823 fail = 1; 824 } 825 826 if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 16, 5) < 0) { 827 tst_resm(TFAIL, "fcntl on file failed, errno =%d", 828 errno); 829 fail = 1; 830 } 831 832 /* 833 * Test the read lock 834 */ 835 do_test(&tl, (short)F_WRLCK, (short)0, 0, 0); 836 compare_lock(&tl, (short)F_RDLCK, (short)0, 10, 5, parent_pid); 837 838 /* 839 * Test that byte in between is unlocked 840 */ 841 do_test(&tl, (short)F_WRLCK, (short)0, 15, 1); 842 compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 1, 0); 843 844 /* 845 * Test the write lock 846 */ 847 do_test(&tl, (short)F_WRLCK, (short)0, 16, 0); 848 compare_lock(&tl, (short)F_WRLCK, (short)0, 16, 5, parent_pid); 849 850 /* 851 * Test to make sure the rest of the file is unlocked 852 */ 853 do_test(&tl, (short)F_WRLCK, (short)0, 21, 0); 854 compare_lock(&tl, (short)F_UNLCK, (short)0, 21, 0, 0); 855 856 /* 857 * remove all the locks set above 858 */ 859 unlock_file(); 860 861 if (fail) { 862 tst_resm(TINFO, "Test block 11: FAILED"); 863 } else { 864 tst_resm(TINFO, "Test block 11: PASSED"); 865 } 866 tst_resm(TINFO, "Exit block 11"); 867 868 stop_child(); 869 close(fd); 870 } 871 cleanup(); 872 return(0); 873} 874