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