Home | History | Annotate | Download | only in doio
      1 /*
      2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
      3  *
      4  * This program is free software; you can redistribute it and/or modify it
      5  * under the terms of version 2 of the GNU General Public License as
      6  * published by the Free Software Foundation.
      7  *
      8  * This program is distributed in the hope that it would be useful, but
      9  * WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     11  *
     12  * Further, this software is distributed without any warranty that it is
     13  * free of the rightful claim of any third person regarding infringement
     14  * or the like.  Any license provided herein, whether implied or
     15  * otherwise, applies only to this software file.  Patent licenses, if
     16  * any, provided herein do not apply to combinations of this program with
     17  * other software, or any other product whatsoever.
     18  *
     19  * You should have received a copy of the GNU General Public License along
     20  * with this program; if not, write the Free Software Foundation, Inc.,
     21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     22  *
     23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
     24  * Mountain View, CA  94043, or:
     25  *
     26  * http://www.sgi.com
     27  *
     28  * For further information regarding this notice, see:
     29  *
     30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
     31  */
     32 /*
     33  * This program will grow a list of files.
     34  * Each file will grow by grow_incr before the same
     35  * file grows twice.  Each file is open and closed before next file is opened.
     36  *
     37  * To just verify file contents: growfiles -g 0 -c 1 filename
     38  *
     39  * See help and prt_examples functions below.
     40  *
     41  * Basic code layout
     42  *  process cmdline
     43  *  print debug message about options used
     44  *  setup signal handlers
     45  *  return control to user (if wanted - default action)
     46  *  fork number of desired childern (if wanted)
     47  *  re-exec self (if wanted)
     48  *  Determine number of files
     49  *  malloc space or i/o buffer
     50  *  Loop until stop is set
     51  *    Determine if hit iteration, time, max errors or num bytes reached
     52  *    Loop through each file
     53  *	open file
     54  *	fstat file - to determine if file if a fifo
     55  *	prealloc file space (if wanted)
     56  *      growfile
     57  *	check last write
     58  *	check whole file
     59  *	shrink file
     60  *	close file
     61  *	delay (if wanted)
     62  *    End loop
     63  *  End loop
     64  *  remove all files (if wanted)
     65  *
     66  * Author: Richard Logan
     67  *
     68  */
     69 #include <stdio.h>
     70 #include <errno.h>
     71 #include <stdlib.h>
     72 #include <ctype.h>
     73 #include <sys/types.h>
     74 #include <time.h>
     75 #include <sys/file.h>
     76 #include <unistd.h>
     77 #include <sys/stat.h>
     78 #include <sys/time.h>
     79 #include <sys/param.h>
     80 #include <sys/signal.h>
     81 #include <fcntl.h>
     82 #include <errno.h>
     83 #include <string.h>
     84 #include <inttypes.h>
     85 #include "dataascii.h"
     86 #include "random_range.h"
     87 #include "databin.h"
     88 #include "open_flags.h"
     89 #include "forker.h"
     90 #include "file_lock.h"
     91 
     92 #ifdef CRAY
     93 #include <sys/panic.h>
     94 #include <sys/category.h>
     95 #endif
     96 
     97 #include "test.h"
     98 
     99 int set_sig(void);
    100 void sig_handler(int sig);
    101 static void notify_others(void);
    102 int handle_error(void);
    103 int cleanup(void);
    104 void usage(void);
    105 void help(void);
    106 void prt_examples(FILE * stream);
    107 int growfile(int fd, char *file, int grow_incr, char *buf,
    108 	     unsigned long *curr_size_ptr);
    109 int shrinkfile(int fd, char *filename, int trunc_incr,
    110 	       int trunc_inter, int just_trunc);
    111 int check_write(int fd, int cf_inter, char *filename, int mode);
    112 int check_file(int fd, int cf_inter, char *filename, int no_file_check);
    113 int file_size(int fd);
    114 int lkfile(int fd, int operation, int lklevel);
    115 
    116 #ifndef linux
    117 int pre_alloc(int fd, long size);
    118 #endif /* !linux */
    119 
    120 extern int datapidgen(int, char *, int, int);
    121 extern int datapidchk(int, char *, int, int, char **);
    122 
    123 /* LTP status reporting */
    124 char *TCID = "growfiles";	/* Default test program identifier.    */
    125 int TST_TOTAL = 1;		/* Total number of test cases. */
    126 
    127 /* To avoid extensive modifications to the code, use this bodge */
    128 #define exit(x) myexit(x)
    129 void myexit(int x)
    130 {
    131 	if (x)
    132 		tst_resm(TFAIL, "Test failed");
    133 	else
    134 		tst_resm(TPASS, "Test passed");
    135 	tst_exit();
    136 }
    137 
    138 #define NEWIO	1		/* Use the tlibio.c functions */
    139 
    140 #ifndef NEWIO
    141 #define NEWIO	0		/* specifies to use original iowrite.c */
    142 			/* functions instead of tlibio.c functions */
    143 			/* Once it is proven tlibio.c functions work properly, */
    144 			/* only tlibio.c functions will be used */
    145 #else
    146 #include "tlibio.h"
    147 #endif
    148 
    149 #ifndef PATH_MAX
    150 #define PATH_MAX	1023
    151 #endif
    152 
    153 #define DEF_DIR		"."
    154 #define DEF_FILE	"gf"
    155 
    156 char *Progname;
    157 int Debug = 0;
    158 
    159 int Pid = 0;
    160 
    161 int io_type = 0;		/* I/O type -sync */
    162 
    163 #ifdef O_LARGEFILE
    164 int open_flags = O_RDWR | O_CREAT | O_LARGEFILE;	/* open flags */
    165 #else
    166 #warning O_LARGEFILE is not defined!
    167 int open_flags = O_RDWR | O_CREAT;	/* open flags */
    168 #endif
    169 
    170 #define MAX_FC_READ	196608	/* 4096 * 48 - 48 blocks */
    171 
    172 #define PATTERN_ASCII	1	/* repeating alphabet letter pattern */
    173 				/* allows multiple writers and to be checked */
    174 #define PATTERN_PID	2	/* <pid><words byte offset><pid> */
    175 				/* Assumes 64 bit word. Only allows single */
    176 				/* process to write and check */
    177 /*
    178  *	1234567890123456789012345678901234567890123456789012345678901234
    179  *	________________________________________________________________
    180  *	<    pid       >< offset in file of this word  ><    pid       >
    181  */
    182 
    183 #define PATTERN_OFFSET	3	/* Like PATTERN_PID but has a fixed number */
    184 				/* (STATIC_NUM) instead of pid. */
    185 				/* Allows multiple processes to write/read */
    186 #define PATTERN_ALT	4	/* alternating bit pattern (i.e. 0x5555555...) */
    187 #define PATTERN_CHKER	5	/* checkerboard pattern (i.e. 0xff00ff00ff00...) */
    188 #define PATTERN_CNTING  6	/* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
    189 #define PATTERN_ONES	7	/* all bits set (i.e. 0xffffffffffffff...) */
    190 #define PATTERN_ZEROS	8	/* all bits cleared (i.e. 0x000000000...) */
    191 #define PATTERN_RANDOM	9	/* random integers - can not be checked */
    192 #define STATIC_NUM	221849	/* used instead of pid when PATTERN_OFFSET */
    193 
    194 #define MODE_RAND_SIZE	1	/* random write and trunc */
    195 #define MODE_RAND_LSEEK	2	/* random lseek before write */
    196 #define MODE_GROW_BY_LSEEK 4	/* lseek beyond end of file then write a byte */
    197 #define RANDOM_OPEN	999876	/* if Open_flags set to this value, open flags */
    198 				/* will be randomly choosen from Open_flags[] */
    199 #define MODE_FIFO	S_IFIFO	/* defined in stat.h  0010000 */
    200 
    201 int num_files = 0;		/* num_auto_files + cmd line files */
    202 char *filenames;		/* pointer to space containing filenames */
    203 int remove_files = 0;		/* if set, cleanup default is not to cleanup */
    204 int bytes_consumed = 0;		/* total bytes consumed, all files */
    205 int bytes_to_consume = 0;	/* non-zero if -B was specified, total bytes */
    206 int Maxerrs = 100;		/* Max number errors before forced exit */
    207 int Errors = 0;			/* number of encountered errors */
    208 int Upanic_on_error = 0;	/* call upanic if error and this variable set */
    209 
    210 /* The *_size variables are only used when random iosize option (-r) is used */
    211 int max_size = 5000;
    212 int min_size = 1;		/* also set in option parsing */
    213 int mult_size = 1;		/* when random iosz, iosz must be mult of mult_size */
    214 /* the *_lseek variables are only used when radon lseek option (-R) is used */
    215 int min_lseek = 0;		/* also set in option parsing */
    216 int max_lseek = -1;		/* -1 means size of file */
    217 #ifdef CRAY
    218 int Pattern = PATTERN_OFFSET;	/* This pattern is 64 bit word based */
    219 #else
    220 int Pattern = PATTERN_ASCII;
    221 #endif
    222 int Seed = -1;			/* random number seed, < 0 == uninitialized  */
    223 int Nseeds = 0;			/* Number of seed specified by the user */
    224 int *Seeds;			/* malloc'ed arrary of ints holding user spec seeds */
    225 
    226 int using_random = 0;		/* flag indicating randomization is being used */
    227 float delaysecs = 0.0;		/* delay between iterations (in seconds) */
    228 int delaytime;			/* delay between iterations in clocks/uses */
    229 int lockfile = 0;		/* if set, do file locking */
    230 				/* 1 = do file locking around write, trunc */
    231 				/* and reads. */
    232 				/* 2 = write lock around all file operations */
    233 
    234 off_t Woffset = 0;		/* offset before last write */
    235 int Grow_incr = 4096;		/* sz of last write */
    236 int Mode = 0;			/* bitmask of write/trunc mode */
    237 				/* also knows if dealing with fifo */
    238 char *Buffer = NULL;		/* buffer used by write and write check */
    239 int Alignment = 0;		/* if non word multiple, io will not be word aligned */
    240 int Opid = 0;			/* original pid */
    241 
    242 int Sync_with_others = 0;	/* Flag indicating to stop other if we stop before DONE */
    243 int Iter_cnt = 0;		/* contains current iteration count value */
    244 char TagName[40];		/* name of this growfiles (see Monster)     */
    245 
    246 struct fileinfo_t {
    247 	char *filename;
    248 	int fd;
    249 	int openflags;
    250 	int mode;
    251 } Fileinfo;
    252 
    253 /*
    254  * Define open flags that will be used when '-o random' option is used.
    255  * Note: If there is more than one growfiles doing its thing to the same
    256  * file, O_TRUNC will cause data mismatches.  How you ask?
    257  * timing of events, example:
    258  *   Process one		Process two
    259  *   ---------------		-------------
    260  *   get write lock
    261  *   fstat file
    262  *   lseek
    263  *   generate pattern
    264  *				open with O_TRUNC
    265  *   write with wrong pattern
    266  *	because offset is wrong
    267  *
    268  *  The second process truncated the file after the pattern was
    269  *  determined, thus the pattern is wrong for the file location.
    270  *
    271  * There can also be a timing problem with open flag O_APPEND if
    272  * file locks are not being used (-l option).  Things could happen
    273  * between the fstat and the write. Thus, writing the wrong pattern.
    274  * If all processes observe the file locks, O_APPEND should be ok
    275  * to use.
    276  */
    277 int Open_flags[] = {
    278 #ifdef CRAY
    279 	O_RDWR | O_CREAT,
    280 	O_RDWR | O_CREAT | O_RAW,
    281 	O_RDWR | O_CREAT | O_BIG,
    282 	O_RDWR | O_CREAT | O_APPEND,
    283 	O_RDWR | O_CREAT | O_NDELAY,
    284 	O_RDWR | O_CREAT | O_PLACE,
    285 	O_RDWR | O_CREAT | O_SYNC,
    286 	O_RDWR | O_CREAT | O_RAW | O_SYNC,
    287 	O_RDWR | O_CREAT | O_NDELAY | O_SYNC,
    288 	O_RDWR | O_CREAT | O_NDELAY | O_SYNC | O_BIG,
    289 	O_RDWR | O_CREAT | O_RAW,
    290 	O_RDWR | O_CREAT | O_RAW | O_APPEND,
    291 	O_RDWR | O_CREAT | O_RAW | O_BIG,
    292 	O_RDWR | O_CREAT | O_RAW | O_APPEND | O_BIG,
    293 /***
    294  * O_WELLFORMED makes -o random require well formed i/o
    295  ***/
    296 #if ALLOW_O_WELLFORMED
    297 #if O_PARALLEL
    298 	O_RDWR | O_CREAT | O_PARALLEL | O_WELLFORMED | O_RAW,
    299 	O_RDWR | O_CREAT | O_PARALLEL | O_WELLFORMED | O_RAW | O_TRUNC,
    300 #endif /* O_PARALLEL */
    301 #endif
    302 
    303 #else /* CRAY */
    304 	O_RDWR | O_CREAT,
    305 	O_RDWR | O_CREAT | O_APPEND,
    306 	O_RDWR | O_CREAT | O_NDELAY,
    307 	O_RDWR | O_CREAT | O_SYNC,
    308 	O_RDWR | O_CREAT | O_SYNC | O_NDELAY,
    309 	O_RDWR | O_CREAT | O_APPEND | O_NDELAY,
    310 
    311 #endif /* CRAY */
    312 };
    313 
    314 #define REXEC_INIT	0	/* don't do re-exec of childern */
    315 #define REXEC_DOIT	1	/* Do re-exec of childern */
    316 #define REXEC_DONE	2	/* We've already been re-exec'ed */
    317 
    318 #ifndef BSIZE
    319 #ifdef CRAY
    320 #define BSIZE	1024
    321 #else
    322 #define BSIZE	512
    323 #endif /* CRAY */
    324 #endif /* BSIZE */
    325 
    326 #define USECS_PER_SEC	1000000	/* microseconds per second */
    327 
    328 /*
    329  * Define marcos used when dealing with file locks.
    330  */
    331 #define LKLVL0		1	/* file lock around write/read/trunc */
    332 #define LKLVL1		2	/* file lock after open to before close */
    333 
    334 /*
    335  * Define special max lseek values
    336  */
    337 #define LSK_EOF       	    -1	/* set fptr up to EOF */
    338 #define LSK_EOFPLUSGROW	    -2	/* set fptr up to EOF + grow - leave whole */
    339 #define LSK_EOFMINUSGROW    -3	/* set fptr up to EOF-grow - no grow */
    340 
    341 /***********************************************************************
    342  * MAIN
    343  ***********************************************************************/
    344 int main(int argc, char **argv)
    345 {
    346 	extern char *optarg;	/* used by getopt */
    347 	extern int optind;
    348 
    349 	int ind;
    350 	int first_file_ind = 0;
    351 	int num_auto_files = 0;	/* files created by tool */
    352 	int seq_auto_files = 0;	/* auto files created by tool created by tool */
    353 	char *auto_dir = DEF_DIR;
    354 	char *auto_file = DEF_FILE;
    355 	int grow_incr = 4096;
    356 	int trunc_incr = 4096;
    357 	int trunc_inter = 0;	/* 0 means none, */
    358 	int unlink_inter = 0;	/* 0 means none, 1 means always unlink */
    359 	int unlink_inter_ran = -1;	/* -1 -use unlink_inter, otherwise randomly choose */
    360 	/* between unlink_inter and unlink_inter_ran */
    361 	int file_check_inter = 0;	/* 0 means never, 1 means always */
    362 	int write_check_inter = 1;	/* 0 means never, 1 means always */
    363 	int iterations = 1;	/* number of increments to be added */
    364 	int no_file_check = 0;	/* if set, no whole file checking will be done */
    365 	int num;
    366 	int fd;			/* file descriptor */
    367 	int stop = 0;		/* loop stopper if set */
    368 
    369 	unsigned long curr_size = 0;	/* BUG:14136 (keep track of file size) */
    370 	const unsigned long ext2_limit = 2147483647;	/* BUG:14136 (2GB ext2 filesize limit) */
    371 
    372 	int tmp;
    373 	char chr;
    374 	int ret;
    375 	int pre_alloc_space = 0;
    376 #ifndef linux
    377 	long total_grow_value;	/* used in pre-allocations */
    378 #endif
    379 	int backgrnd = 1;	/* return control to user */
    380 	struct stat statbuf;
    381 	int time_iterval = -1;
    382 	time_t start_time = 0;
    383 	char reason[128];	/* reason for loop termination */
    384 	int num_procs = 1;
    385 	int forker_mode = 0;
    386 	int reexec = REXEC_INIT;	/* reexec info */
    387 	char *exec_path = NULL;
    388 
    389 /*char *strrchr();*/
    390 
    391 	char *filename;		/* name of file specified by user */
    392 	char *cptr;		/* temp char pointer */
    393 	extern int Forker_npids;	/* num of forked pid, defined in forker.c */
    394 	struct timeval tv1;
    395 
    396 	if (argv[0][0] == '-')
    397 		reexec = REXEC_DONE;
    398 	/*
    399 	 * Determine name of file used to invoke this program
    400 	 */
    401 	if ((Progname = strrchr(argv[0], '/')) != NULL)
    402 		Progname++;
    403 	else
    404 		Progname = argv[0];
    405 
    406 	TagName[0] = '\0';
    407 
    408 	/*
    409 	 * Process options
    410 	 */
    411 	while ((ind = getopt(argc, argv,
    412 			     "hB:C:c:bd:D:e:Ef:g:H:I:i:lL:n:N:O:o:pP:q:wt:r:R:s:S:T:uU:W:xy"))
    413 	       != EOF) {
    414 		switch (ind) {
    415 
    416 		case 'h':
    417 			help();
    418 			tst_exit();
    419 
    420 		case 'B':
    421 			switch (sscanf(optarg, "%i%c", &bytes_to_consume, &chr)) {
    422 			case 1:	/* noop */
    423 				break;
    424 
    425 			case 2:
    426 				if (chr == 'b') {
    427 					bytes_to_consume *= BSIZE;
    428 				} else {
    429 					fprintf(stderr,
    430 						"%s%s:  --B option arg invalid\n",
    431 						Progname, TagName);
    432 					usage();
    433 					exit(1);
    434 				}
    435 				break;
    436 
    437 			default:
    438 				fprintf(stderr,
    439 					"%s%s: --B option arg invalid\n",
    440 					Progname, TagName);
    441 				usage();
    442 				exit(1);
    443 				break;
    444 			}
    445 
    446 			break;
    447 
    448 		case 'E':
    449 			prt_examples(stdout);
    450 			exit(0);
    451 
    452 		case 'b':	/* batch */
    453 			backgrnd = 0;
    454 			break;
    455 
    456 		case 'C':
    457 			if (sscanf(optarg, "%i", &write_check_inter) != 1) {
    458 				fprintf(stderr,
    459 					"%s%s: --c option arg invalid\n",
    460 					Progname, TagName);
    461 				usage();
    462 				exit(1);
    463 			}
    464 			break;
    465 
    466 		case 'c':
    467 			if (sscanf(optarg, "%i", &file_check_inter) != 1) {
    468 				fprintf(stderr,
    469 					"%s%s: --c option arg invalid\n",
    470 					Progname, TagName);
    471 				usage();
    472 				exit(1);
    473 			}
    474 			break;
    475 
    476 		case 'd':
    477 			auto_dir = optarg;
    478 #ifdef CRAY
    479 			unsetenv("TMPDIR");	/* force the use of auto_dir */
    480 #endif
    481 			if (stat(auto_dir, &statbuf) == -1) {
    482 				if (mkdir(auto_dir, 0777) == -1) {
    483 					if (errno != EEXIST) {
    484 						fprintf(stderr,
    485 							"%s%s: Unable to make dir %s\n",
    486 							Progname, TagName,
    487 							auto_dir);
    488 						exit(1);
    489 					}
    490 				}
    491 			} else {
    492 				if (!(statbuf.st_mode & S_IFDIR)) {
    493 					fprintf(stderr,
    494 						"%s%s: %s already exists and is not a directory\n",
    495 						Progname, TagName, auto_dir);
    496 					exit(1);
    497 				}
    498 			}
    499 			break;
    500 
    501 		case 'D':
    502 			if (sscanf(optarg, "%i", &Debug) != 1) {
    503 				fprintf(stderr,
    504 					"%s%s: --D option arg invalid\n",
    505 					Progname, TagName);
    506 				usage();
    507 				exit(1);
    508 			}
    509 			break;
    510 
    511 		case 'e':
    512 			if (sscanf(optarg, "%i", &Maxerrs) != 1) {
    513 				fprintf(stderr,
    514 					"%s%s: --e option arg invalid\n",
    515 					Progname, TagName);
    516 				usage();
    517 				exit(1);
    518 			}
    519 			break;
    520 
    521 		case 'f':
    522 			auto_file = optarg;
    523 			break;
    524 
    525 		case 'g':
    526 			if ((ret = sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1
    527 			    || grow_incr < 0) {
    528 
    529 				fprintf(stderr,
    530 					"%s%s: --g option arg invalid\n",
    531 					Progname, TagName);
    532 				usage();
    533 				exit(1);
    534 			}
    535 			if (ret == 2) {
    536 				if (chr == 'b' || chr == 'B')
    537 					grow_incr *= 4096;
    538 				else {
    539 					fprintf(stderr,
    540 						"%s%s: --g option arg invalid\n",
    541 						Progname, TagName);
    542 					usage();
    543 					exit(1);
    544 				}
    545 			}
    546 			break;
    547 
    548 		case 'H':
    549 			if (sscanf(optarg, "%f", &delaysecs) != 1
    550 			    || delaysecs < 0) {
    551 
    552 				fprintf(stderr,
    553 					"%s%s: --H option arg invalid\n",
    554 					Progname, TagName);
    555 				usage();
    556 				exit(1);
    557 			}
    558 			break;
    559 
    560 		case 'i':
    561 			if (sscanf(optarg, "%i", &iterations) != 1 ||
    562 			    iterations < 0) {
    563 
    564 				fprintf(stderr,
    565 					"%s%s: --i option arg invalid\n",
    566 					Progname, TagName);
    567 				usage();
    568 				exit(1);
    569 			}
    570 			break;
    571 
    572 		case 'I':
    573 #if NEWIO
    574 			if ((io_type = lio_parse_io_arg1(optarg)) == -1) {
    575 				fprintf(stderr,
    576 					"%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
    577 					Progname, TagName);
    578 				exit(1);
    579 			}
    580 			if (io_type & LIO_RANDOM)
    581 				using_random++;
    582 #else
    583 			if ((io_type = parse_io_arg(optarg)) == -1) {
    584 				fprintf(stderr,
    585 					"%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
    586 					Progname, TagName);
    587 				exit(1);
    588 			}
    589 			if (io_type == 99)	/* hold-over until tlibio.h */
    590 				using_random++;
    591 #endif
    592 			break;
    593 
    594 		case 'l':
    595 			lockfile++;
    596 			if (lockfile > 2)
    597 				lockfile = 2;	/* lockfile can only be 1 or 2 */
    598 			break;
    599 
    600 		case 'L':
    601 			if (sscanf(optarg, "%i", &time_iterval) != 1 ||
    602 			    time_iterval < 0) {
    603 				fprintf(stderr,
    604 					"%s%s: --L option arg invalid\n",
    605 					Progname, TagName);
    606 				usage();
    607 				exit(1);
    608 			}
    609 			break;
    610 
    611 		case 'n':
    612 			if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) <
    613 			    1 || num_procs < 0) {
    614 
    615 				fprintf(stderr,
    616 					"%s%s: --n option arg invalid\n",
    617 					Progname, TagName);
    618 				usage();
    619 				exit(1);
    620 			}
    621 
    622 			break;
    623 
    624 		case 'N':
    625 			if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
    626 			    num_auto_files < 0) {
    627 
    628 				fprintf(stderr,
    629 					"%s%s: --N option arg invalid\n",
    630 					Progname, TagName);
    631 				usage();
    632 				exit(1);
    633 			}
    634 			break;
    635 
    636 		case 'O':
    637 			if (sscanf(optarg, "%i", &Alignment) != 1 ||
    638 			    Alignment < 0) {
    639 
    640 				fprintf(stderr,
    641 					"%s%s: --O option arg invalid\n",
    642 					Progname, TagName);
    643 				usage();
    644 				exit(1);
    645 			}
    646 			break;
    647 
    648 		case 'o':
    649 			if (strcmp(optarg, "random") == 0) {
    650 				open_flags = RANDOM_OPEN;
    651 				using_random++;
    652 
    653 			} else if ((open_flags = parse_open_flags(optarg, NULL))
    654 				   == -1) {
    655 				fprintf(stderr,
    656 					"%s%s: --o arg contains invalid flag\n",
    657 					Progname, TagName);
    658 				exit(1);
    659 			}
    660 			break;
    661 
    662 		case 'p':	/* pre allocate space */
    663 #ifdef linux
    664 			printf("%s%s: --p is illegal option on linux system\n",
    665 			       Progname, TagName);
    666 			exit(1);
    667 #else
    668 			pre_alloc_space++;
    669 #endif
    670 			break;
    671 
    672 		case 'P':
    673 #ifdef CRAY
    674 			if (strcmp(optarg, "PANIC") != 0) {
    675 				fprintf(stderr, "%s%s: --P arg must be PANIC\n",
    676 					Progname, TagName);
    677 				exit(1);
    678 			}
    679 			Upanic_on_error++;
    680 			printf("%s%s: Will call upanic after writes\n", Progname, TagName);
    681 #else
    682 			printf
    683 			    ("%s%s: --P is illegal option on non-cray system\n",
    684 			     Progname, TagName);
    685 			exit(1);
    686 #endif
    687 			break;
    688 
    689 		case 'q':	/* file content or pattern */
    690 			switch (optarg[0]) {
    691 			case 'A':
    692 				Pattern = PATTERN_ALT;
    693 				break;
    694 			case 'a':
    695 				Pattern = PATTERN_ASCII;
    696 				break;
    697 			case 'p':
    698 				Pattern = PATTERN_PID;
    699 				break;
    700 			case 'o':
    701 				Pattern = PATTERN_OFFSET;
    702 				break;
    703 			case 'c':
    704 				Pattern = PATTERN_CHKER;
    705 				break;
    706 			case 'C':
    707 				Pattern = PATTERN_CNTING;
    708 				break;
    709 			case 'r':
    710 				Pattern = PATTERN_RANDOM;
    711 				using_random++;
    712 				break;
    713 			case 'z':
    714 				Pattern = PATTERN_ZEROS;
    715 				break;
    716 			case 'O':
    717 				Pattern = PATTERN_ONES;
    718 				break;
    719 			default:
    720 				fprintf(stderr,
    721 					"%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
    722 					Progname, TagName);
    723 				usage();
    724 				exit(1);
    725 			}
    726 			break;
    727 
    728 		case 'R':	/* random lseek before write arg: [min-]max */
    729 			if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) !=
    730 			    2) {
    731 				min_lseek = 1;	/* same as default in define */
    732 				if (sscanf(optarg, "%i%c", &max_lseek, &chr) !=
    733 				    1) {
    734 					fprintf(stderr,
    735 						"%s%s: --R option arg invalid: [min-]max\n",
    736 						Progname, TagName);
    737 					exit(1);
    738 				}
    739 			}
    740 			if (max_lseek < LSK_EOFMINUSGROW) {
    741 				fprintf(stderr,
    742 					"%s%s: --R option, max_lseek is invalid\n",
    743 					Progname, TagName);
    744 				exit(1);
    745 			}
    746 			Mode |= MODE_RAND_LSEEK;
    747 			using_random++;
    748 			break;
    749 
    750 		case 'r':	/* random io size arg: [min-]max[:mult] */
    751 
    752 			/* min-max:mult format */
    753 			if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
    754 				   &mult_size, &chr) != 3) {
    755 				min_size = 1;
    756 				/* max:mult format */
    757 				if (sscanf(optarg, "%i:%i%c", &max_size,
    758 					   &mult_size, &chr) != 2) {
    759 					/* min-max format */
    760 					if (sscanf(optarg, "%i-%i%c", &min_size,
    761 						   &max_size, &chr) != 2) {
    762 						min_size = 1;
    763 						if (sscanf
    764 						    (optarg, "%i%c", &max_size,
    765 						     &chr) != 1) {
    766 							fprintf(stderr,
    767 								"%s%s: --r option arg invalid: [min-]max[:mult]\n",
    768 								Progname,
    769 								TagName);
    770 							exit(1);
    771 						}
    772 					}
    773 				}
    774 			}
    775 
    776 			if (max_size < 0) {
    777 				fprintf(stderr,
    778 					"%s%s: --r option, max_size is invalid\n",
    779 					Progname, TagName);
    780 				exit(1);
    781 			}
    782 			/*
    783 			 * If min and max are the same, no randomness
    784 			 */
    785 			if (min_size != max_size) {
    786 				Mode |= MODE_RAND_SIZE;
    787 				using_random++;
    788 			}
    789 			break;
    790 
    791 		case 'S':
    792 			if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
    793 			    seq_auto_files < 0) {
    794 
    795 				fprintf(stderr,
    796 					"%s%s: --S option arg invalid\n",
    797 					Progname, TagName);
    798 				usage();
    799 				exit(1);
    800 			}
    801 			break;
    802 
    803 		case 's':	/* format: seed[,seed...] */
    804 
    805 			/* count the number of seeds */
    806 			cptr = optarg;
    807 			for (Nseeds = 1; *cptr; Nseeds++) {
    808 				if ((filename = strchr(cptr, ',')) == NULL)
    809 					break;
    810 				cptr = filename;
    811 				cptr++;
    812 			}
    813 			Seeds = malloc(Nseeds * sizeof(int));
    814 
    815 			/*
    816 			 * check that each seed is valid and put them in
    817 			 * the newly malloc'ed Seeds arrary.
    818 			 */
    819 			filename = cptr = optarg;
    820 			for (Nseeds = 0; *cptr; Nseeds++) {
    821 				if ((filename = strchr(cptr, ',')) == NULL) {
    822 					if (sscanf(cptr, "%i", &Seeds[Nseeds]) <
    823 					    1) {
    824 						fprintf(stderr,
    825 							"%s%s: --s option arg %s invalid\n",
    826 							Progname, TagName,
    827 							cptr);
    828 						usage();
    829 						exit(1);
    830 					}
    831 					Nseeds++;
    832 					break;
    833 				}
    834 
    835 				*filename = '\0';
    836 				if (sscanf(cptr, "%i", &Seeds[Nseeds]) < 1) {
    837 					fprintf(stderr,
    838 						"%s%s: --s option arg %s invalid\n",
    839 						Progname, TagName, cptr);
    840 					usage();
    841 					exit(1);
    842 				}
    843 				*filename = ',';	/* restore string */
    844 				cptr = filename;
    845 				cptr++;
    846 			}
    847 			break;
    848 
    849 		case 't':
    850 			if ((ret =
    851 			     sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1
    852 			    || trunc_incr < 0) {
    853 
    854 				fprintf(stderr,
    855 					"%s%s: --t option arg invalid\n",
    856 					Progname, TagName);
    857 				usage();
    858 				exit(1);
    859 			}
    860 			if (ret == 2) {
    861 				if (chr == 'b' || chr == 'B')
    862 					trunc_incr *= 4096;
    863 				else {
    864 					fprintf(stderr,
    865 						"%s%s: --t option arg invalid\n",
    866 						Progname, TagName);
    867 					usage();
    868 					exit(1);
    869 				}
    870 			}
    871 			break;
    872 
    873 		case 'T':	/* truncate interval */
    874 			if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
    875 			    trunc_inter < 0) {
    876 
    877 				fprintf(stderr,
    878 					"%s%s: --T option arg invalid\n",
    879 					Progname, TagName);
    880 				usage();
    881 				exit(1);
    882 			}
    883 			break;
    884 
    885 		case 'u':
    886 			remove_files++;
    887 			break;
    888 
    889 		case 'U':	/* how often to unlink file */
    890 			/*
    891 			 * formats:
    892 			 *      A-B  - randomly pick interval between A and B
    893 			 *      X    - unlink file every X iteration
    894 			 */
    895 			if (sscanf(optarg, "%i-%i", &unlink_inter,
    896 				   &unlink_inter_ran) == 2) {
    897 
    898 				if (unlink_inter < 0 || unlink_inter_ran < 0) {
    899 					fprintf(stderr,
    900 						"%s%s: --U option arg invalid\n",
    901 						Progname, TagName);
    902 					usage();
    903 					exit(1);
    904 				}
    905 				/* ensure unlink_inter contains smaller value */
    906 				if (unlink_inter > unlink_inter_ran) {
    907 					tmp = unlink_inter_ran;
    908 					unlink_inter_ran = unlink_inter;
    909 					unlink_inter = tmp;
    910 				}
    911 				using_random++;
    912 
    913 			} else if (sscanf(optarg, "%i%c", &unlink_inter, &chr)
    914 				   != 1 || unlink_inter < 0) {
    915 
    916 				fprintf(stderr,
    917 					"%s%s: --U option arg invalid\n",
    918 					Progname, TagName);
    919 				usage();
    920 				exit(1);
    921 			}
    922 			break;
    923 
    924 		case 'x':
    925 			if (reexec != REXEC_DONE)
    926 				reexec = REXEC_DOIT;
    927 			break;
    928 
    929 		case 'w':
    930 			Mode |= MODE_GROW_BY_LSEEK;
    931 			break;
    932 
    933 		case 'W':
    934 			TCID = optarg;
    935 			sprintf(TagName, "(%.39s)", optarg);
    936 			break;
    937 
    938 		case 'y':
    939 			Sync_with_others = 1;
    940 			break;
    941 
    942 		case '?':
    943 			usage();
    944 			exit(1);
    945 			break;
    946 		}
    947 	}
    948 
    949 	if (Debug == 1) {
    950 		cptr = getenv("TOUTPUT");
    951 		if ((cptr != NULL) && (strcmp(cptr, "NOPASS") == 0)) {
    952 			Debug = 0;
    953 		}
    954 	}
    955 
    956 	if (Pattern == PATTERN_RANDOM) {
    957 		no_file_check = 1;
    958 		if (write_check_inter || file_check_inter)
    959 			printf
    960 			    ("%s%s: %d Using random pattern - no data checking will be performed!\n",
    961 			     Progname, TagName, getpid());
    962 	} else if (max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK) {
    963 		no_file_check = 1;
    964 
    965 		if (file_check_inter)
    966 			printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
    967 no whole file checking will be performed!\n", Progname, TagName,
    968 			       getpid());
    969 
    970 	}
    971 
    972 	if (Mode & MODE_RAND_SIZE)
    973 		grow_incr = max_size;
    974 
    975 	set_sig();
    976 
    977 	Opid = getpid();
    978 	Pid = Opid;
    979 
    980 	if (backgrnd) {
    981 		if (Debug > 1)
    982 			printf
    983 			    ("%s: %d DEBUG2 forking, returning control to the user\n",
    984 			     Progname, Opid);
    985 		background(Progname);	/* give user their prompt back */
    986 	}
    987 #if CRAY
    988 	if (Sync_with_others)
    989 		setpgrp();
    990 #endif
    991 
    992 	if (Debug > 3) {
    993 #if NEWIO
    994 		lio_set_debug(Debug - 3);
    995 #else
    996 		set_iowrite_debug(Debug - 3);
    997 #endif
    998 	}
    999 
   1000 	/*
   1001 	 * Print some program information here if debug is turned on to
   1002 	 * level 3 or higher.
   1003 	 */
   1004 
   1005 	if (Debug > 2) {
   1006 
   1007 		if (Mode & MODE_GROW_BY_LSEEK)
   1008 			printf
   1009 			    ("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
   1010 			     Progname, Pid);
   1011 		else if (Pattern == PATTERN_OFFSET)
   1012 			printf
   1013 			    ("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
   1014 			     Progname, Pid, STATIC_NUM, STATIC_NUM);
   1015 		else if (Pattern == PATTERN_PID)
   1016 			printf
   1017 			    ("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
   1018 			     Progname, Pid);
   1019 		else if (Pattern == PATTERN_ASCII)
   1020 			printf
   1021 			    ("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
   1022 			     Progname, Pid);
   1023 		else if (Pattern == PATTERN_ALT)
   1024 			printf
   1025 			    ("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
   1026 			     Progname, Pid);
   1027 		else if (Pattern == PATTERN_CHKER)
   1028 			printf
   1029 			    ("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
   1030 			     Progname, Pid);
   1031 		else if (Pattern == PATTERN_CNTING)
   1032 			printf
   1033 			    ("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
   1034 			     Progname, Pid);
   1035 		else if (Pattern == PATTERN_RANDOM)
   1036 			printf
   1037 			    ("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
   1038 			     Progname, Pid);
   1039 		else if (Pattern == PATTERN_ONES)
   1040 			printf
   1041 			    ("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
   1042 			     Progname, Pid);
   1043 		else if (Pattern == PATTERN_ZEROS)
   1044 			printf
   1045 			    ("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
   1046 			     Progname, Pid);
   1047 
   1048 		else
   1049 			printf("%s: %d DEBUG3 unknown pattern\n",
   1050 			       Progname, Pid);
   1051 		if (bytes_to_consume)
   1052 			printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
   1053 			       Progname, Pid, bytes_to_consume);
   1054 		printf
   1055 		    ("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n",
   1056 		     Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
   1057 
   1058 		printf
   1059 		    ("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
   1060 		     Progname, Pid, Debug, remove_files);
   1061 
   1062 		printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
   1063 
   1064 		if (open_flags == RANDOM_OPEN)
   1065 			printf
   1066 			    ("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n",
   1067 			     Progname, Pid, io_type);
   1068 		else
   1069 			printf
   1070 			    ("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n",
   1071 			     Progname, Pid, open_flags, io_type);
   1072 
   1073 		if (Mode & MODE_RAND_SIZE) {
   1074 			printf
   1075 			    ("%s: %d DEBUG3 random write/trunc:  min=%d, max=%d, mult = %d\n",
   1076 			     Progname, Pid, min_size, max_size, mult_size);
   1077 		} else {
   1078 			printf("%s: %d DEBUG3 grow_incr = %d\n",
   1079 			       Progname, Pid, grow_incr);
   1080 		}
   1081 		if (Mode & MODE_RAND_LSEEK) {
   1082 			if (max_lseek == LSK_EOF)
   1083 				printf
   1084 				    ("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile>\n",
   1085 				     Progname, Pid, min_lseek);
   1086 			else if (max_lseek == LSK_EOFPLUSGROW)
   1087 				printf
   1088 				    ("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile+iosize>\n",
   1089 				     Progname, Pid, min_lseek);
   1090 			else if (max_lseek == LSK_EOFMINUSGROW)
   1091 				printf
   1092 				    ("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile-iosize>\n",
   1093 				     Progname, Pid, min_lseek);
   1094 			else
   1095 				printf
   1096 				    ("%s: %d DEBUG3 random lseek:  min=%d, max=%d\n",
   1097 				     Progname, Pid, min_lseek, max_lseek);
   1098 		}
   1099 
   1100 		printf
   1101 		    ("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
   1102 		     Progname, Pid, write_check_inter, file_check_inter);
   1103 
   1104 		printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
   1105 		       Progname, Pid, trunc_inter, trunc_incr);
   1106 
   1107 		if (no_file_check)
   1108 			printf
   1109 			    ("%s: %d DEBUG3 no whole file checking will be done\n",
   1110 			     Progname, Pid);
   1111 
   1112 		if (unlink_inter_ran == -1) {
   1113 			printf("%s: %d DEBUG3 unlink_inter = %d\n",
   1114 			       Progname, Pid, unlink_inter);
   1115 		} else {
   1116 			printf
   1117 			    ("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n",
   1118 			     Progname, Pid, unlink_inter, unlink_inter_ran);
   1119 		}
   1120 
   1121 		if (Debug > 8) {
   1122 			num = sizeof(Open_flags) / sizeof(int);
   1123 			printf("%s: %d DEBUG9 random open flags values:\n",
   1124 			       Progname, Pid);
   1125 			for (ind = 0; ind < num; ind++) {
   1126 				printf("\t%#o\n", Open_flags[ind]);
   1127 			}
   1128 		}
   1129 	}
   1130 	/* end of DEBUG > 2 */
   1131 	if (Debug > 1 && num_procs > 1) {
   1132 		printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
   1133 		       Opid, num_procs - 1);
   1134 	}
   1135 
   1136 	fflush(stdout);		/* ensure pending i/o is flushed before forking */
   1137 	fflush(stderr);
   1138 
   1139 	forker(num_procs, forker_mode, Progname);
   1140 
   1141 	Pid = getpid();		/* reset after the forks */
   1142 	/*
   1143 	 * If user specified random seed(s), get that random seed value.
   1144 	 * get random seed if it was not specified by the user.
   1145 	 * This is done after the forks, because pid is used to get the seed.
   1146 	 */
   1147 	if (Nseeds == 1) {
   1148 		/*
   1149 		 * If only one seed specified, all processes will get that seed.
   1150 		 */
   1151 		Seed = Seeds[0];
   1152 	} else if (Nseeds > 1) {
   1153 		/*
   1154 		 * More than one seed was specified.
   1155 		 * The original process gets the first seed.  Each
   1156 		 * process will be get the next seed in the specified list.
   1157 		 */
   1158 		if (Opid == Pid) {
   1159 			Seed = Seeds[0];
   1160 		} else {
   1161 			/*
   1162 			 * If user didn't specify enough seeds, use default method.
   1163 			 */
   1164 			if (Forker_npids >= Nseeds) {
   1165 				struct timeval ts;
   1166 				gettimeofday(&ts, NULL);
   1167 				Seed = ts.tv_sec + Pid;	/* default random seed */
   1168 			} else {
   1169 				Seed = Seeds[Forker_npids];
   1170 			}
   1171 		}
   1172 	} else {
   1173 		/*
   1174 		 * Generate a random seed based on time and pid.
   1175 		 * It has a good chance of being unique for each pid.
   1176 		 */
   1177 		struct timeval ts;
   1178 		gettimeofday(&ts, NULL);
   1179 		Seed = ts.tv_sec + Pid;	/* default random seed */
   1180 		//Seed=time(0) + Pid;  /* default random seed */
   1181 
   1182 	}
   1183 
   1184 	random_range_seed(Seed);
   1185 
   1186 	if (using_random && Debug > 0)
   1187 		printf("%s%s: %d DEBUG1 Using random seed of %d\n",
   1188 		       Progname, TagName, Pid, Seed);
   1189 
   1190 	if (unlink_inter_ran > 0) {
   1191 		/*
   1192 		 * Find unlinking file interval.  This must be done after
   1193 		 * the seed was set.   This allows multiple copies to
   1194 		 * get different intervals.
   1195 		 */
   1196 		tmp = unlink_inter;
   1197 		unlink_inter =
   1198 		    (int)random_range(tmp, unlink_inter_ran, 1, NULL);
   1199 
   1200 		if (Debug > 2)
   1201 			printf
   1202 			    ("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
   1203 			     Progname, Pid, unlink_inter, tmp,
   1204 			     unlink_inter_ran);
   1205 	}
   1206 
   1207 	/*
   1208 	 * re-exec all childern if reexec is set to REXEC_DOIT.
   1209 	 * This is useful on MPP systems to get the
   1210 	 * child process on another PE.
   1211 	 */
   1212 	if (reexec == REXEC_DOIT && Opid != Pid) {
   1213 		if (exec_path == NULL) {
   1214 			exec_path = argv[0];
   1215 			/* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
   1216 			argv[0] = malloc(strlen(exec_path) + 2);
   1217 			sprintf(argv[0], "-%s", exec_path);
   1218 		}
   1219 
   1220 		if (Debug > 2)
   1221 			printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
   1222 			       Progname, Pid, __FILE__, __LINE__, argv[0]);
   1223 
   1224 		execvp(argv[0], argv);
   1225 	}
   1226 
   1227 	/*** begin filename stuff here *****/
   1228 	/*
   1229 	 * Determine the number of files to be dealt with
   1230 	 */
   1231 	if (optind == argc) {
   1232 		/*
   1233 		 * no cmd line files, therfore, set
   1234 		 * the default number of auto created files
   1235 		 */
   1236 		if (!num_auto_files && !seq_auto_files)
   1237 			num_auto_files = 1;
   1238 	} else {
   1239 		first_file_ind = optind;
   1240 		num_files += argc - optind;
   1241 	}
   1242 
   1243 	if (num_auto_files) {
   1244 		num_files += num_auto_files;
   1245 	}
   1246 
   1247 	if (seq_auto_files) {
   1248 		num_files += seq_auto_files;
   1249 	}
   1250 
   1251 	/*
   1252 	 * get space for file names
   1253 	 */
   1254 	if ((filenames = malloc(num_files * PATH_MAX)) == NULL) {
   1255 		fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
   1256 			Progname, TagName, Pid, __FILE__, __LINE__,
   1257 			num_files * PATH_MAX, strerror(errno));
   1258 		exit(1);
   1259 	}
   1260 
   1261 	/*
   1262 	 * fill in filename cmd files then auto files.
   1263 	 */
   1264 
   1265 	num = 0;
   1266 	if (first_file_ind) {
   1267 		for (ind = first_file_ind; ind < argc; ind++, num++) {
   1268 			strcpy((char *)filenames + (num * PATH_MAX), argv[ind]);
   1269 		}
   1270 	}
   1271 
   1272 	/*
   1273 	 * construct auto filename and insert them into filenames space
   1274 	 */
   1275 
   1276 	for (ind = 0; ind < num_auto_files; ind++, num++) {
   1277 		gettimeofday(&tv1, NULL);
   1278 		sprintf((char *)filenames + (num * PATH_MAX),
   1279 			"%s/%s%ld%ld%d.%d", auto_dir, auto_file,
   1280 			(long)tv1.tv_sec, (long)tv1.tv_usec, rand(), ind);
   1281 	}
   1282 
   1283 	/*
   1284 	 * construct auto seq filenames
   1285 	 */
   1286 	for (ind = 1; ind <= seq_auto_files; ind++, num++) {
   1287 		sprintf((char *)filenames + (num * PATH_MAX), "%s/%s%d",
   1288 			auto_dir, auto_file, ind);
   1289 	}
   1290 
   1291 /**** end filename stuff ****/
   1292 
   1293 	if (time_iterval > 0) {
   1294 		struct timeval ts;
   1295 		gettimeofday(&ts, NULL);
   1296 		start_time = ts.tv_sec;
   1297 		//start_time=time(0);
   1298 	}
   1299 
   1300 	/*
   1301 	 * get space for I/O buffer
   1302 	 */
   1303 	if (grow_incr) {
   1304 		if ((Buffer = malloc(grow_incr + Alignment)) == NULL) {
   1305 			fprintf(stderr,
   1306 				"%s%s: %d %s/%d: malloc(%d) failed: %s\n",
   1307 				Progname, TagName, Pid, __FILE__, __LINE__,
   1308 				grow_incr, strerror(errno));
   1309 			exit(1);
   1310 		}
   1311 		if (Alignment)
   1312 			Buffer = Buffer + Alignment;
   1313 
   1314 	}
   1315 
   1316 	if (Debug > 2) {
   1317 		printf("%s: %d DEBUG3 num_files = %d\n",
   1318 		       Progname, Pid, num_files);
   1319 	}
   1320 #ifndef linux
   1321 	if (pre_alloc_space) {
   1322 		if (iterations == 0) {
   1323 			fprintf(stderr,
   1324 				"%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
   1325 				Progname, TagName, Pid, __FILE__, __LINE__);
   1326 			exit(1);
   1327 		}
   1328 		if (Mode & MODE_RAND_SIZE) {
   1329 			fprintf(stderr,
   1330 				"%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
   1331 				Progname, TagName, Pid, __FILE__, __LINE__);
   1332 			exit(1);
   1333 		}
   1334 
   1335 		total_grow_value = grow_incr * iterations;
   1336 
   1337 		/*
   1338 		 * attempt to limit
   1339 		 */
   1340 		if (bytes_to_consume && bytes_to_consume < total_grow_value) {
   1341 			total_grow_value = bytes_to_consume;
   1342 		}
   1343 	}
   1344 #endif
   1345 
   1346 	/*
   1347 	 * If delaying between iterations, get amount time to
   1348 	 * delaysecs in clocks or usecs.
   1349 	 * If on the CRAY, delaytime is in clocks since
   1350 	 * _rtc() will be used, which does not have the overhead
   1351 	 * of gettimeofday(2).
   1352 	 */
   1353 	if (delaysecs) {
   1354 #if CRAY
   1355 		int hz;
   1356 		hz = sysconf(_SC_CLK_TCK);
   1357 		delaytime = (int)((float)hz * delaysecs);
   1358 #else
   1359 		delaytime = (int)((float)USECS_PER_SEC * delaysecs);
   1360 #endif
   1361 	}
   1362 
   1363 	/*
   1364 	 * This is the main iteration loop.
   1365 	 * Each iteration, all files can  be opened, written to,
   1366 	 * read to check the write, check the whole file,
   1367 	 * truncated, and closed.
   1368 	 */
   1369 	for (Iter_cnt = 1; !stop; Iter_cnt++) {
   1370 		struct timeval ts;
   1371 		if (iterations && (Iter_cnt >= iterations + 1)) {
   1372 			strcpy(reason, "Hit iteration value");
   1373 			stop = 1;
   1374 			continue;
   1375 		}
   1376 		gettimeofday(&ts, NULL);
   1377 		if ((time_iterval > 0)
   1378 		    && (start_time + time_iterval < ts.tv_sec)) {
   1379 
   1380 			sprintf(reason, "Hit time value of %d", time_iterval);
   1381 			stop = 1;
   1382 			continue;
   1383 		}
   1384 
   1385 		if (bytes_to_consume && bytes_consumed >= bytes_to_consume) {
   1386 			sprintf(reason, "Hit bytes consumed value of %d",
   1387 				bytes_to_consume);
   1388 			stop = 1;
   1389 			continue;
   1390 		}
   1391 
   1392 		/*
   1393 		 * This loop will loop through all files.
   1394 		 * Each iteration, a single file can  be opened, written to,
   1395 		 * read to check the write, check the whole file,
   1396 		 * truncated, and closed.
   1397 		 */
   1398 		for (ind = 0; ind < num_files; ind++) {
   1399 
   1400 			fflush(stdout);
   1401 			fflush(stderr);
   1402 
   1403 			filename = (char *)filenames + (ind * PATH_MAX);
   1404 			Fileinfo.filename =
   1405 			    (char *)filenames + (ind * PATH_MAX);
   1406 
   1407 			if (open_flags == RANDOM_OPEN) {
   1408 				ret =
   1409 				    Open_flags[random_range
   1410 					       (0,
   1411 						sizeof(Open_flags) /
   1412 						sizeof(int) - 1, 1, NULL)];
   1413 			}
   1414 
   1415 			else
   1416 				ret = open_flags;
   1417 
   1418 			Fileinfo.openflags = ret;
   1419 
   1420 			if (Debug > 3) {
   1421 				printf
   1422 				    ("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
   1423 				     Progname, Pid, __FILE__, __LINE__,
   1424 				     Iter_cnt, filename, ret,
   1425 				     openflags2symbols(ret, ",", 0));
   1426 			} else if (Debug > 2) {
   1427 				printf
   1428 				    ("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
   1429 				     Progname, Pid, __FILE__, __LINE__,
   1430 				     Iter_cnt, filename, ret);
   1431 			}
   1432 
   1433 			/*
   1434 			 * open file with desired flags.
   1435 			 */
   1436 			if ((fd = open(filename, ret, 0777)) == -1) {
   1437 				fprintf(stderr,
   1438 					"%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
   1439 					Progname, TagName, Pid, __FILE__,
   1440 					__LINE__, filename, ret, errno,
   1441 					strerror(errno));
   1442 				handle_error();
   1443 				continue;
   1444 			}
   1445 
   1446 			Fileinfo.fd = fd;
   1447 
   1448 			lkfile(fd, LOCK_EX, LKLVL1);	/* lock if lockfile is LKLVL1 */
   1449 
   1450 #ifndef linux
   1451 			/*
   1452 			 * preallocation is only done once, if specified.
   1453 			 */
   1454 			if (pre_alloc_space) {
   1455 				if (pre_alloc(fd, total_grow_value) != 0) {
   1456 					cleanup();
   1457 					exit(2);
   1458 				}
   1459 				if (Debug > 1) {
   1460 					printf
   1461 					    ("%s: %d DEBUG2 %s/%d: pre_allocated %ld for file %s\n",
   1462 					     Progname, Pid, __FILE__, __LINE__,
   1463 					     total_grow_value, filename);
   1464 				}
   1465 				lkfile(fd, LOCK_UN, LKLVL1);	/* release lock */
   1466 				close(fd);
   1467 				Iter_cnt = 0;	/* reset outside loop to restart from one */
   1468 				continue;
   1469 			}
   1470 #endif
   1471 
   1472 			/*
   1473 			 * grow file by desired amount.
   1474 			 * growfile() will set the Grow_incr variable and
   1475 			 * possiblly update the Mode variable indicating
   1476 			 * if we are dealing with a FIFO file.
   1477 			 */
   1478 
   1479 			/* BUG:14136 (don't go past ext2's filesize limit) */
   1480 			curr_size = file_size(fd);
   1481 			if (curr_size + grow_incr >= ext2_limit) {
   1482 				lkfile(fd, LOCK_UN, LKLVL1);	/* release lock */
   1483 				close(fd);
   1484 				sprintf(reason,
   1485 					"Reached %ld filesize which is almost %ld limit.",
   1486 					curr_size, ext2_limit);
   1487 				stop = 1;
   1488 				continue;
   1489 			}
   1490 
   1491 			if (growfile(fd, filename, grow_incr, Buffer, &curr_size) != 0) {	/* BUG:14136 */
   1492 				handle_error();
   1493 				lkfile(fd, LOCK_UN, LKLVL1);	/* release lock */
   1494 				close(fd);
   1495 				continue;
   1496 			}
   1497 
   1498 			/*
   1499 			 * check if last write is not corrupted
   1500 			 */
   1501 			if (check_write(fd, write_check_inter, filename,
   1502 					Mode) != 0) {
   1503 				handle_error();
   1504 			}
   1505 
   1506 			/*
   1507 			 * Check that whole file is not corrupted.
   1508 			 */
   1509 			if (check_file(fd, file_check_inter, filename,
   1510 				       no_file_check) != 0) {
   1511 				handle_error();
   1512 			}
   1513 
   1514 			/*
   1515 			 * shrink file by desired amount if it is time
   1516 			 */
   1517 
   1518 			if (shrinkfile
   1519 			    (fd, filename, trunc_incr, trunc_inter,
   1520 			     Mode) != 0) {
   1521 				handle_error();
   1522 			}
   1523 
   1524 			lkfile(fd, LOCK_UN, LKLVL1);	/* release lock */
   1525 
   1526 			if (Debug > 4)
   1527 				printf
   1528 				    ("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n",
   1529 				     Progname, Pid, __FILE__, __LINE__,
   1530 				     Iter_cnt, filename, fd);
   1531 			close(fd);
   1532 
   1533 			/*
   1534 			 * Unlink the file if that is desired
   1535 			 */
   1536 			if (unlink_inter && (Iter_cnt % unlink_inter == 0)) {
   1537 
   1538 				if (Debug > 4)
   1539 					printf
   1540 					    ("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n",
   1541 					     Progname, Pid, __FILE__, __LINE__,
   1542 					     Iter_cnt, filename);
   1543 
   1544 				unlink(filename);
   1545 			}
   1546 
   1547 			/*
   1548 			 * delay while staying active for "delaysecs" seconds.
   1549 			 */
   1550 			if (delaytime) {
   1551 
   1552 				int ct, end;
   1553 #ifdef CRAY
   1554 				ct = _rtc();
   1555 				end = ct + delaytime;
   1556 				while (ct < end) {
   1557 					ct = _rtc();
   1558 				}
   1559 #else
   1560 				struct timeval curtime;
   1561 				gettimeofday(&curtime, NULL);
   1562 				ct = curtime.tv_sec * USECS_PER_SEC +
   1563 				    curtime.tv_usec;
   1564 				end = ct + delaytime;
   1565 				while (ct < end) {
   1566 
   1567 					gettimeofday(&curtime, NULL);
   1568 					ct = curtime.tv_sec * USECS_PER_SEC +
   1569 					    curtime.tv_usec;
   1570 				}
   1571 #endif
   1572 			}
   1573 		}
   1574 #ifndef linux
   1575 		/*
   1576 		 * if Iter_cnt == 0, then we pre allocated space to all files
   1577 		 * and we are starting outside loop over.  Set pre_alloc_space
   1578 		 * to zero otherwise we get in infinite loop
   1579 		 */
   1580 		if (Iter_cnt == 0) {
   1581 			pre_alloc_space = 0;
   1582 		}
   1583 #endif
   1584 
   1585 	}			/* end iteration for loop */
   1586 
   1587 	if (Debug) {
   1588 		printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
   1589 		       Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt,
   1590 		       num_files, reason);
   1591 	}
   1592 	fflush(stdout);
   1593 	fflush(stderr);
   1594 
   1595 	cleanup();
   1596 
   1597 	if (Errors) {
   1598 		if (Debug > 2) {
   1599 			printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
   1600 			       Progname, TagName, Pid, Errors);
   1601 			printf
   1602 			    ("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n",
   1603 			     Progname, TagName, Pid, __FILE__, __LINE__);
   1604 		}
   1605 		exit(1);
   1606 	}
   1607 	if (Debug > 2) {
   1608 		printf
   1609 		    ("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n",
   1610 		     Progname, TagName, Pid, __FILE__, __LINE__);
   1611 	}
   1612 
   1613 	exit(0);
   1614 	tst_exit();		/* to keep compiler happy */
   1615 }
   1616 
   1617 /***********************************************************************
   1618  *
   1619  ***********************************************************************/
   1620 int set_sig(void)
   1621 {
   1622 	int sig;
   1623 
   1624 	/*
   1625 	 * now loop through all signals and set the handlers
   1626 	 */
   1627 
   1628 	for (sig = 1; sig < NSIG; sig++) {
   1629 		switch (sig) {
   1630 		case SIGKILL:
   1631 		case SIGSTOP:
   1632 		case SIGCONT:
   1633 #ifdef CRAY
   1634 		case SIGINFO:
   1635 		case SIGRECOVERY:
   1636 #endif /* CRAY */
   1637 #ifdef SIGCKPT
   1638 		case SIGCKPT:
   1639 #endif /* SIGCKPT */
   1640 #ifdef SIGRESTART
   1641 		case SIGRESTART:
   1642 #endif /* SIGRESTART */
   1643 		case SIGCHLD:
   1644 			break;
   1645 
   1646 		default:
   1647 #ifdef sgi
   1648 			sigset(sig, sig_handler);
   1649 #else
   1650 /* linux and cray */
   1651 			signal(sig, sig_handler);
   1652 #endif
   1653 			break;
   1654 		}
   1655 	}			/* endfor */
   1656 
   1657 	return 0;
   1658 }
   1659 
   1660 /***********************************************************************
   1661  *
   1662  ***********************************************************************/
   1663 void sig_handler(int sig)
   1664 {
   1665 	int exit_stat = 2;
   1666 
   1667 	if (sig == SIGUSR2) {
   1668 		fprintf(stdout,
   1669 			"%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
   1670 			Progname, TagName, Pid, __FILE__, __LINE__, sig);
   1671 #ifndef sgi
   1672 		signal(sig, sig_handler);	/* allow us to get this signal more than once */
   1673 #endif
   1674 
   1675 	} else if (sig == SIGINT) {
   1676 		/* The user has told us to cleanup, don't pretend it's an error. */
   1677 		exit_stat = 0;
   1678 		if (Debug != 0) {
   1679 			fprintf(stderr,
   1680 				"%s%s: %d %s/%d: received unexpected signal: %d\n",
   1681 				Progname, TagName, Pid, __FILE__, __LINE__,
   1682 				sig);
   1683 		}
   1684 	} else {
   1685 		fprintf(stderr,
   1686 			"%s%s: %d %s/%d: received unexpected signal: %d\n",
   1687 			Progname, TagName, Pid, __FILE__, __LINE__, sig);
   1688 	}
   1689 
   1690 	notify_others();
   1691 	cleanup();
   1692 	if (Debug > 2) {
   1693 		printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
   1694 		       Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
   1695 	}
   1696 	exit(exit_stat);
   1697 }
   1698 
   1699 /***********************************************************************
   1700  * this function attempts to send SIGUSR2 to other growfiles processes
   1701  * telling them to stop.
   1702  *
   1703  ***********************************************************************/
   1704 static void notify_others(void)
   1705 {
   1706 	static int send_signals = 0;
   1707 	int ind;
   1708 
   1709 	if (Sync_with_others && send_signals == 0) {
   1710 
   1711 #if CRAY
   1712 		send_signals = 1;	/* only send signals once */
   1713 		if (Debug > 1)
   1714 			printf
   1715 			    ("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pgrp\n",
   1716 			     Progname, TagName, Pid, __FILE__, __LINE__);
   1717 		killm(C_PGRP, getpgrp(), SIGUSR2);
   1718 #else
   1719 		send_signals = 1;	/* only send signals once */
   1720 
   1721 		for (ind = 0; ind < Forker_npids; ind++) {
   1722 			if (Forker_pids[ind] != Pid)
   1723 				if (Debug > 1)
   1724 					printf
   1725 					    ("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
   1726 					     Progname, TagName, Pid, __FILE__,
   1727 					     __LINE__, Forker_pids[ind]);
   1728 			kill(Forker_pids[ind], SIGUSR2);
   1729 		}
   1730 #endif
   1731 	}
   1732 
   1733 }
   1734 
   1735 /***********************************************************************
   1736  * this function will count the number of errors encountered.
   1737  * This function will call upanic if wanted or cleanup and
   1738  * and exit is Maxerrs were encountered.
   1739  ***********************************************************************/
   1740 int handle_error(void)
   1741 {
   1742 	Errors++;
   1743 
   1744 #ifdef CRAY
   1745 	if (Errors & Upanic_on_error) {
   1746 		upanic(PA_PANIC);
   1747 	}
   1748 #endif
   1749 
   1750 	if (Maxerrs && Errors >= Maxerrs) {
   1751 		printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n",
   1752 		       Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt,
   1753 		       Maxerrs);
   1754 		notify_others();
   1755 		cleanup();
   1756 
   1757 		if (Debug > 2) {
   1758 			printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
   1759 			       Progname, TagName, Pid, Errors);
   1760 			printf
   1761 			    ("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n",
   1762 			     Progname, TagName, Pid, __FILE__, __LINE__);
   1763 		}
   1764 
   1765 		exit(1);
   1766 	}
   1767 
   1768 	return 0;
   1769 }
   1770 
   1771 /***********************************************************************
   1772  *
   1773  ***********************************************************************/
   1774 int cleanup(void)
   1775 {
   1776 	int ind;
   1777 
   1778 	if (remove_files) {
   1779 		if (Debug > 2)
   1780 			printf("%s: %d DEBUG3 Removing all %d files\n",
   1781 			       Progname, Pid, num_files);
   1782 		for (ind = 0; ind <= num_files; ind++) {
   1783 			unlink(filenames + (ind * PATH_MAX));
   1784 		}
   1785 	}
   1786 	if (using_random && Debug > 1)
   1787 		printf("%s%s: %d DEBUG2 Used random seed: %d\n",
   1788 		       Progname, TagName, Pid, Seed);
   1789 	return 0;
   1790 }
   1791 
   1792 /***********************************************************************
   1793  *
   1794  ***********************************************************************/
   1795 void usage(void)
   1796 {
   1797 	fprintf(stderr,
   1798 		"Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
   1799 		Progname, TagName);
   1800 	fprintf(stderr,
   1801 		"[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
   1802 	fprintf(stderr,
   1803 		"[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
   1804 	fprintf(stderr,
   1805 		"[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
   1806 
   1807 	return;
   1808 
   1809 }				/* end of usage */
   1810 
   1811 /***********************************************************************
   1812  *
   1813  ***********************************************************************/
   1814 void help(void)
   1815 {
   1816 	usage();
   1817 
   1818 	fprintf(stdout, "\
   1819   -h             Specfied to print this help and exit.\n\
   1820   -b             Specfied to execute in sync mode.(def async mode)\n\
   1821   -B maxbytes    Max bytes to consume by all files.  growfiles exits when more\n\
   1822                  than maxbytes have been consumed. (def no chk)  If maxbytes ends\n\
   1823                  with the letter 'b', maxbytes is multiplied by BSIZE\n\
   1824   -C write_chk   Specifies how often to check the last write (default 1)\n\
   1825   -c file_chk    Specifies how often to check whole file (default 0)\n\
   1826   -d auto_dir    Specifies the directory to auto created files. (default .)\n\
   1827   -D debug_lvl   Specifies the debug level (default 1)\n\
   1828   -E             Print examples and exit\n\
   1829   -e errs        The number errors that will terminate this program (def 100)\n\
   1830   -f auto_file   Specifies the base filename files created. (default \"gf\")\n\
   1831   -g grow_incr   Specfied to grow by incr for each num. (default 4096)\n\
   1832                  grow_incr may end in b for blocks\n\
   1833 		 If -r option is used, this option is ignored and size is random\n\
   1834   -H delay       Amount of time to delay between each file (default 0.0)\n\
   1835   -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
   1836 		 l - listio sync, L - listio async, r - random\n\
   1837   -i iteration   Specfied to grow each file num times. 0 means forever (default 1)\n\
   1838   -l             Specfied to do file locking around write/read/trunc\n\
   1839 		 If specified twice, file locking after open to just before close\n\
   1840   -L time        Specfied to exit after time secs, must be used with -i.\n\
   1841   -N num_files   Specifies the number of files to be created.\n\
   1842                  The default is zero if cmd line files.\n\
   1843                  The default is one if no cmd line files.\n\
   1844   -n num_procs   Specifies the number of copies of this cmd.\n\
   1845   -o op_type     Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
   1846   -O offset      adjust i/o buffer alignment by offset bytes\n\
   1847   -P PANIC       Specifies to call upanic on error.\n\
   1848   -p             Specifies to pre-allocate space\n\
   1849   -q pattern     pattern can be a - ascii, p - pid with boff, o boff (def)\n\
   1850 		 A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
   1851 		 c - checkboard, C - counting\n\
   1852   -R [min-]max   random lseek before write and trunc, max of -1 means filesz,\n\
   1853 		 -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
   1854   -r [min-]max   random io write size (min def is 1)\n\
   1855   -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
   1856   -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
   1857   -t trunc_incr  Specfied the amount to shrink file. (default 4096)\n\
   1858                  trunc_inter may end in b for blocks\n\
   1859 		 If -R option is used, this option is ignored and trunc is random\n\
   1860   -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
   1861   -u             unlink files before exit\n\
   1862   -U ui[-ui2]    Unlink files each ui iteration (def 0)\n\
   1863   -w             Specfied to grow via lseek instead of writes.\n\
   1864   -W tag-name	 Who-am-i.  My Monster tag name.  (used by Monster).\n\
   1865   -x		 Re-exec children before continuing - useful on MPP systems\n\
   1866   -y             Attempt to sync copies - if one fails it will send sigusr2 to others\n\
   1867   Action to each file every iteration is open, write, write check\n\
   1868   file check, trunc and closed.\n");
   1869 
   1870 	return;
   1871 }
   1872 
   1873 /***********************************************************************
   1874  *
   1875  ***********************************************************************/
   1876 void prt_examples(FILE * stream)
   1877 {
   1878 	/* This example creates 200 files in directory dir1.  It writes */
   1879 	/* 4090 bytes 100 times then truncates 408990 bytes off the file */
   1880 	/* The file contents are checked every 1000 grow. */
   1881 	fprintf(stream,
   1882 		"# run forever: writes of 4090 bytes then on every 100 iterval\n\
   1883 # truncate file by 408990 bytes.  Done to 200 files in dir1.\n\
   1884 %s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n",
   1885 		Progname);
   1886 
   1887 	/* same as above with 5000 byte grow and a 499990 byte tuncate */
   1888 	fprintf(stream,
   1889 		"# same as above with writes of 5000 bytes and truncs of 499990\n\
   1890 %s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n",
   1891 		Progname);
   1892 
   1893 	/* This example beats on opens and closes */
   1894 	fprintf(stream,
   1895 		"# runs forever: beats on opens and closes of file ocfile - no io\n\
   1896 %s -i 0 -g 0 -c 0 -C 0 ocfile\n\n",
   1897 		Progname);
   1898 
   1899 	fprintf(stream, "# writes 4096 to files until 50 blocks are written\n\
   1900 %s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
   1901 
   1902 	fprintf(stream,
   1903 		"# write one byte to 750 files in gdir then unlinks them\n\
   1904 %s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
   1905 
   1906 	fprintf(stream, "# run 30 secs: random iosize, random lseek up to eof\n\
   1907 %s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
   1908 
   1909 	fprintf(stream,
   1910 		"# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
   1911 %s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10  g_sleek1 g_lseek2\n\n",
   1912 		Progname);
   1913 
   1914 	fprintf(stream,
   1915 		"# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
   1916 # rand io types doing a trunc every 5 iterations, with unlinks.\n\
   1917 %s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n",
   1918 		Progname);
   1919 
   1920 	fprintf(stream,
   1921 		"# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
   1922 # random open flags, rand io types doing a trunc every 10 iterations.\n\
   1923 %s -i0 -r 1-50000 -R 0--2 -o random -I r -C0 -l -T 20 -uU100-200 -n 5 gf_rand1 gf_rand2\n",
   1924 		Progname);
   1925 
   1926 	return;
   1927 }
   1928 
   1929 /***********************************************************************
   1930  *
   1931  * The file descriptor current offset is assumed to be the end of the
   1932  * file.
   1933  * Woffset will be set to the offset before the write.
   1934  * Grow_incr will be set to the size of the write or lseek write.
   1935  ***********************************************************************/
   1936 int /* BUG:14136 */ growfile(int fd, char *file, int grow_incr, char *buf,
   1937 			     unsigned long *curr_size_ptr)
   1938 {
   1939 	off_t noffset;
   1940 	int ret;
   1941 	int cur_offset;
   1942 	char *errmsg;
   1943 	off_t fsize;		/* current size of file */
   1944 	int size_grew;		/* size the file grew */
   1945 	struct stat stbuf;
   1946 	off_t off_tmp = 0;
   1947 
   1948 	/*
   1949 	 * Do a stat on the open file.
   1950 	 * If the file is a fifo, set the bit in Mode variable.
   1951 	 * This fifo check must be done prior to growfile() returning.
   1952 	 * Also get the current size of the file.
   1953 	 */
   1954 	if (fstat(fd, &stbuf) != -1) {
   1955 		if (S_ISFIFO(stbuf.st_mode)) {
   1956 			Fileinfo.mode |= MODE_FIFO;
   1957 			Mode |= MODE_FIFO;
   1958 			if (Debug > 3)
   1959 				printf
   1960 				    ("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
   1961 				     Progname, Pid, __FILE__, __LINE__);
   1962 		}
   1963 		fsize = stbuf.st_size;
   1964 
   1965 	} else {
   1966 		fprintf(stderr,
   1967 			"%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
   1968 			Progname, TagName, Pid, __FILE__, __LINE__, fd, errno,
   1969 			strerror(errno));
   1970 
   1971 		return -1;
   1972 	}
   1973 
   1974 	if (grow_incr <= 0) {	/* don't attempt i/o if grow_incr <= 0 */
   1975 
   1976 		Grow_incr = grow_incr;
   1977 		if (Debug > 2)
   1978 			printf
   1979 			    ("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
   1980 			     Progname, Pid, __FILE__, __LINE__, grow_incr);
   1981 		return grow_incr;
   1982 	}
   1983 
   1984 	if (Mode & MODE_RAND_SIZE) {
   1985 		grow_incr =
   1986 		    random_range(min_size, max_size, mult_size, &errmsg);
   1987 		if (errmsg != NULL) {
   1988 			fprintf(stderr,
   1989 				"%s%s: %d %s/%d: random_range() failed - %s\n",
   1990 				Progname, TagName, Pid, __FILE__, __LINE__,
   1991 				errmsg);
   1992 			return -1;
   1993 		}
   1994 		Grow_incr = grow_incr;
   1995 	} else
   1996 		Grow_incr = grow_incr;
   1997 
   1998 	if (!(Mode & MODE_FIFO)) {
   1999 		if ((cur_offset = lseek(fd, 0, SEEK_CUR)) == -1) {
   2000 			fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
   2001 				Progname, TagName, Pid, __FILE__, __LINE__,
   2002 				strerror(errno));
   2003 			return -1;
   2004 		}
   2005 	}
   2006 
   2007 	if (Mode & MODE_GROW_BY_LSEEK) {
   2008 		Woffset = fsize;
   2009 		if (Debug > 2) {
   2010 			printf
   2011 			    ("%s: %d DEBUG3 %s/%d: Current size of file is %ld\n",
   2012 			     Progname, Pid, __FILE__, __LINE__, (long)Woffset);
   2013 			printf
   2014 			    ("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n",
   2015 			     Progname, Pid, __FILE__, __LINE__, grow_incr - 1);
   2016 		}
   2017 
   2018 		if ((noffset = lseek(fd, grow_incr - 1, SEEK_END)) == -1) {
   2019 			fprintf(stderr,
   2020 				"%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
   2021 				Progname, TagName, __FILE__, __LINE__,
   2022 				grow_incr - 1, strerror(errno));
   2023 			return -1;
   2024 		}
   2025 
   2026 		lkfile(fd, LOCK_EX, LKLVL0);	/* get exclusive lock */
   2027 
   2028 #if NEWIO
   2029 		ret =
   2030 		    lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg, 0);
   2031 #else
   2032 		ret = write_buffer(fd, io_type, "w", 1, 0, &errmsg);
   2033 #endif
   2034 
   2035 		if (ret != 1) {
   2036 			fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
   2037 				Progname, TagName, Pid, __FILE__, __LINE__,
   2038 				Iter_cnt, errmsg);
   2039 			if (ret == -ENOSPC) {
   2040 				cleanup();
   2041 				exit(2);
   2042 			}
   2043 		}
   2044 /***
   2045 		write(fd, "w", 1);
   2046 ****/
   2047 
   2048 		lkfile(fd, LOCK_UN, LKLVL0);
   2049 
   2050 		if (Debug > 2)
   2051 			printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
   2052 			       Progname, Pid, __FILE__, __LINE__, Iter_cnt);
   2053 
   2054 	} else {		/* end of grow by lseek */
   2055 
   2056 		if (Fileinfo.openflags & O_APPEND) {
   2057 			/*
   2058 			 * Deal with special case of the open flag containing O_APPEND.
   2059 			 * If it does, the current offset does not matter since the write
   2060 			 * will be done end of the file.
   2061 			 */
   2062 			if (Debug > 4)
   2063 				printf
   2064 				    ("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
   2065 				     Progname, Pid, __FILE__, __LINE__);
   2066 			lkfile(fd, LOCK_EX, LKLVL0);	/* get exclusive lock */
   2067 
   2068 			/*
   2069 			 * do fstat again to get size of the file.
   2070 			 * This is done inside a file lock (if locks are being used).
   2071 			 */
   2072 			if (fstat(fd, &stbuf) != -1) {
   2073 				Woffset = stbuf.st_size;
   2074 			} else {
   2075 				fprintf(stderr,
   2076 					"%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
   2077 					Progname, TagName, Pid, __FILE__,
   2078 					__LINE__, fd, errno, strerror(errno));
   2079 
   2080 				lkfile(fd, LOCK_UN, LKLVL0);	/* release lock */
   2081 				return -1;
   2082 			}
   2083 			if (Debug > 2)
   2084 				printf
   2085 				    ("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
   2086 				     Progname, Pid, __FILE__, __LINE__,
   2087 				     (int)stbuf.st_size);
   2088 
   2089 		} else if (Mode & MODE_RAND_LSEEK) {
   2090 			if (max_lseek == LSK_EOF) {	/* within file size */
   2091 				noffset =
   2092 				    random_range(min_lseek, fsize, 1, NULL);
   2093 			} else if (max_lseek == LSK_EOFPLUSGROW) {
   2094 				/* max to beyond file size */
   2095 				noffset =
   2096 				    random_range(min_lseek, fsize + grow_incr,
   2097 						 1, NULL);
   2098 			} else if (max_lseek == LSK_EOFMINUSGROW) {
   2099 				/*
   2100 				 * Attempt to not grow the file.
   2101 				 * If the i/o will fit from min_lseek to EOF,
   2102 				 * pick offset to allow it to fit.
   2103 				 * Otherwise, pick the min_lseek offset and grow
   2104 				 * file by smallest amount.
   2105 				 * If min_lseek is != 0, there will be a problem
   2106 				 * with whole file checking if file is ever smaller
   2107 				 * than min_lseek.
   2108 				 */
   2109 				if (fsize <= min_lseek + grow_incr)
   2110 					noffset = min_lseek;	/* file will still grow */
   2111 				else
   2112 					noffset =
   2113 					    random_range(min_lseek,
   2114 							 fsize - grow_incr, 1,
   2115 							 NULL);
   2116 			} else {
   2117 				noffset =
   2118 				    random_range(min_lseek, max_lseek, 1, NULL);
   2119 			}
   2120 
   2121 			if ((Woffset = lseek(fd, noffset, SEEK_SET)) == -1) {
   2122 				fprintf(stderr,
   2123 					"%s%s: %d %s/%d: lseek(%d, %ld, "
   2124 					"SEEK_SET) l2 failed: %s\n", Progname,
   2125 					TagName, Pid, __FILE__, __LINE__, fd,
   2126 					(long)noffset, strerror(errno));
   2127 				return -1;
   2128 			} else if (Debug > 2)
   2129 				printf("%s: %d DEBUG3 %s/%d: lseeked to "
   2130 				       "random offset %ld (fsz:%d)\n",
   2131 				       Progname, Pid, __FILE__, __LINE__,
   2132 				       (long)Woffset, (int)stbuf.st_size);
   2133 
   2134 		}
   2135 
   2136 		/*
   2137 		 * lseek to end of file only if not fifo
   2138 		 */
   2139 		else if (!(Mode & MODE_FIFO)) {
   2140 			if ((Woffset = lseek(fd, 0, SEEK_END)) == -1) {
   2141 				fprintf(stderr,
   2142 					"%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
   2143 					Progname, TagName, Pid, __FILE__,
   2144 					__LINE__, strerror(errno));
   2145 				return -1;
   2146 			} else if (Debug > 2)
   2147 				printf("%s: %d DEBUG3 %s/%d: lseeked to "
   2148 				       "end of file, offset %ld\n",
   2149 				       Progname, Pid, __FILE__, __LINE__,
   2150 				       (long)Woffset);
   2151 		}
   2152 
   2153 		if (Pattern == PATTERN_OFFSET)
   2154 			datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
   2155 		else if (Pattern == PATTERN_PID)
   2156 			datapidgen(Pid, buf, grow_incr, Woffset);
   2157 		else if (Pattern == PATTERN_ASCII)
   2158 			dataasciigen(NULL, buf, grow_incr, Woffset);
   2159 		else if (Pattern == PATTERN_RANDOM)
   2160 			databingen('r', buf, grow_incr, Woffset);
   2161 		else if (Pattern == PATTERN_ALT)
   2162 			databingen('a', buf, grow_incr, Woffset);
   2163 		else if (Pattern == PATTERN_CHKER)
   2164 			databingen('c', buf, grow_incr, Woffset);
   2165 		else if (Pattern == PATTERN_CNTING)
   2166 			databingen('C', buf, grow_incr, Woffset);
   2167 		else if (Pattern == PATTERN_ZEROS)
   2168 			databingen('z', buf, grow_incr, Woffset);
   2169 		else if (Pattern == PATTERN_ONES)
   2170 			databingen('o', buf, grow_incr, Woffset);
   2171 		else
   2172 			dataasciigen(NULL, buf, grow_incr, Woffset);
   2173 
   2174 		if (Debug > 2)
   2175 			printf
   2176 			    ("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
   2177 			     Progname, Pid, __FILE__, __LINE__, grow_incr);
   2178 
   2179 		lkfile(fd, LOCK_EX, LKLVL0);	/* get exclusive lock */
   2180 
   2181 /*****
   2182 		ret=write(fd, buf, grow_incr);
   2183 
   2184 		off_tmp = tell(fd);
   2185 
   2186 		lkfile(fd, LOCK_UN, LKLVL0);
   2187 
   2188 		if (ret != grow_incr) {
   2189 			fprintf(stderr, "%s: %s/%d: write failed: %s\n",
   2190 				Progname, __FILE__, __LINE__, strerror(errno));
   2191 			return -1;
   2192 		}
   2193 *****/
   2194 
   2195 #if NEWIO
   2196 		ret = lio_write_buffer(fd, io_type, buf, grow_incr,
   2197 				       SIGUSR1, &errmsg, 0);
   2198 #else
   2199 		ret = write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
   2200 #endif
   2201 
   2202 		if (Mode & MODE_FIFO) {
   2203 			/* If it is a fifo then just pretend the file
   2204 			 * offset is where we think it should be.
   2205 			 */
   2206 			off_tmp = Woffset + grow_incr;
   2207 		} else {
   2208 			if ((off_tmp = lseek(fd, 0, SEEK_CUR)) < 0) {	/* get offset after the write */
   2209 				fprintf(stderr,
   2210 					"%s%s: %s/%d: tell(2) failed: %d  %s\n",
   2211 					Progname, TagName, __FILE__, __LINE__,
   2212 					errno, strerror(errno));
   2213 				return -1;
   2214 			}
   2215 #if NEWIO
   2216 #if defined(sgi) || defined(__linux__)
   2217 			/* If this is POSIX I/O and it is via aio_{read,write}
   2218 			 * or lio_listio then after completion of the I/O the
   2219 			 * value of the file offset for the file is
   2220 			 * unspecified--which means we cannot trust what
   2221 			 * tell() told us.  Fudge it here.
   2222 			 */
   2223 			if ((io_type & LIO_IO_ASYNC_TYPES)
   2224 			    || (io_type & LIO_RANDOM)) {
   2225 				if (off_tmp != Woffset + grow_incr) {
   2226 					if (Debug > 5) {
   2227 						printf
   2228 						    ("%s: %d DEBUG6 %s/%d: posix fudge, forcing tmp (%"
   2229 						     PRId64
   2230 						     ") to match Woffset+grow_incr (%"
   2231 						     PRId64 ")\n", Progname,
   2232 						     Pid, __FILE__, __LINE__,
   2233 						     (int64_t) off_tmp,
   2234 						     (int64_t) Woffset +
   2235 						     grow_incr);
   2236 					}
   2237 					off_tmp = Woffset + grow_incr;
   2238 				}
   2239 			}
   2240 #endif /* sgi __linux__ */
   2241 #endif
   2242 		}
   2243 		*curr_size_ptr = off_tmp;	/* BUG:14136 */
   2244 
   2245 		lkfile(fd, LOCK_UN, LKLVL0);
   2246 
   2247 		if (ret != grow_incr) {
   2248 			fprintf(stderr, "%s%s: %d %s/%d: %d %s\n",
   2249 				Progname, TagName, Pid, __FILE__, __LINE__,
   2250 				Iter_cnt, errmsg);
   2251 			if (ret == -ENOSPC) {
   2252 				cleanup();
   2253 				exit(2);
   2254 			}
   2255 			return -1;
   2256 		}
   2257 
   2258 		/*
   2259 		 * Check for a condition where the file was truncated just before
   2260 		 * the write.
   2261 		 */
   2262 		if (off_tmp != Woffset + grow_incr) {
   2263 			/*
   2264 			 * The offset after the write was not as expected.
   2265 			 * This could be caused by the following:
   2266 			 *  - file truncated after the lseek and before the write.
   2267 			 *  - the file was written to after fstat and before the write
   2268 			 *    and the file was opened with O_APPEND.
   2269 			 *
   2270 			 * The pattern written to the file will be considered corrupted.
   2271 			 */
   2272 			if (Debug > 0 && lockfile) {
   2273 				printf("%s%s: %d DEBUG1 %s/%d: offset after "
   2274 				       "write(%ld) not as exp(%ld+%d=%ld)\n",
   2275 				       Progname, TagName, Pid, __FILE__,
   2276 				       __LINE__, (long)off_tmp, (long)Woffset,
   2277 				       grow_incr, (long)(Woffset + grow_incr));
   2278 				printf
   2279 				    ("%s%s: %d DEBUG1 %s/%d: %d Assuming file "
   2280 				     "changed by another process, resetting "
   2281 				     "offset:%ld (expect pattern mismatch)\n",
   2282 				     Progname, TagName, Pid, __FILE__, __LINE__,
   2283 				     Iter_cnt, (long)(off_tmp - grow_incr));
   2284 			}
   2285 			if (Debug > 4) {
   2286 				printf
   2287 				    ("%s: %d DEBUG5 %s/%d: about to chop Woffset.  "
   2288 				     "tmp=%ld, grow_incr=%d, Woffset was %ld\n",
   2289 				     Progname, Pid, __FILE__, __LINE__,
   2290 				     (long)off_tmp, grow_incr, (long)Woffset);
   2291 			}
   2292 			Woffset = off_tmp - grow_incr;
   2293 			if (Woffset < 0)
   2294 				Woffset = 0;
   2295 		}
   2296 
   2297 	}			/* end of grow by write */
   2298 
   2299 	/*
   2300 	 * Woffset - holds start of grow (start of write expect in grow by lseek)
   2301 	 * Grow_incr - holds size of grow (write).
   2302 	 * fsize - holds size of file before write
   2303 	 */
   2304 	size_grew = (Woffset + Grow_incr) - fsize;
   2305 	if (Debug > 1) {
   2306 		if (Mode & MODE_FIFO) {
   2307 			printf
   2308 			    ("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
   2309 			     Progname, Pid, __FILE__, __LINE__, Grow_incr,
   2310 			     Iter_cnt);
   2311 		}
   2312 
   2313 		else if (size_grew > 0)
   2314 			printf
   2315 			    ("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%ld), "
   2316 			     "grew file by %d bytes\n", Progname, Pid, __FILE__,
   2317 			     __LINE__, Iter_cnt, Grow_incr, (long)Woffset,
   2318 			     size_grew);
   2319 		else
   2320 			printf
   2321 			    ("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%ld), "
   2322 			     "did not grow file\n", Progname, Pid, __FILE__,
   2323 			     __LINE__, Iter_cnt, Grow_incr, (long)Woffset);
   2324 	}
   2325 
   2326 	bytes_consumed += size_grew;
   2327 	return 0;
   2328 
   2329 }				/* end of growfile */
   2330 
   2331 /***********************************************************************
   2332  * shrinkfile file by trunc_incr.  file can not be made smaller than
   2333  * size zero.  Therefore, if trunc_incr is larger than file size,
   2334  * file will be truncated to zero.
   2335  * The file descriptor current offset is assumed to be the end of the
   2336  * file.
   2337  *
   2338  ***********************************************************************/
   2339 int
   2340 shrinkfile(int fd, char *filename, int trunc_incr, int trunc_inter,
   2341 	   int just_trunc)
   2342 {
   2343 	static int shrink_cnt = 0;
   2344 	int cur_offset;
   2345 	int new_offset;
   2346 	int ret;
   2347 #ifdef CRAY
   2348 	int offset;
   2349 #endif
   2350 
   2351 	shrink_cnt++;
   2352 
   2353 	if (trunc_inter == 0 || (shrink_cnt % trunc_inter != 0)) {
   2354 		if (Debug > 3)
   2355 			printf
   2356 			    ("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
   2357 			     Progname, Pid, __FILE__, __LINE__, trunc_inter,
   2358 			     shrink_cnt);
   2359 		return 0;	/* not this time */
   2360 	}
   2361 
   2362 	if (Mode & MODE_FIFO) {
   2363 		if (Debug > 5)
   2364 			printf
   2365 			    ("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
   2366 			     Progname, Pid, __FILE__, __LINE__);
   2367 		return 0;	/* can not truncate fifo */
   2368 	}
   2369 
   2370 	lkfile(fd, LOCK_EX, LKLVL0);
   2371 
   2372 	if ((cur_offset = lseek(fd, 0, SEEK_CUR)) == -1) {
   2373 		fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
   2374 			Progname, TagName, Pid, __FILE__, __LINE__, fd,
   2375 			strerror(errno));
   2376 		lkfile(fd, LOCK_UN, LKLVL0);
   2377 		return -1;
   2378 	}
   2379 
   2380 	if (Mode & MODE_RAND_LSEEK) {
   2381 		if (max_lseek <= -1) {
   2382 			if ((new_offset = file_size(fd)) == -1) {
   2383 				lkfile(fd, LOCK_UN, LKLVL0);
   2384 				return -1;
   2385 			}
   2386 
   2387 			if (new_offset < min_lseek)
   2388 				new_offset = min_lseek;
   2389 			else
   2390 				new_offset =
   2391 				    random_range(min_lseek, new_offset, 1,
   2392 						 NULL);
   2393 		} else {
   2394 			new_offset =
   2395 			    random_range(min_lseek, max_lseek, 1, NULL);
   2396 		}
   2397 
   2398 #ifdef CRAY
   2399 		if ((offset = lseek(fd, new_offset, SEEK_SET)) == -1) {
   2400 			fprintf(stderr,
   2401 				"%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l3 failed: %s\n",
   2402 				Progname, TagName, Pid, __FILE__, __LINE__, fd,
   2403 				new_offset, strerror(errno));
   2404 			lkfile(fd, LOCK_UN, LKLVL0);
   2405 			return -1;
   2406 		} else if (Debug > 3)
   2407 			printf
   2408 			    ("%s: %d DEBUG4 %s/%d: lseeked to random offset %d\n",
   2409 			     Progname, Pid, __FILE__, __LINE__, offset);
   2410 
   2411 #endif
   2412 	}
   2413 
   2414 	else {			/* remove trunc_incr from file */
   2415 
   2416 		new_offset = cur_offset - trunc_incr;
   2417 
   2418 		if (new_offset < 0)
   2419 			new_offset = 0;
   2420 
   2421 #ifdef CRAY
   2422 		if (lseek(fd, new_offset, SEEK_SET) == -1) {
   2423 			fprintf(stderr,
   2424 				"%s%s: %d %s/%d: lseek(fd, %d, SEEK_SET) l4 failed: %s\n",
   2425 				Progname, TagName, Pid, __FILE__, __LINE__,
   2426 				new_offset, strerror(errno));
   2427 			lkfile(fd, LOCK_UN, LKLVL0);
   2428 			return -1;
   2429 		} else if (Debug > 3)
   2430 			printf
   2431 			    ("%s: %d DEBUG4 %s/%d: lseeked to offset %d, %d bytes from end\n",
   2432 			     Progname, Pid, __FILE__, __LINE__, new_offset,
   2433 			     trunc_incr);
   2434 #endif
   2435 	}
   2436 
   2437 #ifdef CRAY
   2438 	ret = trunc(fd);
   2439 #else
   2440 	ret = ftruncate(fd, new_offset);
   2441 	if (ret == 0 && Debug > 3) {
   2442 		printf
   2443 		    ("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
   2444 		     Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
   2445 	}
   2446 #endif
   2447 
   2448 	lkfile(fd, LOCK_UN, LKLVL0);
   2449 
   2450 	if (ret == -1) {
   2451 #ifdef CRAY
   2452 		fprintf(stderr, "%s%s: %d %s/%d: trunc failed: %s\n",
   2453 			Progname, TagName, Pid, __FILE__, __LINE__,
   2454 			strerror(errno));
   2455 #else
   2456 		fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
   2457 			Progname, TagName, Pid, __FILE__, __LINE__,
   2458 			strerror(errno));
   2459 #endif
   2460 		return -1;
   2461 	}
   2462 
   2463 	if (Debug > 2) {
   2464 		printf
   2465 		    ("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
   2466 		     Progname, Pid, __FILE__, __LINE__, cur_offset - new_offset,
   2467 		     new_offset);
   2468 	}
   2469 
   2470 	bytes_consumed -= (cur_offset - new_offset);
   2471 	return 0;
   2472 
   2473 }				/* end of shrinkfile */
   2474 
   2475 /***********************************************************************
   2476  *
   2477  ***********************************************************************/
   2478 int check_write(int fd, int cf_inter, char *filename, int mode)
   2479 {
   2480 	int fsize;
   2481 	static int cf_count = 0;
   2482 	int ret = 0;
   2483 	int tmp;
   2484 	char *errmsg;
   2485 	char *ptr;
   2486 
   2487 	cf_count++;
   2488 
   2489 	if (cf_inter == 0 || (cf_count % cf_inter != 0)) {
   2490 		if (Debug > 4)
   2491 			printf
   2492 			    ("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
   2493 			     Progname, Pid, __FILE__, __LINE__, cf_inter,
   2494 			     cf_count);
   2495 		return 0;	/* no check done */
   2496 	}
   2497 
   2498 	if (Grow_incr <= 0) {
   2499 		if (Debug > 3)
   2500 			printf("%s: %d DEBUG4 %s/%d: No write validation,  "
   2501 			       "Grow_incr = %d, offset = %ld\n",
   2502 			       Progname, Pid, __FILE__, __LINE__, Grow_incr,
   2503 			       (long)Woffset);
   2504 		return 0;	/* no check */
   2505 	}
   2506 
   2507 	/*
   2508 	 * Get the shared file lock.  We need to hold the lock from before
   2509 	 * we do the stat until after the read.
   2510 	 */
   2511 	lkfile(fd, LOCK_SH, LKLVL0);
   2512 
   2513 	if ((fsize = file_size(fd)) == -1) {
   2514 		lkfile(fd, LOCK_UN, LKLVL0);
   2515 		return -1;
   2516 
   2517 	} else if (fsize <= Woffset) {
   2518 		/*
   2519 		 * The file was truncated between write and now.
   2520 		 * The contents of our last write is totally gone, no check.
   2521 		 */
   2522 		if (Debug > 1)
   2523 			printf
   2524 			    ("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than "
   2525 			     "where last wrote (%ld)- no write validation\n",
   2526 			     Progname, TagName, Pid, __FILE__, __LINE__,
   2527 			     Iter_cnt, fsize, (long)Woffset);
   2528 		lkfile(fd, LOCK_UN, LKLVL0);
   2529 		return 0;	/* no validation, but not an error */
   2530 
   2531 	} else if (fsize < (Woffset + Grow_incr)) {
   2532 		/*
   2533 		 * The file was truncated between write and now.
   2534 		 * Part of our last write has been truncated, adjust our Grow_incr
   2535 		 * to reflect this.
   2536 		 */
   2537 
   2538 		tmp = Grow_incr;
   2539 		Grow_incr = fsize - Woffset;
   2540 
   2541 		if (Debug > 1) {
   2542 
   2543 			printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of "
   2544 			       "wrt(off:%ld, sz:%d), adj=%d\n", Progname,
   2545 			       TagName, Pid, __FILE__, __LINE__, Iter_cnt,
   2546 			       fsize, tmp - Grow_incr, (long)Woffset, tmp,
   2547 			       Grow_incr);
   2548 		}
   2549 
   2550 	}
   2551 
   2552 	if (Debug > 2)
   2553 		printf("%s: %d DEBUG3 %s/%d: about to do write validation, "
   2554 		       "offset = %ld, size = %d\n",
   2555 		       Progname, Pid, __FILE__, __LINE__, (long)Woffset,
   2556 		       Grow_incr);
   2557 
   2558 	if (!(mode & MODE_FIFO)) {
   2559 
   2560 		if (lseek(fd, Woffset, 0) == -1) {
   2561 			fprintf(stderr,
   2562 				"%s%s: %d %s/%d: lseek(fd, %ld, 0) failed: %s\n",
   2563 				Progname, TagName, Pid, __FILE__, __LINE__,
   2564 				(long)Woffset, strerror(errno));
   2565 		}
   2566 		if (Debug > 3)
   2567 			printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%ld\n",
   2568 			       Progname, Pid, __FILE__, __LINE__,
   2569 			       (long)Woffset);
   2570 	}
   2571 
   2572 	/*
   2573 	 * Read last writes data
   2574 	 */
   2575 #if NEWIO
   2576 	ret =
   2577 	    lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,
   2578 			    0);
   2579 #else
   2580 	ret = read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
   2581 #endif
   2582 
   2583 	/*
   2584 	 * report the error and debug information before releasing
   2585 	 * the file lock
   2586 	 */
   2587 	if (ret != Grow_incr) {
   2588 		fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName,
   2589 			Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
   2590 		{
   2591 			struct stat stbuf;
   2592 			fstat(fd, &stbuf);
   2593 			if (Debug > 2)
   2594 				printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n", Progname, TagName, Pid, __FILE__, __LINE__, fd, (int)lseek(fd, SEEK_CUR, 0),	/* FIXME: 64bit/LFS ? */
   2595 				       (int)stbuf.st_size, Fileinfo.openflags);
   2596 		}
   2597 
   2598 		lkfile(fd, LOCK_UN, LKLVL0);
   2599 		return 1;
   2600 	}
   2601 
   2602 	lkfile(fd, LOCK_UN, LKLVL0);
   2603 
   2604 	if (Mode & MODE_GROW_BY_LSEEK) {
   2605 		/* check that all zeros upto last character */
   2606 		for (ptr = Buffer; ptr < (Buffer + Grow_incr - 1); ptr++) {
   2607 			if (*ptr != '\0') {
   2608 				fprintf(stderr,
   2609 					"%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
   2610 					Progname, TagName, Pid, __FILE__,
   2611 					__LINE__,
   2612 					(int)(Woffset +
   2613 					      (Grow_incr - (Buffer - ptr))), 0,
   2614 					*ptr, filename);
   2615 				fflush(stderr);
   2616 				return 1;
   2617 			}
   2618 		}
   2619 		/* check that the last char is a 'w' */
   2620 		if (*ptr != 'w') {
   2621 			fprintf(stderr,
   2622 				"%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
   2623 				Progname, TagName, Pid, __FILE__, __LINE__,
   2624 				(int)(Woffset + (Grow_incr - (Buffer - ptr))),
   2625 				'w', *ptr, filename);
   2626 			fflush(stderr);
   2627 			return 1;
   2628 		}
   2629 		return 0;	/* all is well */
   2630 
   2631 	} else if (Pattern == PATTERN_OFFSET)
   2632 		ret =
   2633 		    datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
   2634 	else if (Pattern == PATTERN_PID)
   2635 		ret = datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
   2636 	else if (Pattern == PATTERN_ASCII)
   2637 		ret = dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
   2638 	else if (Pattern == PATTERN_RANDOM) ;	/* no check for random */
   2639 	else if (Pattern == PATTERN_ALT)
   2640 		ret = databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
   2641 	else if (Pattern == PATTERN_CHKER)
   2642 		ret = databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
   2643 	else if (Pattern == PATTERN_CNTING)
   2644 		ret = databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
   2645 	else if (Pattern == PATTERN_ZEROS)
   2646 		ret = databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
   2647 	else if (Pattern == PATTERN_ONES)
   2648 		ret = databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
   2649 	else
   2650 		ret = dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
   2651 
   2652 	if (ret >= 0) {
   2653 		fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
   2654 			Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt,
   2655 			errmsg, filename);
   2656 
   2657 		if (Debug > 0)
   2658 			printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, "
   2659 			       "offset:%ld, sz:%d open flags:%#o %s\n",
   2660 			       Progname, TagName, Pid, __FILE__, __LINE__, fd,
   2661 			       lockfile, (long)Woffset, Grow_incr,
   2662 			       Fileinfo.openflags,
   2663 			       openflags2symbols(Fileinfo.openflags, ",", 0));
   2664 
   2665 		fflush(stderr);
   2666 		return 1;
   2667 	}
   2668 
   2669 	if (Debug > 6)
   2670 		printf("%s: %d DEBUG7 %s/%d: No corruption detected on "
   2671 		       "write validation , offset = %ld, size = %d\n",
   2672 		       Progname, Pid, __FILE__, __LINE__, (long)Woffset,
   2673 		       Grow_incr);
   2674 
   2675 	return 0;		/* all is well */
   2676 }
   2677 
   2678 /***********************************************************************
   2679  *
   2680  ***********************************************************************/
   2681 int check_file(int fd, int cf_inter, char *filename, int no_file_check)
   2682 {
   2683 	int fsize;
   2684 	static int cf_count = 0;
   2685 	char *buf;
   2686 	int ret;
   2687 	int ret_val = 0;
   2688 	int rd_cnt;
   2689 	int rd_size;
   2690 	char *errmsg;
   2691 
   2692 	cf_count++;
   2693 
   2694 	if (cf_inter == 0 || (cf_count % cf_inter != 0)) {
   2695 		if (Debug > 4)
   2696 			printf
   2697 			    ("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
   2698 			     Progname, Pid, __FILE__, __LINE__, cf_inter,
   2699 			     cf_count);
   2700 		return 0;	/* no check done */
   2701 	}
   2702 
   2703 	/*
   2704 	 * if we can't determine file content, don't bother checking
   2705 	 */
   2706 	if (no_file_check) {
   2707 		if (Debug > 4)
   2708 			printf
   2709 			    ("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
   2710 			     Progname, Pid, __FILE__, __LINE__);
   2711 		return 0;
   2712 	}
   2713 
   2714 	/*
   2715 	 * Lock the file.  We need to have the file lock before
   2716 	 * the stat and until after the last read to prevent
   2717 	 * a trunc/truncate from "corrupting" our data.
   2718 	 */
   2719 	lkfile(fd, LOCK_SH, LKLVL0);
   2720 
   2721 	if ((fsize = file_size(fd)) == -1) {
   2722 		lkfile(fd, LOCK_UN, LKLVL0);
   2723 		return -1;
   2724 	}
   2725 
   2726 	if (fsize == 0) {
   2727 		if (Debug > 2)
   2728 			printf
   2729 			    ("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
   2730 			     Progname, Pid, __FILE__, __LINE__);
   2731 
   2732 		lkfile(fd, LOCK_UN, LKLVL0);
   2733 		return 0;
   2734 	}
   2735 
   2736 	if (Debug > 2)
   2737 		printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
   2738 		       Progname, Pid, __FILE__, __LINE__);
   2739 
   2740 	if (fsize > MAX_FC_READ) {
   2741 		/*
   2742 		 * read the file in MAX_FC_READ chuncks.
   2743 		 */
   2744 
   2745 		if ((buf = malloc(MAX_FC_READ)) == NULL) {
   2746 			fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n",
   2747 				Progname, TagName, __FILE__, __LINE__,
   2748 				MAX_FC_READ, strerror(errno));
   2749 			lkfile(fd, LOCK_UN, LKLVL0);
   2750 			return -1;
   2751 		}
   2752 
   2753 		lseek(fd, 0, SEEK_SET);
   2754 
   2755 		lkfile(fd, LOCK_SH, LKLVL0);	/* get lock on file before getting file size */
   2756 
   2757 		rd_cnt = 0;
   2758 		while (rd_cnt < fsize) {
   2759 			rd_size = MIN(MAX_FC_READ, fsize - rd_cnt);
   2760 
   2761 #if NEWIO
   2762 			ret = lio_read_buffer(fd, io_type, buf, rd_size,
   2763 					      SIGUSR1, &errmsg, 0);
   2764 #else
   2765 			ret =
   2766 			    read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
   2767 #endif
   2768 
   2769 			if (ret != rd_size) {
   2770 				fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n",
   2771 					Progname, TagName, Pid, __FILE__,
   2772 					__LINE__, Iter_cnt, errmsg);
   2773 				free(buf);
   2774 				lkfile(fd, LOCK_UN, LKLVL0);
   2775 				return -1;
   2776 			}
   2777 /**
   2778 	        read(fd, buf, rd_size);
   2779 ***/
   2780 
   2781 			if (Pattern == PATTERN_OFFSET)
   2782 				ret =
   2783 				    datapidchk(STATIC_NUM, buf, rd_size, rd_cnt,
   2784 					       &errmsg);
   2785 			else if (Pattern == PATTERN_PID)
   2786 				ret =
   2787 				    datapidchk(Pid, buf, rd_size, rd_cnt,
   2788 					       &errmsg);
   2789 			else if (Pattern == PATTERN_ASCII)
   2790 				ret =
   2791 				    dataasciichk(NULL, buf, rd_size, rd_cnt,
   2792 						 &errmsg);
   2793 			else if (Pattern == PATTERN_RANDOM) ;	/* no checks for random */
   2794 			else if (Pattern == PATTERN_ALT)
   2795 				ret =
   2796 				    databinchk('a', buf, rd_size, rd_cnt,
   2797 					       &errmsg);
   2798 			else if (Pattern == PATTERN_CHKER)
   2799 				ret =
   2800 				    databinchk('c', buf, rd_size, rd_cnt,
   2801 					       &errmsg);
   2802 			else if (Pattern == PATTERN_CNTING)
   2803 				ret =
   2804 				    databinchk('C', buf, rd_size, rd_cnt,
   2805 					       &errmsg);
   2806 			else if (Pattern == PATTERN_ZEROS)
   2807 				ret =
   2808 				    databinchk('z', buf, rd_size, rd_cnt,
   2809 					       &errmsg);
   2810 			else if (Pattern == PATTERN_ONES)
   2811 				ret =
   2812 				    databinchk('o', buf, rd_size, rd_cnt,
   2813 					       &errmsg);
   2814 			else
   2815 				ret =
   2816 				    dataasciichk(NULL, buf, rd_size, rd_cnt,
   2817 						 &errmsg);
   2818 
   2819 			if (ret >= 0) {
   2820 				fprintf(stderr,
   2821 					"%s%s: %d %s/%d: %d CFp %s in file %s\n",
   2822 					Progname, TagName, Pid, __FILE__,
   2823 					__LINE__, Iter_cnt, errmsg, filename);
   2824 				fflush(stderr);
   2825 				ret_val = 1;
   2826 				lkfile(fd, LOCK_UN, LKLVL0);
   2827 				break;
   2828 			}
   2829 			rd_cnt += rd_size;
   2830 		}
   2831 
   2832 		lkfile(fd, LOCK_UN, LKLVL0);
   2833 
   2834 		free(buf);
   2835 
   2836 	} else {
   2837 		/*
   2838 		 * Read the whole file in a single read
   2839 		 */
   2840 		if ((buf = malloc(fsize)) == NULL) {
   2841 			fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n",
   2842 				Progname, TagName, __FILE__, __LINE__, fsize,
   2843 				strerror(errno));
   2844 			fflush(stderr);
   2845 			return -1;
   2846 		}
   2847 
   2848 		lseek(fd, 0, SEEK_SET);
   2849 
   2850 /****
   2851 	    read(fd, buf, fsize);
   2852 ****/
   2853 #if NEWIO
   2854 		ret =
   2855 		    lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,
   2856 				    0);
   2857 #else
   2858 		ret = read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
   2859 #endif
   2860 
   2861 		/* unlock the file as soon as we can */
   2862 		lkfile(fd, LOCK_UN, LKLVL0);
   2863 
   2864 		if (ret != fsize) {
   2865 			fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n",
   2866 				Progname, TagName, Pid, __FILE__, __LINE__,
   2867 				Iter_cnt, errmsg);
   2868 			ret_val = 1;
   2869 		} else {
   2870 			if (Pattern == PATTERN_OFFSET)
   2871 				ret =
   2872 				    datapidchk(STATIC_NUM, buf, fsize, 0,
   2873 					       &errmsg);
   2874 			else if (Pattern == PATTERN_PID)
   2875 				ret = datapidchk(Pid, buf, fsize, 0, &errmsg);
   2876 			else if (Pattern == PATTERN_ASCII)
   2877 				ret =
   2878 				    dataasciichk(NULL, buf, fsize, 0, &errmsg);
   2879 			else if (Pattern == PATTERN_RANDOM) ;	/* no check for random */
   2880 			else if (Pattern == PATTERN_ALT)
   2881 				ret = databinchk('a', buf, fsize, 0, &errmsg);
   2882 			else if (Pattern == PATTERN_CHKER)
   2883 				ret = databinchk('c', buf, fsize, 0, &errmsg);
   2884 			else if (Pattern == PATTERN_CNTING)
   2885 				ret = databinchk('C', buf, fsize, 0, &errmsg);
   2886 			else if (Pattern == PATTERN_ZEROS)
   2887 				ret = databinchk('z', buf, fsize, 0, &errmsg);
   2888 			else if (Pattern == PATTERN_ONES)
   2889 				ret = databinchk('o', buf, fsize, 0, &errmsg);
   2890 			else
   2891 				ret =
   2892 				    dataasciichk(NULL, buf, fsize, 0, &errmsg);
   2893 
   2894 			if (ret >= 0) {
   2895 				fprintf(stderr,
   2896 					"%s%s: %d %s/%d: %d CFw %s in file %s\n",
   2897 					Progname, TagName, Pid, __FILE__,
   2898 					__LINE__, Iter_cnt, errmsg, filename);
   2899 				fflush(stderr);
   2900 				ret_val = 1;
   2901 			}
   2902 		}
   2903 		free(buf);
   2904 	}
   2905 
   2906 	return ret_val;
   2907 
   2908 }				/* end of check_file */
   2909 
   2910 /***********************************************************************
   2911  *
   2912  ***********************************************************************/
   2913 int file_size(int fd)
   2914 {
   2915 	struct stat sb;
   2916 
   2917 	if (fstat(fd, &sb) < 0) {
   2918 		fprintf(stderr,
   2919 			"%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
   2920 			Progname, TagName, Pid, __FILE__, __LINE__, fd, errno,
   2921 			strerror(errno));
   2922 		return -1;
   2923 
   2924 	}
   2925 
   2926 	return sb.st_size;
   2927 }
   2928 
   2929 /***********************************************************************
   2930  *  do file lock/unlock action.
   2931  ***********************************************************************/
   2932 int lkfile(int fd, int operation, int lklevel)
   2933 {
   2934 	char *errmsg;
   2935 
   2936 	if (lockfile == lklevel) {
   2937 
   2938 		if (Debug > 5) {
   2939 			switch (operation) {
   2940 			case LOCK_UN:
   2941 				printf
   2942 				    ("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n",
   2943 				     Progname, Pid, __FILE__, __LINE__, fd);
   2944 				break;
   2945 
   2946 			case LOCK_SH:
   2947 				printf
   2948 				    ("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n",
   2949 				     Progname, Pid, __FILE__, __LINE__, fd);
   2950 				break;
   2951 
   2952 			case LOCK_EX:
   2953 				printf
   2954 				    ("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n",
   2955 				     Progname, Pid, __FILE__, __LINE__, fd);
   2956 				break;
   2957 			}
   2958 		}
   2959 
   2960 		/*
   2961 		 * Attempt to get/release desired lock.
   2962 		 * file_lock will attempt to do action over and over again until
   2963 		 * either an unretryable error or the action is completed.
   2964 		 */
   2965 
   2966 		if (file_lock(fd, operation, &errmsg) != 0) {
   2967 			printf
   2968 			    ("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
   2969 			     Progname, TagName, Pid, __FILE__, __LINE__,
   2970 			     errmsg);
   2971 
   2972 			/* do we count this as an error? handle_error();  */
   2973 			return -1;
   2974 		}
   2975 
   2976 		if (Debug > 2) {
   2977 			switch (operation) {
   2978 			case LOCK_UN:
   2979 				printf
   2980 				    ("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n",
   2981 				     Progname, Pid, __FILE__, __LINE__, fd);
   2982 				break;
   2983 
   2984 			case LOCK_SH:
   2985 				printf
   2986 				    ("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n",
   2987 				     Progname, Pid, __FILE__, __LINE__, fd);
   2988 				break;
   2989 
   2990 			case LOCK_EX:
   2991 				printf
   2992 				    ("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n",
   2993 				     Progname, Pid, __FILE__, __LINE__, fd);
   2994 				break;
   2995 
   2996 			default:
   2997 				printf
   2998 				    ("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n",
   2999 				     Progname, Pid, __FILE__, __LINE__,
   3000 				     operation, fd);
   3001 				break;
   3002 			}
   3003 		}
   3004 	}
   3005 
   3006 	return 0;
   3007 }
   3008 
   3009 #ifndef linux
   3010 /***********************************************************************
   3011  *
   3012  ***********************************************************************/
   3013 int pre_alloc(int fd, long size)
   3014 {
   3015 
   3016 #ifdef CRAY
   3017 	long avl;
   3018 
   3019 	if (ialloc(fd, size, IA_CONT, &avl) == -1) {
   3020 		fprintf(stderr,
   3021 			"%s%s %s/%d: Unable to pre-alloc space: ialloc failed: %d  %s\n",
   3022 			Progname, TagName, __FILE__, __LINE__, errno,
   3023 			strerror(errno));
   3024 		return -1;
   3025 	}
   3026 #endif
   3027 
   3028 #ifdef sgi
   3029 	struct flock f;
   3030 
   3031 	f.l_whence = 0;
   3032 	f.l_start = 0;
   3033 	f.l_len = size;
   3034 
   3035 	/* non-zeroing reservation */
   3036 	if (fcntl(fd, F_RESVSP, &f) == -1) {
   3037 		fprintf(stderr,
   3038 			"%s%s %s/%d: Unable to pre-alloc space: fcntl(F_RESVSP) failed: %d  %s\n",
   3039 			Progname, TagName, __FILE__, __LINE__, errno,
   3040 			strerror(errno));
   3041 		return -1;
   3042 	}
   3043 #endif
   3044 
   3045 	return 0;
   3046 }
   3047 #endif
   3048