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  *	fcntl14.c
     23  *
     24  * DESCRIPTION
     25  *	File locking test cases for fcntl. In Linux, S_ENFMT is not implemented
     26  *	in the kernel. However all standard Unix kernels define S_ENFMT as
     27  *	S_ISGID. So this test defines S_ENFMT as S_ISGID.
     28  *
     29  * ALGORITHM
     30  *	Various test cases are used to lock a file opened without mandatory
     31  *	locking, with mandatory locking and mandatory locking with NOBLOCK
     32  *
     33  * USAGE
     34  *	fcntl14
     35  *
     36  * HISTORY
     37  *	07/2001 Ported by Wayne Boyer
     38  *
     39  * RESTRICTIONS
     40  *	None
     41  */
     42 #define _GNU_SOURCE 1
     43 #include <fcntl.h>
     44 #include <sys/types.h>
     45 #include <sys/stat.h>
     46 #include <signal.h>
     47 #include <errno.h>
     48 #include <sys/wait.h>
     49 #include <inttypes.h>
     50 #include "test.h"
     51 
     52 #define SKIP 0x0c00
     53 #if SKIP == F_RDLCK || SKIP== F_WRLCK
     54 #error invalid value for SKIP, must be distinct from F_RDLCK and F_WRLCK
     55 #endif
     56 #ifndef S_ENFMT
     57 #define S_ENFMT S_ISGID
     58 #endif
     59 
     60 /* NOBLOCK - immediate success */
     61 #define NOBLOCK 2
     62 
     63 /* WILLBLOCK - blocks, then succeeds (parent must unlock records) */
     64 #define WILLBLOCK 3
     65 
     66 #define TIME_OUT 60
     67 
     68 typedef struct {
     69 	short a_type;
     70 	short a_whence;
     71 	long a_start;
     72 	long a_len;
     73 	short b_type;		/* SKIP means suppress fcntl call */
     74 	short b_whence;
     75 	long b_start;
     76 	long b_len;
     77 	short c_type;
     78 	int c_whence;
     79 	long c_start;
     80 	long c_len;
     81 	short c_flag;
     82 } testcase;
     83 
     84 static testcase testcases[] = {
     85 	/* Test cases: entire boundary */
     86 	/* #1 Parent making a write lock on entire file */
     87 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
     88 	 /* Child attempting a read lock on entire file */
     89 	 F_RDLCK, 0, 0L, 0L, WILLBLOCK},
     90 
     91 	/* #2 Parent making a write lock on entire file */
     92 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
     93 	 /* Child attempting a write lock on entire file */
     94 	 F_WRLCK, 0, 0L, 0L, WILLBLOCK},
     95 
     96 	/* #3 Parent making a read lock on entire file */
     97 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
     98 	 /* Child attempting a read lock on entire file */
     99 	 F_RDLCK, 0, 0L, 0L, NOBLOCK},
    100 
    101 	/* #4 Parent making a read lock on entire file */
    102 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    103 	 /* Child attempting a write lock on entire file */
    104 	 F_WRLCK, 0, 0L, 0L, WILLBLOCK},
    105 
    106 	/* Test case: start boundary */
    107 	/* #5 Parent making a write lock on entire file */
    108 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    109 	 /*
    110 	  * Child attempting a read lock from beginning of
    111 	  * file for 5 bytes
    112 	  */
    113 	 F_RDLCK, 0, 0L, 5L, WILLBLOCK},
    114 
    115 	/* #6 Parent making a write lock on entire file */
    116 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    117 	 /*
    118 	  * Child attempting a write lock from beginning of
    119 	  * file for 5 bytes
    120 	  */
    121 	 F_WRLCK, 0, 0L, 5L, WILLBLOCK},
    122 
    123 	/* #7 Parent making a read lock on entire file */
    124 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    125 	 /*
    126 	  * Child attempting a read lock from beginning of
    127 	  * file for 5 bytes
    128 	  */
    129 	 F_RDLCK, 0, 0L, 5L, NOBLOCK},
    130 
    131 	/* #8 Parent making a read lock on entire file */
    132 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    133 	 /*
    134 	  * Child attempting a write lock from beginning of
    135 	  * file for 5 bytes
    136 	  */
    137 	 F_WRLCK, 0, 0L, 5L, WILLBLOCK},
    138 
    139 	/* Test cases: end boundary */
    140 	/* #9 Parent making a write lock on entire file */
    141 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    142 	 /* Child attempting a read lock from byte 7 to end of file */
    143 	 F_RDLCK, 0, 7L, 0L, WILLBLOCK},
    144 
    145 	/* #10 Parent making a write lock on entire file */
    146 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    147 	 /* Child attempting a write lock from byte 7 to end of file */
    148 	 F_WRLCK, 0, 7L, 0L, WILLBLOCK},
    149 
    150 	/* #11 Parent making a read lock on entire file */
    151 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    152 	 /* Child attempting a read lock from byte 7 to end of file */
    153 	 F_RDLCK, 0, 7L, 0L, NOBLOCK},
    154 
    155 	/* #12 Parent making a read lock on entire file */
    156 	{F_RDLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    157 	 /* Child attempting a write lock from byte 7 to end of file */
    158 	 F_WRLCK, 0, 7L, 0L, WILLBLOCK},
    159 
    160 	/* Test cases: entire boundary ( less than entire file) */
    161 	/*
    162 	 * #13 Parent making a write lock from beginning of
    163 	 * file for 5 bytes
    164 	 */
    165 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    166 	 /*
    167 	  * Child attempting a read lock from beginning of
    168 	  * file for 5 bytes
    169 	  */
    170 	 F_RDLCK, 0, 0L, 5L, WILLBLOCK},
    171 
    172 	/*
    173 	 * #14 Parent making a write lock from beginning of file
    174 	 * for 5 bytes
    175 	 */
    176 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    177 	 /*
    178 	  * Child attempting a write lock from beginning of
    179 	  * file for 5 bytes
    180 	  */
    181 	 F_WRLCK, 0, 0L, 5L, WILLBLOCK},
    182 
    183 	/*
    184 	 * #15 Parent making a read lock from beginning of
    185 	 * file for 5 bytes
    186 	 */
    187 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    188 	 /*
    189 	  * Child attempting a read lock from beginning of
    190 	  * file for 5 bytes
    191 	  */
    192 	 F_RDLCK, 0, 0L, 5L, NOBLOCK},
    193 
    194 	/*
    195 	 * #16 Parent making a read lock from beginning of
    196 	 * file for 5 bytes
    197 	 */
    198 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    199 	 /*
    200 	  * Child attempting a write lock from beginning
    201 	  * of file for 5 bytes
    202 	  */
    203 	 F_WRLCK, 0, 0L, 5L, WILLBLOCK},
    204 
    205 	/* Test cases: inside boundary */
    206 	/*
    207 	 * #17 Parent making a write lock from beginning
    208 	 * of file for 5 bytes
    209 	 */
    210 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    211 	 /* Child attempting a read lock from byte 2 to byte 4 */
    212 	 F_RDLCK, 0, 1L, 3L, WILLBLOCK},
    213 
    214 	/*
    215 	 * #18 Parent making a write lock from beginning of
    216 	 * file for 5 bytes
    217 	 */
    218 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    219 	 /* Child attempting a write lock from byte 2 to byte 4 */
    220 	 F_WRLCK, 0, 1L, 3L, WILLBLOCK},
    221 
    222 	/*
    223 	 * #19 Parent making a read lock from beginning of
    224 	 * file for 5 bytes
    225 	 */
    226 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    227 	 /* Child attempting a read lock from byte 2 to byte 4 */
    228 	 F_RDLCK, 0, 1L, 3L, NOBLOCK},
    229 
    230 	/*
    231 	 * #20 Parent making a read lock from beginning of
    232 	 * file for 5 bytes
    233 	 */
    234 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    235 	 /* Child attempting a write lock from byte 2 to byte 4 */
    236 	 F_WRLCK, 0, 1L, 3L, WILLBLOCK},
    237 
    238 	/* Test cases: cross boundary (inside to after) */
    239 	/*
    240 	 * #21 Parent making a write lock from beginning of
    241 	 * file for 5 bytes
    242 	 */
    243 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    244 	 /* Child attempting a read lock from byte 3 to byte 7 */
    245 	 F_RDLCK, 0, 2L, 5L, WILLBLOCK},
    246 
    247 	/*
    248 	 * #22 Parent making a write lock from beginning
    249 	 * of file for 5 bytes
    250 	 */
    251 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    252 	 /* Child attempting a write lock from byte 3 to byte 7 */
    253 	 F_WRLCK, 0, 2L, 5L, WILLBLOCK},
    254 
    255 	/*
    256 	 * #23 Parent making a read lock from beginning of
    257 	 * file for 5 bytes
    258 	 */
    259 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    260 	 /* Child attempting a read lock from byte 3 to byte 7 */
    261 	 F_RDLCK, 0, 2L, 5L, NOBLOCK},
    262 
    263 	/*
    264 	 * #24 Parent making a read lock from beginning of
    265 	 * file for 5 bytes
    266 	 */
    267 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    268 	 /* Child attempting a write lock from byte 3 to byte 7 */
    269 	 F_WRLCK, 0, 2L, 5L, WILLBLOCK},
    270 
    271 	/* Test cases: outside boundary (after) */
    272 
    273 	/*
    274 	 * #25 Parent making a write lock from beginning of
    275 	 * file for 5 bytes
    276 	 */
    277 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    278 	 /*  Child attempting a read lock from byte 7 to end of file */
    279 	 F_RDLCK, 0, 6L, 0L, NOBLOCK},
    280 
    281 	/*
    282 	 * #26 Parent making a write lock from beginning of
    283 	 * file for 5 bytes
    284 	 */
    285 	{F_WRLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    286 	 /* Child attempting a write lock from byte 7 to end of file */
    287 	 F_WRLCK, 0, 6L, 0L, NOBLOCK},
    288 
    289 	/*
    290 	 * #27 Parent making a read lock from beginning of
    291 	 * file for 5 bytes
    292 	 */
    293 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    294 	 /* Child attempting a read lock from byte 7 to end of file */
    295 	 F_RDLCK, 0, 6L, 0L, NOBLOCK},
    296 
    297 	/*
    298 	 * #28 Parent making a read lock from beginning of
    299 	 * file for 5 bytes
    300 	 */
    301 	{F_RDLCK, 0, 0L, 5L, SKIP, 0, 0L, 0L,
    302 	 /* Child attempting a write lock from byte 7 to end of file */
    303 	 F_WRLCK, 0, 6L, 0L, NOBLOCK},
    304 
    305 	/* Test cases: outside boundary (before) */
    306 
    307 	/* #29 Parent making a write lock from byte 3 to byte 7 */
    308 	{F_WRLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
    309 	 /* Child attempting a read lock from beginning of file to byte 2 */
    310 	 F_RDLCK, 0, 0L, 2L, NOBLOCK},
    311 
    312 	/* #30 Parent making a write lock from byte 3 to byte 7 */
    313 	{F_WRLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
    314 	 /* Child attempting a write lock from beginning of file to byte 2 */
    315 	 F_WRLCK, 0, 0L, 2L, NOBLOCK},
    316 
    317 	/* #31 Parent making a write lock from byte 3 to byte 7 */
    318 	{F_RDLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
    319 	 /* Child attempting a read lock from beginning of file to byte 2 */
    320 	 F_RDLCK, 0, 0L, 2L, NOBLOCK},
    321 
    322 	/* #32 Parent making a write lock from byte 3 to byte 7 */
    323 	{F_RDLCK, 0, 2L, 5L, SKIP, 0, 0L, 0L,
    324 	 /* Child attempting a write lock from beginning of file to byte 2 */
    325 	 F_WRLCK, 0, 0L, 2L, NOBLOCK},
    326 
    327 	/* Test cases: cross boundary (before to inside) */
    328 	/* #33 Parent making a write lock from byte 5 to end of file */
    329 	{F_WRLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
    330 	 /* Child attempting a read lock from byte 3 to byte 7 */
    331 	 F_RDLCK, 0, 2L, 5L, WILLBLOCK},
    332 
    333 	/* #34 Parent making a write lock from byte 5 to end of file */
    334 	{F_WRLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
    335 	 /* Child attempting a write lock from byte 3 to byte 7 */
    336 	 F_WRLCK, 0, 2L, 5L, WILLBLOCK},
    337 
    338 	/* #35 Parent making a read lock from byte 5 to end of file */
    339 	{F_RDLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
    340 	 /* Child attempting a read lock from byte 3 to byte 7 */
    341 	 F_RDLCK, 0, 2L, 5L, NOBLOCK},
    342 
    343 	/* #36 Parent making a read lock from byte 5 to end of file */
    344 	{F_RDLCK, 0, 4L, 0L, SKIP, 0, 0L, 0L,
    345 	 /* Child attempting a write lock from byte 3 to byte 7 */
    346 	 F_WRLCK, 0, 2L, 5L, WILLBLOCK},
    347 
    348 	/* Start of negative L_start and L_len test cases */
    349 	/*
    350 	 * #37 Parent making write lock from byte 2 to byte 3
    351 	 * with L_start = -3
    352 	 */
    353 	{F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
    354 	 /* Child attempting write lock on byte 1 */
    355 	 F_WRLCK, 0, 1L, 1L, NOBLOCK},
    356 
    357 	/*
    358 	 * #38 Parent making write lock from byte 2 to byte 3
    359 	 * with L_start = -3
    360 	 */
    361 	{F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
    362 	 /* Child attempting write lock on byte 4 */
    363 	 F_WRLCK, 0, 4L, 1L, NOBLOCK},
    364 
    365 	/*
    366 	 * #39 Parent making write lock from byte 2 to byte 3
    367 	 * with L_start = -3
    368 	 */
    369 	{F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
    370 	 /* Child attempting write lock on byte 2 */
    371 	 F_WRLCK, 0, 2L, 1L, WILLBLOCK},
    372 
    373 	/*
    374 	 * #40 Parent making write lock from byte 2 to byte 3
    375 	 * with L_start = -3
    376 	 */
    377 	{F_WRLCK, 1, -3L, 2L, SKIP, 0, 0L, 0L,
    378 	 /* Child attempting write lock on byte 3 */
    379 	 F_WRLCK, 0, 3L, 1L, WILLBLOCK},
    380 
    381 	/*
    382 	 * #41 Parent making write lock from byte 2 to byte 6
    383 	 * with L_start = -3
    384 	 */
    385 	{F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
    386 	 /* Child attempting write lock on byte 1 */
    387 	 F_WRLCK, 0, 1L, 1L, NOBLOCK},
    388 
    389 	/*
    390 	 * #42 Parent making write lock from byte 2 to byte 6
    391 	 * with L_start = -3
    392 	 */
    393 	{F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
    394 	 /* Child attempting write lock on byte 7 */
    395 	 F_WRLCK, 0, 1L, 1L, NOBLOCK},
    396 
    397 	/*
    398 	 * #43 Parent making write lock from byte 2 to byte 6
    399 	 * with L_start = -3
    400 	 */
    401 	{F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
    402 	 /* Child attempting write lock on byte 2 */
    403 	 F_WRLCK, 0, 2L, 1L, WILLBLOCK},
    404 
    405 	/*
    406 	 * #44 Parent making write lock from byte 2 to byte 6
    407 	 * with L_start = -3
    408 	 */
    409 	{F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
    410 	 /* Child attempting write lock on byte 5 */
    411 	 F_WRLCK, 0, 5L, 1L, WILLBLOCK},
    412 
    413 	/*
    414 	 * #45 Parent making write lock from byte 2 to byte 6
    415 	 * with L_start = -3
    416 	 */
    417 	{F_WRLCK, 1, -3L, 5L, SKIP, 0, 0L, 0L,
    418 	 /* Child attempting write lock on byte 6 */
    419 	 F_WRLCK, 0, 6L, 1L, WILLBLOCK},
    420 
    421 	/*
    422 	 * #46 Parent making write lock from byte 2 to byte 3 with
    423 	 * L_start = -2 and L_len = -2
    424 	 */
    425 	{F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
    426 	 /* Child attempting write lock on byte 1 */
    427 	 F_WRLCK, 0, 1L, 1L, NOBLOCK},
    428 
    429 	/*
    430 	 * #47 Parent making write lock from byte 2 to byte 3 with
    431 	 * L_start = -2 and L_len = -2
    432 	 */
    433 	{F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
    434 	 /* Child attempting write lock on byte 4 */
    435 	 F_WRLCK, 0, 4L, 1L, NOBLOCK},
    436 
    437 	/*
    438 	 * #48 Parent making write lock from byte 2 to byte 3 with
    439 	 * L_start = -2 and L_len = -2
    440 	 */
    441 	{F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
    442 	 /* Child attempting write lock on byte 2 */
    443 	 F_WRLCK, 0, 2L, 1L, WILLBLOCK},
    444 
    445 	/*
    446 	 * #49 Parent making write lock from byte 2 to byte 3 with
    447 	 * L_start = -2 and L_len = -2
    448 	 */
    449 	{F_WRLCK, 1, -2L, -2L, SKIP, 0, 0L, 0L,
    450 	 /* Child attempting write lock on byte 3 */
    451 	 F_WRLCK, 0, 3L, 1L, WILLBLOCK},
    452 
    453 	/*
    454 	 * #50 Parent making write lock from byte 6 to byte 7 with
    455 	 * L_start = 2 and L_len = -2
    456 	 */
    457 	{F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
    458 	 /* Child attempting write lock on byte 5 */
    459 	 F_WRLCK, 0, 5L, 1L, NOBLOCK},
    460 
    461 	/*
    462 	 * #51 Parent making write lock from byte 6 to byte 7 with
    463 	 * L_start = 2 and L_len = -2
    464 	 */
    465 	{F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
    466 	 /* Child attempting write lock on byte 8 */
    467 	 F_WRLCK, 0, 8L, 1L, NOBLOCK},
    468 
    469 	/*
    470 	 * #52 Parent making write lock from byte 6 to byte 7 with
    471 	 * L_start = 2 and L_len = -2
    472 	 */
    473 	{F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
    474 	 /* Child attempting write lock on byte 6 */
    475 	 F_WRLCK, 0, 6L, 1L, WILLBLOCK},
    476 
    477 	/*
    478 	 * #53 Parent making write lock from byte 6 to byte 7 with
    479 	 * L_start = 2 and L_len = -2
    480 	 */
    481 	{F_WRLCK, 1, 2L, -2L, SKIP, 0, 0L, 0L,
    482 	 /* Child attempting write lock on byte 7 */
    483 	 F_WRLCK, 0, 7L, 1L, WILLBLOCK},
    484 
    485 	/*
    486 	 * #54 Parent making write lock from byte 3 to byte 7 with
    487 	 * L_start = 2 and L_len = -5
    488 	 */
    489 	{F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
    490 	 /* Child attempting write lock on byte 2 */
    491 	 F_WRLCK, 0, 2L, 1L, NOBLOCK},
    492 
    493 	/*
    494 	 * #55 Parent making write lock from byte 3 to byte 7 with
    495 	 * L_start = 2 and L_len = -5
    496 	 */
    497 	{F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
    498 	 /* Child attempting write lock on byte 8 */
    499 	 F_WRLCK, 0, 8L, 1L, NOBLOCK},
    500 
    501 	/*
    502 	 * #56 Parent making write lock from byte 3 to byte 7 with
    503 	 * L_start = 2 and L_len = -5
    504 	 */
    505 	{F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
    506 	 /* Child attempting write lock on byte 3 */
    507 	 F_WRLCK, 0, 3L, 1L, WILLBLOCK},
    508 
    509 	/*
    510 	 * #57 Parent making write lock from byte 3 to byte 7 with
    511 	 * L_start = 2 and L_len = -5
    512 	 */
    513 	{F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
    514 	 /* Child attempting write lock on byte 5 */
    515 	 F_WRLCK, 0, 5L, 1L, WILLBLOCK},
    516 
    517 	/*
    518 	 * #58 Parent making write lock from byte 3 to byte 7 with
    519 	 * L_start = 2 and L_len = -5
    520 	 */
    521 	{F_WRLCK, 1, 2L, -5L, SKIP, 0, 0L, 0L,
    522 	 /* Child attempting write lock on byte 7 */
    523 	 F_WRLCK, 0, 7L, 1L, WILLBLOCK},
    524 
    525 	/* Test case for block 4 */
    526 	/* #59 Parent making write lock on entire file */
    527 	{F_WRLCK, 0, 0L, 0L, SKIP, 0, 0L, 0L,
    528 	 /* Child attempting write lock on byte 15 to end of file */
    529 	 F_WRLCK, 0, 15L, 0L, WILLBLOCK},
    530 };
    531 
    532 static testcase *thiscase;
    533 static struct flock flock;
    534 static int parent, child, status, fail = 0;
    535 static int got1 = 0;
    536 static int fd;
    537 static int test;
    538 static char tmpname[40];
    539 
    540 #define FILEDATA	"ten bytes!"
    541 
    542 void catch1(int sig);
    543 void catch_alarm(int sig);
    544 
    545 char *TCID = "fcntl14";
    546 int TST_TOTAL = 1;
    547 int NO_NFS = 1;
    548 
    549 #ifdef UCLINUX
    550 static char *argv0;
    551 #endif
    552 
    553 void cleanup(void)
    554 {
    555 	tst_rmdir();
    556 }
    557 
    558 void setup(void)
    559 {
    560 	struct sigaction act;
    561 
    562 	tst_sig(FORK, DEF_HANDLER, cleanup);
    563 	signal(SIGHUP, SIG_IGN);
    564 	umask(0);
    565 	TEST_PAUSE;
    566 	tst_tmpdir();
    567 	parent = getpid();
    568 
    569 	sprintf(tmpname, "fcntl2.%d", parent);
    570 
    571 	/* setup signal handler for signal from child */
    572 	memset(&act, 0, sizeof(act));
    573 	act.sa_handler = catch1;
    574 	sigemptyset(&act.sa_mask);
    575 	sigaddset(&act.sa_mask, SIGUSR1);
    576 	if ((sigaction(SIGUSR1, &act, NULL)) < 0) {
    577 		tst_resm(TFAIL, "SIGUSR1 signal setup failed, errno = %d",
    578 			 errno);
    579 		cleanup();
    580 	}
    581 
    582 	memset(&act, 0, sizeof(act));
    583 	act.sa_handler = catch_alarm;
    584 	sigemptyset(&act.sa_mask);
    585 	sigaddset(&act.sa_mask, SIGALRM);
    586 	if ((sigaction(SIGALRM, &act, NULL)) < 0) {
    587 		tst_resm(TFAIL, "SIGALRM signal setup failed");
    588 		cleanup();
    589 	}
    590 }
    591 
    592 void wake_parent(void)
    593 {
    594 	if ((kill(parent, SIGUSR1)) < 0) {
    595 		tst_resm(TFAIL, "Attempt to send signal to parent " "failed");
    596 		tst_resm(TFAIL, "Test case %d, errno = %d", test + 1, errno);
    597 		fail = 1;
    598 	}
    599 }
    600 
    601 void do_usleep_child(void)
    602 {
    603 	usleep(100000);		/* XXX how long is long enough? */
    604 	wake_parent();
    605 	exit(0);
    606 }
    607 
    608 void dochild(void)
    609 {
    610 	int rc;
    611 	pid_t pid;
    612 
    613 	flock.l_type = thiscase->c_type;
    614 	flock.l_whence = thiscase->c_whence;
    615 	flock.l_start = thiscase->c_start;
    616 	flock.l_len = thiscase->c_len;
    617 	flock.l_pid = 0;
    618 	fail = 0;
    619 
    620 	/*
    621 	 * Check to see if child lock will succeed. If it will, FLOCK
    622 	 * structure will return with l_type changed to F_UNLCK. If it will
    623 	 * not, the parent pid will be returned in l_pid and the type of
    624 	 * lock that will block it in l_type.
    625 	 */
    626 	if ((rc = fcntl(fd, F_GETLK, &flock)) < 0) {
    627 		tst_resm(TFAIL, "Attempt to check lock status failed");
    628 		tst_resm(TFAIL, "Test case %d, errno = %d", test + 1, errno);
    629 		fail = 1;
    630 	} else {
    631 
    632 		if ((thiscase->c_flag) == NOBLOCK) {
    633 			if (flock.l_type != F_UNLCK) {
    634 				tst_resm(TFAIL,
    635 					 "Test case %d, GETLK: type = %d, "
    636 					 "%d was expected", test + 1,
    637 					 flock.l_type, F_UNLCK);
    638 				fail = 1;
    639 			}
    640 
    641 			if (flock.l_whence != thiscase->c_whence) {
    642 				tst_resm(TFAIL,
    643 					 "Test case %d, GETLK: whence = %d, "
    644 					 "should have remained %d", test + 1,
    645 					 flock.l_whence, thiscase->c_whence);
    646 				fail = 1;
    647 			}
    648 
    649 			if (flock.l_start != thiscase->c_start) {
    650 				tst_resm(TFAIL,
    651 					 "Test case %d, GETLK: start = %" PRId64
    652 					 ", " "should have remained %" PRId64,
    653 					 test + 1, (int64_t) flock.l_start,
    654 					 (int64_t) thiscase->c_start);
    655 				fail = 1;
    656 			}
    657 
    658 			if (flock.l_len != thiscase->c_len) {
    659 				tst_resm(TFAIL,
    660 					 "Test case %d, GETLK: len = %" PRId64
    661 					 ", " "should have remained %" PRId64,
    662 					 test + 1, (int64_t) flock.l_len,
    663 					 (int64_t) thiscase->c_len);
    664 				fail = 1;
    665 			}
    666 
    667 			if (flock.l_pid != 0) {
    668 				tst_resm(TFAIL,
    669 					 "Test case %d, GETLK: pid = %d, "
    670 					 "should have remained 0", test + 1,
    671 					 flock.l_pid);
    672 				fail = 1;
    673 			}
    674 		} else {
    675 			if (flock.l_pid != parent) {
    676 				tst_resm(TFAIL,
    677 					 "Test case %d, GETLK: pid = %d, "
    678 					 "should be parent's id of %d",
    679 					 test + 1, flock.l_pid, parent);
    680 				fail = 1;
    681 			}
    682 
    683 			if (flock.l_type != thiscase->a_type) {
    684 				tst_resm(TFAIL,
    685 					 "Test case %d, GETLK: type = %d, "
    686 					 "should be parent's first lock type of %d",
    687 					 test + 1, flock.l_type,
    688 					 thiscase->a_type);
    689 				fail = 1;
    690 			}
    691 		}
    692 	}
    693 
    694 	/*
    695 	 * now try to set the lock, nonblocking
    696 	 * This will succeed for NOBLOCK,
    697 	 * fail for WILLBLOCK
    698 	 */
    699 	flock.l_type = thiscase->c_type;
    700 	flock.l_whence = thiscase->c_whence;
    701 	flock.l_start = thiscase->c_start;
    702 	flock.l_len = thiscase->c_len;
    703 	flock.l_pid = 0;
    704 
    705 	if ((rc = fcntl(fd, F_SETLK, &flock)) < 0) {
    706 		if ((thiscase->c_flag) == NOBLOCK) {
    707 			tst_resm(TFAIL, "Attempt to set child NONBLOCKING "
    708 				 "lock failed");
    709 			tst_resm(TFAIL, "Test case %d, errno = %d",
    710 				 test + 1, errno);
    711 			fail = 1;
    712 		}
    713 	}
    714 
    715 	if ((thiscase->c_flag) == WILLBLOCK) {
    716 		if (rc != -1 || (errno != EACCES && errno != EAGAIN)) {
    717 			tst_resm(TFAIL,
    718 				 "SETLK: rc = %d, errno = %d, -1/EAGAIN or EACCES "
    719 				 "was expected", rc, errno);
    720 			fail = 1;
    721 		}
    722 		if (rc == 0) {
    723 			/* accidentally got the lock */
    724 			/* XXX how to clean up? */
    725 			(void)fcntl(fd, F_UNLCK, &flock);
    726 		}
    727 		/*
    728 		 * Lock should succeed after blocking and parent releases
    729 		 * lock, tell the parent to release the locks.
    730 		 * Do the lock in this process, send the signal in a child
    731 		 * process, so that the SETLKW actually uses the blocking
    732 		 * mechanism in the kernel.
    733 		 *
    734 		 * XXX inherent race: we want to wait until the
    735 		 * F_SETLKW has started, but we don't have a way to
    736 		 * check that reliably in the child.  (We'd
    737 		 * need some way to have fcntl() atomically unblock a
    738 		 * signal and wait for the lock.)
    739 		 */
    740 		pid = FORK_OR_VFORK();
    741 		switch (pid) {
    742 		case -1:
    743 			tst_resm(TFAIL, "Fork failed");
    744 			fail = 1;
    745 			break;
    746 		case 0:
    747 #ifdef UCLINUX
    748 			if (self_exec(argv0, "nd", 1, parent) < 0) {
    749 				tst_resm(TFAIL, "self_exec failed");
    750 				break;
    751 			}
    752 #else
    753 			do_usleep_child();
    754 #endif
    755 			break;
    756 
    757 		default:
    758 			if ((rc = fcntl(fd, F_SETLKW, &flock)) < 0) {
    759 				tst_resm(TFAIL, "Attempt to set child BLOCKING "
    760 					 "lock failed");
    761 				tst_resm(TFAIL, "Test case %d, errno = %d",
    762 					 test + 1, errno);
    763 				fail = 1;
    764 			}
    765 			waitpid(pid, &status, 0);
    766 			break;
    767 		}
    768 	}
    769 	if (fail) {
    770 		exit(1);
    771 	} else {
    772 		exit(0);
    773 	}
    774 }
    775 
    776 void run_test(int file_flag, int file_mode, int seek, int start, int end)
    777 {
    778 	extern long time();
    779 
    780 	fail = 0;
    781 
    782 	for (test = start; test < end; test++) {
    783 		fd = open(tmpname, file_flag, file_mode);
    784 		if (fd < 0)
    785 			tst_brkm(TBROK, cleanup, "open() failed");
    786 
    787 		if (write(fd, FILEDATA, 10) < 0)
    788 			tst_brkm(TBROK, cleanup, "write() failed");
    789 
    790 		if (seek) {
    791 			if (lseek(fd, seek, 0) < 0)
    792 				tst_brkm(TBROK, cleanup, "lseek() failed");
    793 		}
    794 
    795 		thiscase = &testcases[test];
    796 		flock.l_type = thiscase->a_type;
    797 		flock.l_whence = thiscase->a_whence;
    798 		flock.l_start = thiscase->a_start;
    799 		flock.l_len = thiscase->a_len;
    800 
    801 		/* set the initial parent lock on the file */
    802 		if ((fcntl(fd, F_SETLK, &flock)) < 0) {
    803 			tst_resm(TFAIL, "First parent lock failed");
    804 			tst_resm(TFAIL, "Test case %d, errno = %d",
    805 				 test + 1, errno);
    806 			fail = 1;
    807 		}
    808 
    809 		if ((thiscase->b_type) != SKIP) {
    810 			flock.l_type = thiscase->b_type;
    811 			flock.l_whence = thiscase->b_whence;
    812 			flock.l_start = thiscase->b_start;
    813 			flock.l_len = thiscase->b_len;
    814 
    815 			/* set the second parent lock */
    816 			if ((fcntl(fd, F_SETLK, &flock)) < 0) {
    817 				tst_resm(TFAIL, "Second parent lock failed");
    818 				tst_resm(TFAIL, "Test case %d, errno = %d",
    819 					 test + 1, errno);
    820 				fail = 1;
    821 			}
    822 		}
    823 		if ((thiscase->c_type) == SKIP) {
    824 			close(fd);
    825 			tst_resm(TINFO, "skipping test %d", test + 1);
    826 			continue;
    827 		}
    828 
    829 		/* Mask SIG_USR1 before forking child, to avoid race */
    830 		(void)sighold(SIGUSR1);
    831 
    832 		/* flush the stdout to avoid garbled output */
    833 		fflush(stdout);
    834 
    835 		if ((child = FORK_OR_VFORK()) == 0) {
    836 #ifdef UCLINUX
    837 			if (self_exec(argv0, "nddddddddd", 2, thiscase->c_type,
    838 				      thiscase->c_whence, thiscase->c_start,
    839 				      thiscase->c_len, thiscase->c_flag,
    840 				      thiscase->a_type, fd, test, parent) < 0) {
    841 				tst_resm(TFAIL, "self_exec failed");
    842 				cleanup();
    843 			}
    844 #else
    845 			dochild();
    846 #endif
    847 		}
    848 		if (child < 0)
    849 			tst_brkm(TBROK|TERRNO, cleanup, "Fork failed");
    850 
    851 		if ((thiscase->c_flag) == WILLBLOCK) {
    852 			/*
    853 			 * Wait for a signal from the child then remove
    854 			 * blocking lock. Set a 60 second alarm to break the
    855 			 * pause just in case the child never signals us.
    856 			 */
    857 			alarm(TIME_OUT);
    858 			sigpause(SIGUSR1);
    859 
    860 			/* turn off the alarm timer */
    861 			alarm((unsigned)0);
    862 			if (got1 != 1)
    863 				tst_resm(TINFO, "Pause terminated without "
    864 					 "signal SIGUSR1 from child");
    865 			got1 = 0;
    866 
    867 			/*
    868 			 * setup lock structure for parent to delete
    869 			 * blocking lock then wait for child to exit
    870 			 */
    871 			flock.l_type = F_UNLCK;
    872 			flock.l_whence = 0;
    873 			flock.l_start = 0L;
    874 			flock.l_len = 0L;
    875 			if ((fcntl(fd, F_SETLK, &flock)) < 0) {
    876 				tst_resm(TFAIL, "Attempt to release parent "
    877 					 "lock failed");
    878 				tst_resm(TFAIL, "Test case %d, errno = %d",
    879 					 test + 1, errno);
    880 				fail = 1;
    881 			}
    882 		}
    883 		/*
    884 		 * set a 60 second alarm to break the wait just in case the
    885 		 * child doesn't terminate on its own accord
    886 		 */
    887 		alarm(TIME_OUT);
    888 
    889 		/* wait for the child to terminate and close the file */
    890 		waitpid(child, &status, 0);
    891 		/* turn off the alarm clock */
    892 		alarm((unsigned)0);
    893 		if (status != 0) {
    894 			tst_resm(TFAIL, "tchild returned status 0x%x", status);
    895 			fail = 1;
    896 		}
    897 		close(fd);
    898 		if (fail)
    899 			tst_resm(TFAIL, "testcase:%d FAILED", test + 1);
    900 		else
    901 			tst_resm(TPASS, "testcase:%d PASSED", test + 1);
    902 	}
    903 	unlink(tmpname);
    904 }
    905 
    906 void catch_alarm(int sig)
    907 {
    908 	/*
    909 	 * Timer has runout and child has not signaled, need
    910 	 * to kill off the child as it appears it will not
    911 	 * on its own accord. Check that it is still around
    912 	 * as it may have terminated abnormally while parent
    913 	 * was waiting for SIGUSR1 signal from it.
    914 	 */
    915 	if (kill(child, 0) == 0) {
    916 		kill(child, SIGKILL);
    917 		perror("The child didnot terminate on its own accord");
    918 	}
    919 }
    920 
    921 void catch1(int sig)
    922 {
    923 	struct sigaction act;
    924 
    925 	/*
    926 	 * Set flag to let parent know that child is ready to have lock
    927 	 * removed
    928 	 */
    929 	memset(&act, 0, sizeof(act));
    930 	act.sa_handler = catch1;
    931 	sigemptyset(&act.sa_mask);
    932 	sigaddset(&act.sa_mask, SIGUSR1);
    933 	sigaction(SIGUSR1, &act, NULL);
    934 	got1++;
    935 }
    936 
    937 static void testcheck_end(int check_fail, char *msg)
    938 {
    939 	if (check_fail)
    940 		tst_resm(TFAIL, "%s FAILED", msg);
    941 	else
    942 		tst_resm(TPASS, "%s PASSED", msg);
    943 }
    944 
    945 int main(int ac, char **av)
    946 {
    947 	int lc;
    948 
    949 	tst_parse_opts(ac, av, NULL, NULL);
    950 #ifdef UCLINUX
    951 	argv0 = av[0];
    952 
    953 	maybe_run_child(&do_usleep_child, "nd", 1, &parent);
    954 	thiscase = malloc(sizeof(testcase));
    955 
    956 	maybe_run_child(&dochild, "nddddddddd", 2, &thiscase->c_type,
    957 			&thiscase->c_whence, &thiscase->c_start,
    958 			&thiscase->c_len, &thiscase->c_flag, &thiscase->a_type,
    959 			&fd, &test, &parent);
    960 #endif
    961 
    962 	setup();
    963 
    964 	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC)
    965 		NO_NFS = 0;
    966 
    967 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    968 		tst_count = 0;
    969 
    970 /* //block1: */
    971 		tst_resm(TINFO, "Enter block 1: without mandatory locking");
    972 		fail = 0;
    973 		/*
    974 		 * try various file locks on an ordinary file without
    975 		 * mandatory locking
    976 		 */
    977 		(void)run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 0, 0, 36);
    978 		testcheck_end(fail, "Block 1, test 1");
    979 
    980 		/* Now try with negative values for L_start and L_len */
    981 		(void)run_test(O_CREAT | O_RDWR | O_TRUNC, 0777, 5, 36, 45);
    982 		testcheck_end(fail, "Block 1, test 2");
    983 
    984 		tst_resm(TINFO, "Exit block 1");
    985 
    986 /* //block2: */
    987 		/*
    988 		 * Skip block2 if test on NFS, since NFS does not support
    989 		 * mandatory locking
    990 		 */
    991 		tst_resm(TINFO, "Enter block 2: with mandatory locking");
    992 		if (NO_NFS) {
    993 			fail = 0;
    994 			/*
    995 			 * Try various locks on a file with mandatory
    996 			 * record locking this should behave the same
    997 			 * as an ordinary file
    998 			 */
    999 			(void)run_test(O_CREAT | O_RDWR | O_TRUNC,
   1000 				S_ENFMT | S_IRUSR | S_IWUSR, 0, 0, 36);
   1001 			testcheck_end(fail, "Block 2, test 1");
   1002 
   1003 			/* Now try negative values for L_start and L_len */
   1004 			(void)run_test(O_CREAT | O_RDWR | O_TRUNC,
   1005 				S_ENFMT | S_IRUSR | S_IWUSR, 5, 36, 45);
   1006 			testcheck_end(fail, "Block 2, test 2");
   1007 		} else {
   1008 			tst_resm(TCONF, "Skip block 2 as NFS does not"
   1009 				" support mandatory locking");
   1010 		}
   1011 
   1012 		tst_resm(TINFO, "Exit block 2");
   1013 
   1014 /* //block3: */
   1015 		tst_resm(TINFO, "Enter block 3");
   1016 		fail = 0;
   1017 		/*
   1018 		 * Check that proper error status is returned when invalid
   1019 		 * argument used for WHENCE (negative value)
   1020 		 */
   1021 
   1022 		fd = open(tmpname, O_CREAT | O_RDWR | O_TRUNC, 0777);
   1023 		if (fd < 0)
   1024 			tst_brkm(TBROK, cleanup, "open failed");
   1025 
   1026 		if (write(fd, FILEDATA, 10) < 0)
   1027 			tst_brkm(TBROK, cleanup, "write failed");
   1028 
   1029 		flock.l_type = F_WRLCK;
   1030 		flock.l_whence = -1;
   1031 		flock.l_start = 0L;
   1032 		flock.l_len = 0L;
   1033 
   1034 		if ((fcntl(fd, F_SETLK, &flock)) < 0) {
   1035 			if (errno != EINVAL) {
   1036 				tst_resm(TFAIL, "Expected %d got %d",
   1037 					 EINVAL, errno);
   1038 				fail = 1;
   1039 			}
   1040 		} else {
   1041 			tst_resm(TFAIL, "Lock succeeded when it should have "
   1042 				 "failed");
   1043 			fail = 1;
   1044 		}
   1045 
   1046 		close(fd);
   1047 		unlink(tmpname);
   1048 
   1049 		testcheck_end(fail, "Test with negative whence locking");
   1050 		tst_resm(TINFO, "Exit block 3");
   1051 
   1052 /* //block4: */
   1053 		tst_resm(TINFO, "Enter block 4");
   1054 		fail = 0;
   1055 		/*
   1056 		 * Check that a lock on end of file is still valid when
   1057 		 * additional data is appended to end of file and a new
   1058 		 * process attempts to lock new data
   1059 		 */
   1060 		fd = open(tmpname, O_CREAT | O_RDWR | O_TRUNC, 0777);
   1061 		if (fd < 0)
   1062 			tst_brkm(TBROK, cleanup, "open failed");
   1063 
   1064 		if (write(fd, FILEDATA, 10) < 0)
   1065 			tst_brkm(TBROK, cleanup, "write failed");
   1066 
   1067 		thiscase = &testcases[58];
   1068 		flock.l_type = thiscase->a_type;
   1069 		flock.l_whence = thiscase->a_whence;
   1070 		flock.l_start = thiscase->a_start;
   1071 		flock.l_len = thiscase->a_len;
   1072 
   1073 		/* Set the initial parent lock on the file */
   1074 		if ((fcntl(fd, F_SETLK, &flock)) < 0) {
   1075 			tst_resm(TFAIL, "First parent lock failed");
   1076 			tst_resm(TFAIL, "Test case %d, errno = %d", 58, errno);
   1077 			fail = 1;
   1078 		}
   1079 
   1080 		/* Write some additional data to end of file */
   1081 		if (write(fd, FILEDATA, 10) < 0)
   1082 			tst_brkm(TBROK, cleanup, "write failed");
   1083 
   1084 		/* Mask signal to avoid race */
   1085 		if (sighold(SIGUSR1) < 0)
   1086 			tst_brkm(TBROK, cleanup, "sighold failed");
   1087 
   1088 		if ((child = FORK_OR_VFORK()) == 0) {
   1089 #ifdef UCLINUX
   1090 			if (self_exec(argv0, "nddddddddd", 2, thiscase->c_type,
   1091 				      thiscase->c_whence, thiscase->c_start,
   1092 				      thiscase->c_len, thiscase->c_flag,
   1093 				      thiscase->a_type, fd, test, parent) < 0) {
   1094 				tst_resm(TFAIL, "self_exec failed");
   1095 				cleanup();
   1096 			}
   1097 #else
   1098 			dochild();
   1099 #endif
   1100 		}
   1101 		if (child < 0)
   1102 			tst_brkm(TBROK|TERRNO, cleanup, "Fork failed");
   1103 
   1104 		/*
   1105 		 * Wait for a signal from the child then remove blocking lock.
   1106 		 * Set a 60 sec alarm to break the pause just in case the
   1107 		 * child doesn't terminate on its own accord
   1108 		 */
   1109 		(void)alarm(TIME_OUT);
   1110 
   1111 		(void)sigpause(SIGUSR1);
   1112 
   1113 		/* turn off the alarm timer */
   1114 		(void)alarm((unsigned)0);
   1115 		if (got1 != 1) {
   1116 			tst_resm(TINFO, "Pause terminated without signal "
   1117 				 "SIGUSR1 from child");
   1118 		}
   1119 		got1 = 0;
   1120 
   1121 		/*
   1122 		 * Set up lock structure for parent to delete
   1123 		 * blocking lock then wait for child to exit
   1124 		 */
   1125 		flock.l_type = F_UNLCK;
   1126 		flock.l_whence = 0;
   1127 		flock.l_start = 0L;
   1128 		flock.l_len = 0L;
   1129 		if ((fcntl(fd, F_SETLK, &flock)) < 0) {
   1130 			tst_resm(TFAIL, "Attempt to release parent lock "
   1131 				 "failed");
   1132 			tst_resm(TFAIL, "Test case %d, errno = %d", test + 1,
   1133 				 errno);
   1134 			fail = 1;
   1135 		}
   1136 
   1137 		/*
   1138 		 * set a 60 sec alarm to break the wait just in case the
   1139 		 * child doesn't terminate on its own accord
   1140 		 */
   1141 		(void)alarm(TIME_OUT);
   1142 
   1143 		waitpid(child, &status, 0);
   1144 		if (WEXITSTATUS(status) != 0) {
   1145 			fail = 1;
   1146 			tst_resm(TFAIL, "child returned bad exit status");
   1147 		}
   1148 
   1149 		/* turn off the alarm clock */
   1150 		(void)alarm((unsigned)0);
   1151 		if (status != 0) {
   1152 			tst_resm(TFAIL, "child returned status 0x%x", status);
   1153 			fail = 1;
   1154 		}
   1155 		close(fd);
   1156 		unlink(tmpname);
   1157 
   1158 		testcheck_end(fail, "Test of locks on file");
   1159 		tst_resm(TINFO, "Exit block 4");
   1160 	}
   1161 	cleanup();
   1162 	tst_exit();
   1163 }
   1164