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  *	fcntl11.c
     23  *
     24  * DESCRIPTION
     25  *	Testcase to check locking of regions of a file
     26  *
     27  * ALGORITHM
     28  *	Test changing lock sections around a write lock
     29  *
     30  * USAGE
     31  *	fcntl11
     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 #include "safe_macros.h"
     49 
     50 #define STRINGSIZE	27
     51 #define STRING		"abcdefghijklmnopqrstuvwxyz\n"
     52 #define STOP		0xFFF0
     53 
     54 int parent_pipe[2];
     55 int child_pipe[2];
     56 int fd;
     57 pid_t parent_pid, child_pid;
     58 
     59 void parent_put();
     60 void parent_get();
     61 void child_put();
     62 void child_get();
     63 void stop_child();
     64 void compare_lock(struct flock *, short, short, int, int, pid_t);
     65 void unlock_file();
     66 void do_test(struct flock *, short, short, int, int);
     67 void catch_child();
     68 char *str_type();
     69 int do_lock(int, short, short, int, int);
     70 
     71 char *TCID = "fcntl11";
     72 int TST_TOTAL = 1;
     73 
     74 int fail;
     75 
     76 void cleanup(void)
     77 {
     78 	tst_rmdir();
     79 
     80 }
     81 
     82 void setup(void)
     83 {
     84 	char *buf = STRING;
     85 	char template[PATH_MAX];
     86 	struct sigaction act;
     87 
     88 	tst_sig(FORK, DEF_HANDLER, cleanup);
     89 	tst_tmpdir();
     90 
     91 	umask(0);
     92 
     93 	TEST_PAUSE;
     94 
     95 	SAFE_PIPE(cleanup, parent_pipe);
     96 	SAFE_PIPE(cleanup, child_pipe);
     97 	parent_pid = getpid();
     98 	snprintf(template, PATH_MAX, "fcntl11XXXXXX");
     99 
    100 	if ((fd = mkstemp(template)) < 0)
    101 		tst_resm(TFAIL, "Couldn't open temp file! errno = %d", errno);
    102 
    103 	SAFE_WRITE(cleanup, 0, fd, buf, STRINGSIZE);
    104 
    105 	memset(&act, 0, sizeof(act));
    106 	act.sa_handler = catch_child;
    107 	sigemptyset(&act.sa_mask);
    108 	sigaddset(&act.sa_mask, SIGCHLD);
    109 	if ((sigaction(SIGCHLD, &act, NULL)) < 0)
    110 		tst_brkm(TBROK | TERRNO, cleanup,
    111 			 "sigaction(SIGCHLD, ..) failed");
    112 }
    113 
    114 void do_child(void)
    115 {
    116 	struct flock fl;
    117 
    118 	close(parent_pipe[1]);
    119 	close(child_pipe[0]);
    120 	while (1) {
    121 		child_get(&fl);
    122 		if (fcntl(fd, F_GETLK, &fl) < 0)
    123 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    124 		child_put(&fl);
    125 	}
    126 }
    127 
    128 int do_lock(int cmd, short type, short whence, int start, int len)
    129 {
    130 	struct flock fl;
    131 
    132 	fl.l_type = type;
    133 	fl.l_whence = whence;
    134 	fl.l_start = start;
    135 	fl.l_len = len;
    136 	return (fcntl(fd, cmd, &fl));
    137 }
    138 
    139 void do_test(struct flock *fl, short type, short whence, int start, int len)
    140 {
    141 	fl->l_type = type;
    142 	fl->l_whence = whence;
    143 	fl->l_start = start;
    144 	fl->l_len = len;
    145 	fl->l_pid = (short)0;
    146 
    147 	parent_put(fl);
    148 	parent_get(fl);
    149 }
    150 
    151 void
    152 compare_lock(struct flock *fl, short type, short whence, int start, int len,
    153 	     pid_t pid)
    154 {
    155 	if (fl->l_type != type)
    156 		tst_resm(TFAIL, "lock type is wrong should be %s is %s",
    157 			 str_type(type), str_type(fl->l_type));
    158 
    159 	if (fl->l_whence != whence)
    160 		tst_resm(TFAIL, "lock whence is wrong should be %d is %d",
    161 			 whence, fl->l_whence);
    162 
    163 	if (fl->l_start != start)
    164 		tst_resm(TFAIL, "region starts in wrong place, should be "
    165 			 "%d is %" PRId64, start, (int64_t) fl->l_start);
    166 
    167 	if (fl->l_len != len)
    168 		tst_resm(TFAIL,
    169 			 "region length is wrong, should be %d is %" PRId64,
    170 			 len, (int64_t) fl->l_len);
    171 
    172 	if (fl->l_pid != pid)
    173 		tst_resm(TFAIL, "locking pid is wrong, should be %d is %d",
    174 			 pid, fl->l_pid);
    175 }
    176 
    177 void unlock_file(void)
    178 {
    179 	struct flock fl;
    180 
    181 	if (do_lock(F_SETLK, (short)F_UNLCK, (short)0, 0, 0) < 0)
    182 		tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    183 	do_test(&fl, F_WRLCK, 0, 0, 0);
    184 	compare_lock(&fl, (short)F_UNLCK, (short)0, 0, 0, (pid_t) 0);
    185 }
    186 
    187 char *str_type(int type)
    188 {
    189 	static char buf[20];
    190 
    191 	switch (type) {
    192 	case 0:
    193 		return ("F_RDLCK");
    194 	case 1:
    195 		return ("F_WRLCK");
    196 	case 2:
    197 		return ("F_UNLCK");
    198 	default:
    199 		sprintf(buf, "BAD VALUE: %d", type);
    200 		return (buf);
    201 	}
    202 }
    203 
    204 void parent_put(struct flock *l)
    205 {
    206 	SAFE_WRITE(cleanup, 1, parent_pipe[1], l, sizeof(*l));
    207 }
    208 
    209 void parent_get(struct flock *l)
    210 {
    211 	SAFE_READ(cleanup, 1, child_pipe[0], l, sizeof(*l));
    212 }
    213 
    214 void child_put(struct flock *l)
    215 {
    216 	SAFE_WRITE(NULL, 1, child_pipe[1], l, sizeof(*l));
    217 }
    218 
    219 void child_get(struct flock *l)
    220 {
    221 	SAFE_READ(NULL, 1, parent_pipe[0], l, sizeof(*l));
    222 	if (l->l_type == (short)STOP)
    223 		exit(0);
    224 }
    225 
    226 void stop_child(void)
    227 {
    228 	struct flock fl;
    229 
    230 	signal(SIGCHLD, SIG_DFL);
    231 	fl.l_type = STOP;
    232 	parent_put(&fl);
    233 	wait(0);
    234 }
    235 
    236 void catch_child(void)
    237 {
    238 	tst_brkm(TFAIL, cleanup, "Unexpected death of child process");
    239 }
    240 
    241 int main(int ac, char **av)
    242 {
    243 	struct flock tl;
    244 
    245 	int lc;
    246 
    247 	tst_parse_opts(ac, av, NULL, NULL);
    248 #ifdef UCLINUX
    249 	maybe_run_child(&do_child, "ddddd", &parent_pipe[0],
    250 			&parent_pipe[1], &child_pipe[0], &child_pipe[1], &fd);
    251 #endif
    252 
    253 	setup();		/* global setup */
    254 
    255 	/* Check for looping state if -i option is given */
    256 	for (lc = 0; TEST_LOOPING(lc); lc++) {
    257 		/* reset tst_count in case we are looping */
    258 		tst_count = 0;
    259 
    260 		if ((child_pid = FORK_OR_VFORK()) == 0) {	/* parent */
    261 #ifdef UCLINUX
    262 			if (self_exec(av[0], "ddddd", parent_pipe[0],
    263 				      parent_pipe[1], child_pipe[0],
    264 				      child_pipe[1], fd) < 0)
    265 				tst_brkm(TBROK | TERRNO, cleanup,
    266 					 "self_exec failed");
    267 #else
    268 			do_child();
    269 #endif
    270 		} else if (child_pid == -1)
    271 			tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
    272 
    273 		SAFE_CLOSE(cleanup, parent_pipe[0]);
    274 		SAFE_CLOSE(cleanup, child_pipe[1]);
    275 
    276 /* //block1: */
    277 		tst_resm(TINFO, "Enter block 1");
    278 
    279 		/*
    280 		 * Add a write lock to the middle of the file and a read
    281 		 * at the begining
    282 		 */
    283 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    284 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    285 
    286 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 1, 5) < 0)
    287 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    288 
    289 		/*
    290 		 * Test read lock
    291 		 */
    292 		do_test(&tl, F_WRLCK, 0, 0, 0);
    293 		compare_lock(&tl, (short)F_RDLCK, (short)0, 1, 5, parent_pid);
    294 
    295 		/*
    296 		 * Test write lock
    297 		 */
    298 		do_test(&tl, F_WRLCK, 0, 6, 0);
    299 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 5, parent_pid);
    300 
    301 		/*
    302 		 * Test that the rest of the file is unlocked
    303 		 */
    304 		do_test(&tl, F_WRLCK, 0, 15, 0);
    305 		compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
    306 
    307 		/*
    308 		 * remove all the locks set above
    309 		 */
    310 		unlock_file();
    311 
    312 		tst_resm(TINFO, "Exit block 1");
    313 
    314 /* //block2: */
    315 		tst_resm(TINFO, "Enter block 2");
    316 
    317 		/*
    318 		 * Set a write lock at the middle of the file and a
    319 		 * read lock just before
    320 		 */
    321 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    322 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    323 
    324 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 5, 5) < 0)
    325 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    326 
    327 		/*
    328 		 * Test the read lock
    329 		 */
    330 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    331 		compare_lock(&tl, (short)F_RDLCK, (short)0, 5, 5, parent_pid);
    332 
    333 		/*
    334 		 * Test the write lock.
    335 		 */
    336 		do_test(&tl, (short)F_WRLCK, (short)0, 10, 0);
    337 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 5, parent_pid);
    338 
    339 		/*
    340 		 * Test to make sure the rest of the file is unlocked.
    341 		 */
    342 		do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
    343 		compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
    344 
    345 		/*
    346 		 * remove all the locks set above
    347 		 */
    348 		unlock_file();
    349 
    350 		tst_resm(TINFO, "Exit block 2");
    351 
    352 /* //block3: */
    353 		tst_resm(TINFO, "Enter block 3");
    354 
    355 		/*
    356 		 * Set a write lock in the middle and a read lock that
    357 		 * ends at the first byte of the write lock
    358 		 */
    359 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    360 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    361 
    362 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 5, 6) < 0)
    363 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    364 
    365 		/*
    366 		 * Test read lock
    367 		 */
    368 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    369 		compare_lock(&tl, (short)F_RDLCK, (short)0, 5, 6, parent_pid);
    370 
    371 		/*
    372 		 * Test write lock
    373 		 */
    374 		do_test(&tl, (short)F_WRLCK, (short)0, 11, 0);
    375 		compare_lock(&tl, (short)F_WRLCK, (short)0, 11, 4, parent_pid);
    376 
    377 		/*
    378 		 * Test to make sure the rest of the file is unlocked.
    379 		 */
    380 		do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
    381 		compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
    382 
    383 		/*
    384 		 * remove all the locks set above
    385 		 */
    386 		unlock_file();
    387 
    388 		tst_resm(TINFO, "Exit block 3");
    389 
    390 /* //block4: */
    391 		tst_resm(TINFO, "Enter block 4");
    392 
    393 		/*
    394 		 * Set a write lock on the middle of the file and a read
    395 		 * lock that overlaps the front of the write.
    396 		 */
    397 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    398 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    399 
    400 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 5, 8) < 0)
    401 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    402 
    403 		/*
    404 		 * Test the read lock
    405 		 */
    406 		do_test(&tl, (short)F_WRLCK, (short)0, 5, 0);
    407 		compare_lock(&tl, (short)F_RDLCK, (short)0, 5, 8, parent_pid);
    408 
    409 		/*
    410 		 * Test the write lock
    411 		 */
    412 		do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
    413 		compare_lock(&tl, (short)F_WRLCK, (short)0, 13, 2, parent_pid);
    414 
    415 		/*
    416 		 * Test to make sure the rest of the file is unlocked.
    417 		 */
    418 		do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
    419 		compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 0, 0);
    420 
    421 		/*
    422 		 * remove all the locks set above
    423 		 */
    424 		unlock_file();
    425 
    426 		tst_resm(TINFO, "Exit block 4");
    427 
    428 /* //block5: */
    429 		tst_resm(TINFO, "Enter block 5");
    430 
    431 		/*
    432 		 * Set a write lock in the middle of a file and a read
    433 		 * lock in the middle of it
    434 		 */
    435 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 10) < 0)
    436 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    437 
    438 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 13, 5) < 0)
    439 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    440 
    441 		/*
    442 		 * Test the first write lock
    443 		 */
    444 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    445 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 3, parent_pid);
    446 
    447 		/*
    448 		 * Test the read lock
    449 		 */
    450 		do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
    451 		compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 5, parent_pid);
    452 
    453 		/*
    454 		 * Test the second write lock
    455 		 */
    456 		do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
    457 		compare_lock(&tl, (short)F_WRLCK, (short)0, 18, 2, parent_pid);
    458 
    459 		/*
    460 		 * Test to make sure the rest of the file is unlocked
    461 		 */
    462 		do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
    463 		compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
    464 
    465 		/*
    466 		 * remove all the locks set above.
    467 		 */
    468 		unlock_file();
    469 		tst_resm(TINFO, "Exit block 5");
    470 
    471 /* //block6: */
    472 		tst_resm(TINFO, "Enter block 6");
    473 		/*
    474 		 * Set a write lock in the middle of the file and a read
    475 		 * lock that overlaps the end
    476 		 */
    477 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    478 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    479 
    480 		/*
    481 		 * Set a read lock on the whole file
    482 		 */
    483 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 13, 5) < 0)
    484 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    485 
    486 		/*
    487 		 * Test the write lock
    488 		 */
    489 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    490 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 3, parent_pid);
    491 
    492 		/*
    493 		 * Test the read lock
    494 		 */
    495 		do_test(&tl, (short)F_WRLCK, (short)0, 13, 0);
    496 		compare_lock(&tl, (short)F_RDLCK, (short)0, 13, 5, parent_pid);
    497 
    498 		/*
    499 		 * Test to make sure the rest of the file is unlocked
    500 		 */
    501 		do_test(&tl, (short)F_WRLCK, (short)0, 18, 0);
    502 		compare_lock(&tl, (short)F_UNLCK, (short)0, 18, 0, 0);
    503 
    504 		/*
    505 		 * remove all the locks set above
    506 		 */
    507 		unlock_file();
    508 
    509 		tst_resm(TINFO, "Exit block 6");
    510 
    511 /* //block7: */
    512 		tst_resm(TINFO, "Enter block 7");
    513 
    514 		/*
    515 		 * Set a write lock in the middle of the file and a read
    516 		 * lock starting at the last byte of the write lock
    517 		 */
    518 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    519 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    520 
    521 		/*
    522 		 * Set a read lock on the whole file.
    523 		 */
    524 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 14, 5) < 0)
    525 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    526 
    527 		/*
    528 		 * Test write lock
    529 		 */
    530 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    531 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 4, parent_pid);
    532 
    533 		/*
    534 		 * Test the read lock
    535 		 */
    536 		do_test(&tl, (short)F_WRLCK, (short)0, 14, 0);
    537 		compare_lock(&tl, (short)F_RDLCK, (short)0, 14, 5, parent_pid);
    538 
    539 		/*
    540 		 * Test to make sure the end of the file is unlocked
    541 		 */
    542 		do_test(&tl, (short)F_WRLCK, (short)0, 19, 0);
    543 		compare_lock(&tl, (short)F_UNLCK, (short)0, 19, 0, 0);
    544 
    545 		/*
    546 		 * remove all the locks set above
    547 		 */
    548 		unlock_file();
    549 
    550 		tst_resm(TINFO, "Exit block 7");
    551 
    552 /* //block8: */
    553 		tst_resm(TINFO, "Enter block 8");
    554 
    555 		/*
    556 		 * Set a write lock in the middle of the file and a read
    557 		 * lock that starts just after the last byte of the
    558 		 * write lock.
    559 		 */
    560 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    561 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    562 
    563 		/*
    564 		 * Set a read lock on the whole file
    565 		 */
    566 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 15, 5) < 0)
    567 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    568 
    569 		/*
    570 		 * Test the write lock
    571 		 */
    572 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    573 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 5, parent_pid);
    574 
    575 		/*
    576 		 * Test the read lock
    577 		 */
    578 		do_test(&tl, (short)F_WRLCK, (short)0, 15, 0);
    579 		compare_lock(&tl, (short)F_RDLCK, (short)0, 15, 5, parent_pid);
    580 
    581 		/*
    582 		 * Test to make sure the rest of the file is unlocked
    583 		 */
    584 		do_test(&tl, (short)F_WRLCK, (short)0, 20, 0);
    585 		compare_lock(&tl, (short)F_UNLCK, (short)0, 20, 0, 0);
    586 
    587 		/*
    588 		 * remove all the locks set above
    589 		 */
    590 		unlock_file();
    591 
    592 		tst_resm(TINFO, "Exit block 8");
    593 
    594 /* //block9: */
    595 		tst_resm(TINFO, "Enter block 9");
    596 
    597 		/*
    598 		 * Set a write lock at the middle of the file and a read
    599 		 * lock that starts past the end of the write lock.
    600 		 */
    601 		if (do_lock(F_SETLK, (short)F_WRLCK, (short)0, 10, 5) < 0)
    602 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    603 
    604 		if (do_lock(F_SETLK, (short)F_RDLCK, (short)0, 16, 5) < 0)
    605 			tst_resm(TFAIL | TERRNO, "fcntl on file failed");
    606 
    607 		/*
    608 		 * Test the write lock
    609 		 */
    610 		do_test(&tl, (short)F_WRLCK, (short)0, 0, 0);
    611 		compare_lock(&tl, (short)F_WRLCK, (short)0, 10, 5, parent_pid);
    612 
    613 		/*
    614 		 * Test that byte in between is unlocked
    615 		 */
    616 		do_test(&tl, (short)F_WRLCK, (short)0, 15, 1);
    617 		compare_lock(&tl, (short)F_UNLCK, (short)0, 15, 1, 0);
    618 
    619 		/*
    620 		 * Test the read lock
    621 		 */
    622 		do_test(&tl, (short)F_WRLCK, (short)0, 16, 0);
    623 		compare_lock(&tl, (short)F_RDLCK, (short)0, 16, 5, parent_pid);
    624 
    625 		/*
    626 		 * Test to make sure the rest of the file is unlocked
    627 		 */
    628 		do_test(&tl, (short)F_WRLCK, (short)0, 21, 0);
    629 		compare_lock(&tl, (short)F_UNLCK, (short)0, 21, 0, 0);
    630 
    631 		/*
    632 		 * remove all the locks set above
    633 		 */
    634 		unlock_file();
    635 
    636 		tst_resm(TINFO, "Exit block 9");
    637 
    638 		stop_child();
    639 		SAFE_CLOSE(cleanup, fd);
    640 	}
    641 	cleanup();
    642 	tst_exit();
    643 }
    644