Home | History | Annotate | Download | only in inode
      1 /*
      2  *
      3  *   Copyright (c) International Business Machines  Corp., 2002
      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 /* 11/01/2002	Port to LTP	robbiew (at) us.ibm.com */
     21 /* 06/30/2001	Port to Linux	nsharoff (at) us.ibm.com */
     22 
     23 			   /*inode02.c */
     24 /*======================================================================
     25 	=================== TESTPLAN SEGMENT ===================
     26 CALLS:	mkdir, stat, open
     27 
     28 	Run with TERM mode.
     29 
     30 >KEYS:  < file system and I/O management, system resource constraints.
     31 >WHAT:  < Can the system handle a heavy load on the file system I/O
     32 	< functions?
     33 >HOW:   < Create several identical process that call inode02.c.  This
     34 	< will simulate the multi-user environment, and hopefully uncover
     35 	< conflicts that might occur in "real life" use.
     36 >BUGS:  <
     37 ======================================================================*/
     38 
     39 #define PATH_STRING_LENGTH  1024
     40 #define NAME_LENGTH  8
     41 #define MAX_PATH_STRING_LENGTH  (PATH_STRING_LENGTH - NAME_LENGTH - 40)
     42 #define DIRECTORY_MODE  00777
     43 #define FILE_MODE       00777
     44 
     45 #define MKDIR_STRING_LENGTH  (MAX_PATH_STRING_LENGTH + 7)
     46 
     47 /* #define DEBUG	 you can watch the generation with this flag */
     48 
     49 #define TRUE  1
     50 #define FALSE 0
     51 #define READ  0
     52 #define WRITE 1
     53 
     54 #include <stdio.h>
     55 #include <errno.h>
     56 #include <sys/types.h>
     57 #include <sys/stat.h>
     58 #include <signal.h>
     59 #include <fcntl.h>
     60 #include <errno.h>
     61 #include <sys/wait.h>
     62 
     63 #ifdef LINUX
     64 #include <stdlib.h>
     65 #include <unistd.h>
     66 #include <string.h>
     67 #endif
     68 
     69 #define MAXCHILD	25
     70 int allchild[MAXCHILD + 1];
     71 
     72 char name[NAME_LENGTH + 1];
     73 char path_string[PATH_STRING_LENGTH + 1];
     74 char read_string[PATH_STRING_LENGTH + 1];
     75 char write_string[PATH_STRING_LENGTH + 1];
     76 char remove_string[PATH_STRING_LENGTH + 10];
     77 int parent_pid;
     78 int nchild;
     79 
     80 FILE *list_stream = NULL;
     81 int list_id;
     82 int file_id;
     83 
     84 int increment_name(), get_next_name(), mode(), escrivez(), massmurder();
     85 int max_depth, max_breadth, file_length;
     86 int bd_arg(char *);
     87 
     88 #ifdef LINUX
     89 void (*sigset(int, void (*)(int))) (int);
     90 #endif
     91 
     92 /** LTP Port **/
     93 #include "test.h"
     94 
     95 void setup(void);
     96 void fail_exit(void);
     97 void anyfail(void);
     98 void ok_exit(void);
     99 void forkfail(void);
    100 void terror(char *);
    101 int instress(void);
    102 
    103 #define FAILED 0
    104 #define PASSED 1
    105 
    106 int local_flag = PASSED;
    107 FILE *temp;
    108 
    109 char *TCID = "inode02";		/* Test program identifier.    */
    110 int TST_TOTAL = 1;		/* Total number of test cases. */
    111 /**************/
    112 
    113 int main(int argc, char *argv[])
    114 {
    115 	int pid, tree(), p, status;
    116 	int count, child;
    117 	register int i;
    118 	int term();
    119 
    120 	setup();
    121 
    122 	parent_pid = getpid();
    123 
    124 	if (sigset(SIGTERM, (void (*)())term) == SIG_ERR) {
    125 		tst_resm(TBROK, "\tSIGTERM sigset set failed, errno=%d\n",
    126 			 errno);
    127 		exit(1);
    128 	}
    129 
    130 	/************************************************/
    131 	/*                                              */
    132 	/*  Input the parameters for the directory---   */
    133 	/*  file trees which are to be generated        */
    134 	/*                                              */
    135 	/************************************************/
    136 
    137 	if (argc < 2) {
    138 		max_depth = 6;
    139 		max_breadth = 5;
    140 		file_length = 8;
    141 		nchild = 5;
    142 	} else if (argc < 5) {
    143 		tst_resm(TCONF, "Bad argument count.\n");
    144 		printf
    145 		    ("\tinode02 max_depth max_breadth file_length #children\n\tdefault: inode02 6 5 8 5\n");
    146 		exit(1);
    147 	} else {
    148 		i = 1;
    149 		if (sscanf(argv[i++], "%d", &max_depth) != 1)
    150 			bd_arg(argv[i - 1]);
    151 		if (sscanf(argv[i++], "%d", &max_breadth) != 1)
    152 			bd_arg(argv[i - 1]);
    153 		if (sscanf(argv[i++], "%d", &file_length) != 1)
    154 			bd_arg(argv[i - 1]);
    155 		if (sscanf(argv[i++], "%d", &nchild) != 1)
    156 			bd_arg(argv[i - 1]);
    157 		if (nchild > MAXCHILD) {
    158 			fprintf(temp, "too many children - max is %d\n",
    159 				MAXCHILD);
    160 			exit(1);
    161 		}
    162 	}
    163 
    164 	/************************************************/
    165 	/*                                              */
    166 	/*  Generate and check nchild trees             */
    167 	/*                                              */
    168 	/************************************************/
    169 
    170 	for (p = 0; p < nchild; p++) {
    171 		pid = fork();
    172 		if (pid == 0) {
    173 			tree();
    174 		} else {
    175 			if (pid < 1) {
    176 				terror
    177 				    ("Fork failed (may be OK if under stress)");
    178 				massmurder();
    179 				if (instress()) {
    180 					ok_exit();
    181 				}
    182 				forkfail();
    183 			}
    184 		}
    185 	}
    186 
    187 	count = 0;
    188 	while ((child = wait(&status)) > 0) {
    189 #ifdef DEBUG
    190 		tst_resm(TINFO, "Test %d exited status = %d\n", child, status);
    191 #endif
    192 		if (status) {
    193 			fprintf(temp, "Test %d failed - expected 0 exit.\n",
    194 				child);
    195 			local_flag = FAILED;
    196 		}
    197 		count++;
    198 	}
    199 
    200 	if (count != nchild) {
    201 		tst_resm(TFAIL, "Wrong number of children waited on!\n");
    202 		tst_resm(TFAIL, "Saw %d, expected %d\n", count, nchild);
    203 		local_flag = FAILED;
    204 	}
    205 
    206 	/************************************************/
    207 	/*                                              */
    208 	/*  And report the results..........            */
    209 	/*                                              */
    210 	/************************************************/
    211 
    212 	anyfail();
    213 	/** NOT REACHED **/
    214 	tst_exit();
    215 }
    216 
    217 int bd_arg(char *str)
    218 {
    219 	fprintf(temp,
    220 		"Bad argument - %s - could not parse as number.\n\tinode02 [max_depth] [max_breadth] [file_length] [#children]\n\tdefault: inode02 6 5 8 5\n",
    221 		str);
    222 	exit(1);
    223 }
    224 
    225 int tree(void)
    226 
    227 /************************************************/
    228 /*						*/
    229 /*  		      TREE			*/
    230 /*						*/
    231 /*   generate a tree of directories and files   */
    232 /*   and save the path names in the path_list	*/
    233 /*   file 					*/
    234 /*						*/
    235 /*   then, read the path names and attempt to   */
    236 /*   access the corresponding directories and	*/
    237 /*   files					*/
    238 /*						*/
    239 /************************************************/
    240 {
    241 	int gen_ret_val, ch_ret_val, exit_val, level;
    242 	int ret_val;
    243 	int generate(), check();
    244 	char path_list_string[PATH_STRING_LENGTH + 10];
    245 	int len;
    246 	int status;
    247 	int snp_ret;
    248 
    249 	/********************************/
    250 	/*                              */
    251 	/*  make the root directory for */
    252 	/*  the tree                    */
    253 	/*                              */
    254 	/********************************/
    255 
    256 	sprintf(path_string, "inode02.%d", getpid());
    257 
    258 	ret_val = mkdir(path_string, DIRECTORY_MODE);
    259 
    260 	if (ret_val == -1) {
    261 		tst_resm(TBROK,
    262 			 "Reason: Impossible to create directory %s, errno=%d\n",
    263 			 path_string, errno);
    264 		exit(-5);
    265 	}
    266 
    267 	strcpy(remove_string, "rm -rf ");
    268 	strcat(remove_string, path_string);
    269 
    270 #ifdef DEBUG
    271 	tst_resm(TINFO, "\n%s\n", path_string);
    272 #endif
    273 
    274 	/****************************************/
    275 	/*                                      */
    276 	/*  create the "path_list" file, in     */
    277 	/*  which the list of generated paths   */
    278 	/*  will be stored so that they later   */
    279 	/*  may be checked                      */
    280 	/*                                      */
    281 	/****************************************/
    282 
    283 	snp_ret = snprintf(path_list_string, sizeof(path_list_string),
    284 		"%s/path_list",	path_string);
    285 	if (snp_ret < 0 || snp_ret >= sizeof(path_list_string)) {
    286 		tst_resm(TBROK, "snprintf(path_list_string,..) returned %d",
    287 			snp_ret);
    288 		exit(-1);
    289 	}
    290 	list_id = creat(path_list_string, FILE_MODE);
    291 	if (list_id == -1) {
    292 		fprintf(temp,
    293 			"\nThe path_list file '%s' cannot be created, errno=%d\n",
    294 			path_list_string, errno);
    295 		exit(-7);
    296 	}
    297 
    298 	/****************************************/
    299 	/*                                      */
    300 	/*   and store its name in path_list    */
    301 	/*                                      */
    302 	/****************************************/
    303 
    304 	strcpy(write_string, path_string);
    305 	len = strlen(write_string);
    306 	write_string[len++] = 'D';
    307 	write_string[len] = '\0';
    308 	escrivez(write_string);
    309 
    310 	/****************************************/
    311 	/*                                      */
    312 	/*   generate the directory-file tree   */
    313 	/*                                      */
    314 	/****************************************/
    315 
    316 	level = 0;
    317 
    318 #ifdef DEBUG
    319 	tst_resm(TINFO, "\n\t%s\n\n", "GENERATING:");
    320 #endif
    321 
    322 	gen_ret_val = generate(path_string, level);
    323 	close(list_id);
    324 	list_id = open(path_list_string, READ);
    325 	if (list_id == -1) {
    326 		fprintf(temp,
    327 			"\nThe path_list file cannot be opened for reading, errno=%d\n",
    328 			errno);
    329 		exit(-8);
    330 	}
    331 	list_stream = fdopen(list_id, "r");
    332 
    333 	/****************************************/
    334 	/*                                      */
    335 	/*   check the directory-file tree      */
    336 	/*      for correctness                 */
    337 	/*                                      */
    338 	/****************************************/
    339 
    340 #ifdef DEBUG
    341 	tst_resm(TINFO, "\n\t%s\n\n", "CHECKING:");
    342 #endif
    343 
    344 	ch_ret_val = check();
    345 
    346 	exit_val = MIN(ch_ret_val, gen_ret_val);
    347 
    348 	status = fclose(list_stream);
    349 	if (status != 0) {
    350 		fprintf(temp,
    351 			"Failed to close list_stream: ret=%d errno=%d (%s)\n",
    352 			status, errno, strerror(errno));
    353 		exit(-8);
    354 	}
    355 
    356 	/*
    357 	 * Remove file.
    358 	 */
    359 
    360 	status = system(remove_string);
    361 	if (status) {
    362 		fprintf(temp, "Caution - `%s' failed.\n", remove_string);
    363 		fprintf(temp, "Status returned %d.\n", status);
    364 	}
    365 
    366 	/****************************************/
    367 	/*                                      */
    368 	/*         .....and exit main           */
    369 	/*                                      */
    370 	/****************************************/
    371 
    372 	exit(exit_val);
    373 }
    374 
    375 int generate(char *string, int level)
    376 
    377 /****************************************/
    378 /*					*/
    379 /*   generate recursively a tree of	*/
    380 /*   directories and files:  within   	*/
    381 /*   created directory, an alternating	*/
    382 /*   series of files and directories 	*/
    383 /*   are constructed---until tree	*/
    384 /*   breadth and depth limits are	*/
    385 /*   reached or an error occurs		*/
    386 /*					*/
    387 /****************************************/
    388 /***************************/
    389 /*  string:                */
    390 /*  the directory path     */
    391 /*  string below which a   */
    392 /*  tree is generated      */
    393 /*                         */
    394 /***************************/
    395 
    396 /***************************/
    397 /* level:                  */
    398 /* the tree depth variable */
    399 /*                         */
    400 /***************************/
    401 {
    402 	int switch_flag;
    403 	int ret_val = 0;
    404 	int new_ret_val, len, ret_len;
    405 	char new_string[PATH_STRING_LENGTH + 1];
    406 	int new_level;
    407 	int i, j;		/* iteration counters */
    408 	int snp_ret;
    409 
    410 	switch_flag = level & TRUE;
    411 	if (strlen(string) >= MAX_PATH_STRING_LENGTH) {
    412 
    413 		/********************************/
    414 		/*                              */
    415 		/*   Maximum path name length   */
    416 		/*          reached             */
    417 		/*                              */
    418 		/********************************/
    419 
    420 		fprintf(temp, "\nMaximum path_name length reached\n");
    421 		return (-1);
    422 	} else if (level < max_depth) {
    423 		for (i = 0; i <= max_breadth; i++) {
    424 			get_next_name();
    425 			snp_ret = snprintf(new_string, sizeof(new_string),
    426 				"%s/%s", string, name);
    427 			if (snp_ret < 0 || snp_ret >= sizeof(new_string)) {
    428 				tst_resm(TBROK, "snprintf(new_string,..) "
    429 					"returned %d", snp_ret);
    430 				exit(-1);
    431 			}
    432 
    433 			/****************************************/
    434 			/*                                      */
    435 			/*    switch between creating files     */
    436 			/*    and making directories            */
    437 			/*                                      */
    438 			/****************************************/
    439 
    440 			if (switch_flag) {
    441 				switch_flag = FALSE;
    442 
    443 				/****************************************/
    444 				/*                                      */
    445 				/*        create a new file             */
    446 				/*                                      */
    447 				/****************************************/
    448 
    449 				file_id = creat(new_string, FILE_MODE);
    450 				if (file_id == -1) {
    451 					fprintf(temp,
    452 						"\nImpossible to create file %s, errno=%d\n",
    453 						new_string, errno);
    454 					return (-2);
    455 				}
    456 #ifdef DEBUG
    457 				tst_resm(TINFO, "%d  %s F\n", level,
    458 					 new_string);
    459 #endif
    460 
    461 				/****************************************/
    462 				/*                                      */
    463 				/*            write to it               */
    464 				/*                                      */
    465 				/****************************************/
    466 
    467 				len = strlen(new_string);
    468 				for (j = 1; j <= file_length; j++) {
    469 					ret_len =
    470 					    write(file_id, new_string, len);
    471 					if (ret_len != len) {
    472 						fprintf(temp,
    473 							"\nUnsuccessful write to file %s, errno=%d\n",
    474 							new_string, errno);
    475 						return (-3);
    476 					}
    477 				}
    478 				close(file_id);
    479 
    480 				/****************************************/
    481 				/*                                      */
    482 				/*   and store its name in path_list    */
    483 				/*                                      */
    484 				/****************************************/
    485 
    486 				strcpy(write_string, new_string);
    487 				len = strlen(write_string);
    488 				write_string[len++] = 'F';
    489 				write_string[len] = '\0';
    490 				escrivez(write_string);
    491 			} else {
    492 				switch_flag = TRUE;
    493 
    494 				/****************************************/
    495 				/*                                      */
    496 				/*       or make a directory            */
    497 				/*                                      */
    498 				/*  (mknod can only be called when in   */
    499 				/*   super user mode)                   */
    500 				/*                                      */
    501 				/****************************************/
    502 
    503 				ret_val = mkdir(new_string, DIRECTORY_MODE);
    504 
    505 				if (ret_val != 0) {
    506 					fprintf(temp,
    507 						"\nImpossible to create directory %s, errno=%d\n",
    508 						new_string, errno);
    509 					return (-5);
    510 				}
    511 #ifdef DEBUG
    512 				tst_resm(TINFO, "%d  %s D\n", level,
    513 					 new_string);
    514 #endif
    515 
    516 				/****************************************/
    517 				/*                                      */
    518 				/*     store its name in path_list      */
    519 				/*                                      */
    520 				/****************************************/
    521 
    522 				strcpy(write_string, new_string);
    523 				len = strlen(write_string);
    524 				write_string[len++] = 'D';
    525 				write_string[len] = '\0';
    526 				escrivez(write_string);
    527 
    528 				/****************************************/
    529 				/*                                      */
    530 				/*      and generate a new level        */
    531 				/*                                      */
    532 				/****************************************/
    533 
    534 				new_level = level + 1;
    535 				new_ret_val = generate(new_string, new_level);
    536 				if (new_ret_val < ret_val)
    537 					ret_val = new_ret_val;
    538 			}
    539 		}
    540 
    541 		/********************************/
    542 		/*                              */
    543 		/*    Maximum breadth reached   */
    544 		/*                              */
    545 		/********************************/
    546 
    547 		return (ret_val);
    548 	} else
    549 		    /********************************/
    550 		/*                             */
    551 		/*    Maximum depth reached    */
    552 		/*                             */
    553  /********************************/
    554 		return 0;
    555 }
    556 
    557 int check(void)
    558 
    559 /****************************************/
    560 /*					*/
    561 /*   check for file and directory	*/
    562 /*   correctness by reading records	*/
    563 /*   from the path_list and attempting	*/
    564 /*   to determine if the corresponding	*/
    565 /*   files or directories are as 	*/
    566 /*   created 				*/
    567 /*					*/
    568 /****************************************/
    569 {
    570 	int len, path_mode, val, ret_len, j;
    571 
    572 	for (;;) {
    573 
    574 		/****************************************/
    575 		/*                                      */
    576 		/*  read a path string from path_list   */
    577 		/*                                      */
    578 		/****************************************/
    579 
    580 		if (fscanf(list_stream, "%s", path_string) == EOF) {
    581 
    582 #ifdef DEBUG
    583 			tst_resm(TINFO, "\nEnd of path_list file reached \n");
    584 #endif
    585 
    586 			return 0;
    587 		}
    588 #ifdef DEBUG
    589 		tst_resm(TINFO, "%s\n", path_string);
    590 #endif
    591 
    592 		len = strlen(path_string);
    593 		len--;
    594 		if (path_string[len] == 'F') {
    595 
    596 		/********************************/
    597 			/*                              */
    598 			/*    this should be a file     */
    599 			/*                              */
    600 		/********************************/
    601 
    602 			path_string[len] = '\0';
    603 			file_id = open(path_string, READ);
    604 			if (file_id <= 0) {
    605 				fprintf(temp,
    606 					"\nImpossible to open file %s, errno=%d\n",
    607 					path_string, errno);
    608 				return (-1);
    609 			}
    610 
    611 			else {
    612 				/********************************/
    613 				/*                              */
    614 				/*    check its contents        */
    615 				/*                              */
    616 				/********************************/
    617 
    618 				ret_len = 0;
    619 				len = strlen(path_string);
    620 				for (j = 1; j <= file_length; j++) {
    621 					ret_len =
    622 					    read(file_id, read_string, len);
    623 					if (len != ret_len) {
    624 						fprintf(temp,
    625 							"\nFile read error for file %s, errno=%d\n",
    626 							path_string, errno);
    627 						return (-3);
    628 					}
    629 					read_string[len] = '\0';
    630 					val = strcmp(read_string, path_string);
    631 					if (val != 0) {
    632 						fprintf(temp,
    633 							"\nContents of file %s are different than expected: %s\n",
    634 							path_string,
    635 							read_string);
    636 						return (-4);
    637 					}
    638 				}
    639 				close(file_id);
    640 			}	/* else for */
    641 			if (ret_len <= 0) {
    642 				fprintf(temp,
    643 					"\nImpossible to read file %s, errno=%d\n",
    644 					path_string, errno);
    645 				return (-2);
    646 			}
    647 		} else {
    648 
    649 		/********************************/
    650 			/*                              */
    651 			/*  otherwise..........         */
    652 			/*  it should be a directory    */
    653 			/*                              */
    654 		/********************************/
    655 
    656 			path_string[len] = '\0';
    657 			path_mode = mode(path_string);
    658 			if (path_mode == -1) {
    659 				fprintf(temp,
    660 					"\nPreviously created directory path %s was not open\n",
    661 					path_string);
    662 				return (-4);
    663 			}
    664 			if ((040000 & path_mode) != 040000) {
    665 				fprintf(temp,
    666 					"\nPath %s was not recognized to be a directory\n",
    667 					path_string);
    668 				fprintf(temp, "Its mode is %o\n", path_mode);
    669 				return (-5);
    670 			}
    671 		}
    672 	}			/* while */
    673 }
    674 
    675 int get_next_name(void)
    676 
    677 /****************************************/
    678 /*					*/
    679 /*   get the next---in a dictionary	*/
    680 /*   sense---file or directory name	*/
    681 /*					*/
    682 /****************************************/
    683 {
    684 	static int k;
    685 	int i;
    686 	int last_position;
    687 
    688 	last_position = NAME_LENGTH - 1;
    689 	if (k == 0) {
    690 
    691 		/************************/
    692 		/*                      */
    693 		/*   initialize name    */
    694 		/*                      */
    695 		/************************/
    696 
    697 		for (i = 0; i < NAME_LENGTH; i++)
    698 			name[i] = 'a';
    699 		name[NAME_LENGTH] = '\0';
    700 		k++;
    701 	}
    702 					    /********************************/
    703 	/*                              */
    704 	else
    705 		increment_name(last_position);	/* i.e., beginning at the last  */
    706 	/* position                     */
    707 	/*                              */
    708 					    /********************************/
    709 	return 0;
    710 }
    711 
    712 int increment_name(int position)
    713 
    714 /****************************************/
    715 /*					*/
    716 /*  recursively revise the letters in 	*/
    717 /*  a name to get the lexiographically	*/
    718 /*  next name				*/
    719 /*					*/
    720 /****************************************/
    721 {
    722 	int next_position;
    723 
    724 	if (name[position] == 'z')
    725 		if (position == 0) {
    726 			fprintf(temp,
    727 				"ERROR: There are no more available names\n");
    728 			exit(-1);
    729 		} else {
    730 			name[position] = 'a';	       /**********************/
    731 			next_position = --position;	/*                    */
    732 			increment_name(next_position);	/*  increment the     */
    733 			/*  previous letter   */
    734 			/*                    */
    735 						       /**********************/
    736 		}
    737 				  /*********************************/
    738 	/*                               */
    739 	else
    740 		name[position]++;	/* otherwise, increment this one */
    741 	return 0;		/*                               */
    742 				  /*********************************/
    743 }
    744 
    745 int mode(char *path_string)
    746 
    747 /****************************************/
    748 /*					*/
    749 /*   determine and return the mode of	*/
    750 /*   the file named by path_string 	*/
    751 /*					*/
    752 /****************************************/
    753 {
    754 	struct stat buf;
    755 	int ret_val, mod;
    756 
    757 	ret_val = stat(path_string, &buf);
    758 	if (ret_val == -1)
    759 		return (-1);
    760 	else {
    761 		mod = buf.st_mode;
    762 		return (mod);
    763 	}
    764 }
    765 
    766 int escrivez(char *string)
    767 {
    768 	char write_string[PATH_STRING_LENGTH + 1];
    769 	int len, ret_len;
    770 
    771 	strcpy(write_string, string);
    772 	len = strlen(write_string);
    773 	write_string[len] = '\n';
    774 	len++;
    775 	ret_len = write(list_id, write_string, len);
    776 	if (len != ret_len) {
    777 		fprintf(temp,
    778 			"A string of deviant length %d written to path_list, errno=%d\n",
    779 			ret_len, errno);
    780 		exit(-2);
    781 	}
    782 	return 0;
    783 }
    784 
    785 int term(void)
    786 {
    787 	int status;
    788 
    789 	fflush(temp);
    790 	if (parent_pid == getpid()) {
    791 		massmurder();	/* kill kids */
    792 		fprintf(temp, "\term1 - SIGTERM received by parent.\n");
    793 		fflush(temp);
    794 	} else {
    795 		fprintf(temp, "\tchild - got SIGTERM signal.\n");
    796 		if (list_stream != NULL)
    797 			fclose(list_stream);
    798 		close(list_id);
    799 		close(file_id);
    800 		status = system(remove_string);
    801 		if (status) {
    802 			fprintf(temp, "Caution - ``%s'' returned status %d\n",
    803 				remove_string, status);
    804 		}
    805 		exit(0);
    806 	}
    807 	return 0;
    808 }
    809 
    810 int massmurder(void)
    811 {
    812 	int i;
    813 	for (i = 0; i < MAXCHILD; i++) {
    814 		if (allchild[i]) {
    815 			kill(allchild[i], SIGTERM);
    816 		}
    817 	}
    818 	return 0;
    819 }
    820 
    821 /** LTP Port **/
    822 /*
    823  * setup
    824  *
    825  * Do set up - here its a dummy function
    826  */
    827 void setup(void)
    828 {
    829 	tst_tmpdir();
    830 	temp = stderr;
    831 }
    832 
    833 /*
    834  * fail_exit()
    835  *
    836  * Exit on failure
    837  */
    838 void fail_exit(void)
    839 {
    840 	tst_brkm(TFAIL, tst_rmdir, "Test failed\n");
    841 }
    842 
    843 /*
    844  *
    845  * Function: anyfail()
    846  *
    847  * Description: Exit a test.
    848  */
    849 void anyfail(void)
    850 {
    851 	(local_flag == FAILED) ? tst_resm(TFAIL, "Test failed")
    852 	    : tst_resm(TPASS, "Test passed");
    853 	tst_rmdir();
    854 	tst_exit();
    855 }
    856 
    857 /*
    858  * ok_exit
    859  *
    860  * Calling block passed the test
    861  */
    862 void ok_exit(void)
    863 {
    864 	local_flag = PASSED;
    865 	return;
    866 }
    867 
    868 /*
    869  * forkfail()
    870  *
    871  * exit on failure
    872  */
    873 void forkfail(void)
    874 {
    875 	tst_brkm(TBROK, tst_rmdir, "Reason: %s\n", strerror(errno));
    876 }
    877 
    878 /*
    879  * Function: terror
    880  *
    881  * Description: prints error message this may not be because some part of the
    882  *              test case failed, for example fork() failed. We will log this
    883  *              failure as TBROK instead of TFAIL.
    884  */
    885 void terror(char *message)
    886 {
    887 	tst_resm(TBROK, "Reason: %s:%s\n", message, strerror(errno));
    888 	return;
    889 }
    890 
    891 /*
    892  * instress
    893  *
    894  * Assume that we are always running under stress, so this function will
    895  * return > 0 value always.
    896  */
    897 int instress(void)
    898 {
    899 	tst_resm(TINFO, "System resource may be too low, fork() malloc()"
    900 		 " etc are likely to fail.\n");
    901 	return 1;
    902 }
    903