Diff of /doio/growfiles.c [000000] .. [b973f2] Maximize Restore

  Switch to side-by-side view

--- a
+++ b/doio/growfiles.c
@@ -0,0 +1,2813 @@
+/*
+ * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
+ */
+/*
+ * This program will grow a list of files.
+ * Each file will grow by grow_incr before the same
+ * file grows twice.  Each file is open and closed before next file is opened.
+ *
+ * To just verify file contents: growfiles -g 0 -c 1 filename
+ *
+ * See help and prt_examples functions below.
+ *
+ * Basic code layout
+ *  process cmdline 
+ *  print debug message about options used
+ *  setup signal handlers
+ *  return control to user (if wanted - default action)
+ *  fork number of desired childern (if wanted)
+ *  re-exec self (if wanted)
+ *  Determine number of files
+ *  malloc space or i/o buffer
+ *  Loop until stop is set
+ *    Determine if hit iteration, time, max errors or num bytes reached
+ *    Loop through each file
+ *	open file
+ *	fstat file - to determine if file if a fifo
+ *	prealloc file space (if wanted)
+ *      growfile
+ *	check last write
+ *	check whole file
+ *	shrink file
+ *	close file
+ *	delay (if wanted)
+ *    End loop
+ *  End loop
+ *  remove all files (if wanted)
+ *
+ * Author: Richard Logan
+ *
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/file.h>
+#include <sys/unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <errno.h>
+#include <string.h>
+#include "dataascii.h"
+#include "random_range.h"
+
+#ifdef CRAY
+#include <sys/panic.h>
+#include <sys/category.h>
+#endif
+
+extern int errno;
+
+extern char *openflags2symbols();
+
+extern int parse_open_flags();
+extern int background();
+extern int forker();
+extern int datapidgen();
+extern void databingen();
+extern int datapidchk();
+extern int databinchk();
+extern int file_lock();
+
+int file_size();
+int check_write();
+int shrinkfile();
+int check_file();
+int growfile();
+int cleanup();
+int handle_error();
+int lkfile();
+void usage();
+void help();
+void prt_examples();
+int set_sig();
+void sig_handler();
+static void notify_others();
+#ifndef linux
+int pre_alloc();
+#endif
+
+
+#define NEWIO	1	/* Use the tlibio.c functions */
+
+#ifndef NEWIO
+#define NEWIO	0	/* specifies to use original iowrite.c */
+			/* functions instead of tlibio.c functions */
+			/* Once it is proven tlibio.c functions work properly, */
+			/* only tlibio.c functions will be used */
+#else
+#include "tlibio.h"
+#endif
+
+#ifndef PATH_MAX
+#define PATH_MAX	1023
+#endif
+
+
+#define DEF_DIR		"."
+#define DEF_FILE	"gf"
+
+char *Progname;
+int Debug  = 1;
+
+int Pid=0;
+
+int io_type = 0;			/* I/O type -sync */
+int open_flags = O_RDWR|O_CREAT;	/* open flags */
+
+#define MAX_FC_READ	196608		/* 4096 * 48 - 48 blocks */
+
+#define PATTERN_ASCII	1	/* repeating alphabet letter pattern */
+				/* allows multiple writers and to be checked */
+#define PATTERN_PID	2	/* <pid><words byte offset><pid> */
+				/* Assumes 64 bit word. Only allows single */
+				/* process to write and check */
+/*
+ *	1234567890123456789012345678901234567890123456789012345678901234
+ *	________________________________________________________________
+ *	<    pid       >< offset in file of this word  ><    pid       >
+ */
+	
+#define PATTERN_OFFSET	3	/* Like PATTERN_PID but has a fixed number */
+				/* (STATIC_NUM) instead of pid. */
+				/* Allows multiple processes to write/read */
+#define PATTERN_ALT	4	/* alternating bit pattern (i.e. 0x5555555...) */
+#define PATTERN_CHKER	5	/* checkerboard pattern (i.e. 0xff00ff00ff00...) */
+#define PATTERN_CNTING  6	/* counting pattern (i.e. 0 - 07, 0 - 07, ...) */
+#define PATTERN_ONES	7	/* all bits set (i.e. 0xffffffffffffff...) */
+#define PATTERN_ZEROS	8	/* all bits cleared (i.e. 0x000000000...) */
+#define PATTERN_RANDOM	9	/* random integers - can not be checked */
+#define STATIC_NUM	221849	/* used instead of pid when PATTERN_OFFSET */
+
+#define MODE_RAND_SIZE	1	/* random write and trunc */
+#define MODE_RAND_LSEEK	2	/* random lseek before write */
+#define MODE_GROW_BY_LSEEK 4	/* lseek beyond end of file then write a byte */
+#define RANDOM_OPEN	999876	/* if Open_flags set to this value, open flags */
+				/* will be randomly choosen from Open_flags[] */
+#define MODE_FIFO	S_IFIFO	/* defined in stat.h  0010000 */
+
+int num_files = 0;		/* num_auto_files + cmd line files */
+char *filenames;		/* pointer to space containing filenames */
+int remove_files = 0;		/* if set, cleanup default is not to cleanup */
+int bytes_consumed = 0;		/* total bytes consumed, all files */
+int bytes_to_consume = 0;   	/* non-zero if -B was specified, total bytes */
+int Maxerrs = 100;		/* Max number errors before forced exit */
+int Errors = 0;			/* number of encountered errors */
+int Upanic_on_error = 0;	/* call upanic if error and this variable set */
+
+/* The *_size variables are only used when random iosize option (-r) is used */
+int max_size=5000;
+int min_size=1;			/* also set in option parsing */
+int mult_size=1;		/* when random iosz, iosz must be mult of mult_size */
+/* the *_lseek variables are only used when radon lseek option (-R) is used */
+int min_lseek=0;		/* also set in option parsing */
+int max_lseek=-1;		/* -1 means size of file */
+#ifdef CRAY
+int Pattern=PATTERN_OFFSET;	/* This pattern is 64 bit word based */
+#else
+int Pattern=PATTERN_ASCII;
+#endif
+int Seed=-1;			/* random number seed, < 0 == uninitialized  */
+int Nseeds=0;			/* Number of seed specified by the user */
+int *Seeds;			/* malloc'ed arrary of ints holding user spec seeds */
+
+int using_random=0;		/* flag indicating randomization is being used */
+float delaysecs=0.0;		/* delay between iterations (in seconds) */
+int delaytime;			/* delay between iterations in clocks/uses */
+int lockfile=0;			/* if set, do file locking */
+				/* 1 = do file locking around write, trunc */
+				/* and reads. */
+				/* 2 = write lock around all file operations */
+
+int Woffset=0;			/* offset before last write */
+int Grow_incr=4096;		/* sz of last write */
+int Mode=0;			/* bitmask of write/trunc mode */
+				/* also knows if dealing with fifo */
+char *Buffer = NULL;		/* buffer used by write and write check */
+int Alignment=0;		/* if non word multiple, io will not be word aligned */
+int Opid=0;			/* original pid */
+
+int Sync_with_others = 0;	/* Flag indicating to stop other if we stop before DONE */
+int Iter_cnt = 0;		/* contains current iteration count value */
+char	TagName[40];		/* name of this growfiles (see Monster)	    */
+
+struct fileinfo_t {
+    char *filename;
+    int fd;
+    int openflags;
+    int mode;
+}  Fileinfo;
+
+/*
+ * Define open flags that will be used when '-o random' option is used.
+ * Note: If there is more than one growfiles doing its thing to the same
+ * file, O_TRUNC will cause data mismatches.  How you ask?
+ * timing of events, example:
+ *   Process one		Process two
+ *   ---------------		-------------
+ *   get write lock
+ *   fstat file
+ *   lseek
+ *   generate pattern
+ *				open with O_TRUNC 
+ *   write with wrong pattern
+ *	because offset is wrong
+ *
+ *  The second process truncated the file after the pattern was
+ *  determined, thus the pattern is wrong for the file location.
+ *
+ * There can also be a timing problem with open flag O_APPEND if
+ * file locks are not being used (-l option).  Things could happen
+ * between the fstat and the write. Thus, writing the wrong pattern.
+ * If all processes observe the file locks, O_APPEND should be ok
+ * to use.
+ */
+int Open_flags[] = { 
+#ifdef CRAY
+	O_RDWR|O_CREAT,
+	O_RDWR|O_CREAT|O_RAW,
+	O_RDWR|O_CREAT|O_BIG,
+	O_RDWR|O_CREAT|O_APPEND,
+	O_RDWR|O_CREAT|O_NDELAY,
+	O_RDWR|O_CREAT|O_PLACE,
+	O_RDWR|O_CREAT|O_SYNC,
+	O_RDWR|O_CREAT|O_RAW|O_SYNC,
+	O_RDWR|O_CREAT|O_NDELAY|O_SYNC,
+	O_RDWR|O_CREAT|O_NDELAY|O_SYNC|O_BIG,
+	O_RDWR|O_CREAT|O_RAW,
+	O_RDWR|O_CREAT|O_RAW|O_APPEND,
+	O_RDWR|O_CREAT|O_RAW|O_BIG,
+	O_RDWR|O_CREAT|O_RAW|O_APPEND|O_BIG,
+/***
+ * O_WELLFORMED makes -o random require well formed i/o
+ ***/
+#if ALLOW_O_WELLFORMED
+#if O_PARALLEL
+	O_RDWR|O_CREAT|O_PARALLEL|O_WELLFORMED|O_RAW,
+	O_RDWR|O_CREAT|O_PARALLEL|O_WELLFORMED|O_RAW|O_TRUNC,
+#endif /* O_PARALLEL */
+#endif
+
+#else /* CRAY */
+	O_RDWR|O_CREAT,
+	O_RDWR|O_CREAT|O_APPEND,
+	O_RDWR|O_CREAT|O_NDELAY,
+	O_RDWR|O_CREAT|O_SYNC,
+	O_RDWR|O_CREAT|O_SYNC|O_NDELAY,
+	O_RDWR|O_CREAT|O_APPEND|O_NDELAY,
+
+#endif /* CRAY */
+};
+
+#define REXEC_INIT	0	/* don't do re-exec of childern */
+#define REXEC_DOIT	1	/* Do re-exec of childern */
+#define REXEC_DONE	2	/* We've already been re-exec'ed */
+
+#ifndef BSIZE
+#ifdef CRAY
+#define BSIZE	1024
+#else
+#define BSIZE	512
+#endif  /* CRAY */
+#endif  /* BSIZE */
+
+#define USECS_PER_SEC	1000000  /* microseconds per second */
+
+/*
+ * Define marcos used when dealing with file locks.
+ */
+#define LKLVL0		1	/* file lock around write/read/trunc */
+#define LKLVL1		2	/* file lock after open to before close */
+
+/*
+ * Define special max lseek values
+ */
+#define LSK_EOF       	    -1	/* set fptr up to EOF */
+#define LSK_EOFPLUSGROW	    -2	/* set fptr up to EOF + grow - leave whole */
+#define LSK_EOFMINUSGROW    -3	/* set fptr up to EOF-grow - no grow */
+
+
+/***********************************************************************
+ * MAIN
+ ***********************************************************************/
+int
+main(argc, argv)
+int argc;
+char **argv;
+{
+extern char *optarg;            /* used by getopt */
+extern int optind;
+extern int opterr;
+
+int ind;
+int first_file_ind = 0;
+int num_auto_files = 0;		/* files created by tool */
+int seq_auto_files = 0;		/* auto files created by tool created by tool */
+char *auto_dir = DEF_DIR;
+char *auto_file = DEF_FILE;
+int grow_incr = 4096;
+int trunc_incr = 4096;
+int trunc_inter = 0;		/* 0 means none, */
+int unlink_inter = 0;		/* 0 means none, 1 means always unlink */
+int unlink_inter_ran = -1;	/* -1 -use unlink_inter, otherwise randomly choose */
+				/* between unlink_inter and unlink_inter_ran */
+int file_check_inter = 0;	/* 0 means never, 1 means always */
+int write_check_inter = 1;	/* 0 means never, 1 means always */
+int iterations = 1;		/* number of increments to be added */
+int no_file_check = 0;		/* if set, no whole file checking will be done */
+int num;
+int fd;				/* file descriptor */
+int stop = 0;			/* loop stopper if set */
+int tmp;
+char chr;
+int ret;
+int pre_alloc_space = 0;
+#ifndef linux
+int total_grow_value;		/* used in pre-allocations */
+#endif
+int backgrnd = 1;		/* return control to user */
+struct stat statbuf;
+int time_iterval = -1;
+time_t start_time;
+char reason[40];		/* reason for loop termination */
+int num_procs=1;
+int forker_mode=0;
+int reexec=REXEC_INIT;		/* reexec info */
+char *exec_path=NULL;
+
+char *strrchr();
+
+char *filename;                 /* name of file specified by user */
+char *cptr;			/* temp char pointer */
+extern int Forker_npids;	/* num of forked pid, defined in forker.c */
+
+
+	if ( argv[0][0] == '-' )
+	   reexec=REXEC_DONE;
+	/*
+	 * Determine name of file used to invoke this program
+	 */
+	if ((Progname=strrchr(argv[0], '/')) != NULL)
+		Progname++;
+	else
+		Progname=argv[0];
+
+	TagName[0] = '\0';
+
+	/*
+	 * Process options
+	 */
+	while ((ind=getopt(argc, argv, 
+	    "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")) != EOF) {
+		switch(ind) {
+
+		case 'h' :
+			help();
+			exit(0);
+
+		case 'B':
+			switch (sscanf(optarg, "%i%c",
+				   &bytes_to_consume, &chr)) {
+			case 1: /* noop */
+			        break;
+
+			case 2:
+				if (chr == 'b') {
+				    bytes_to_consume *= BSIZE;
+				} else {
+				    fprintf(stderr,
+					"%s%s:  --B option arg invalid\n",
+					Progname, TagName);
+				    usage();
+				    exit(1);
+				}
+				break;
+
+			default:
+				fprintf(stderr, "%s%s: --B option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+				break;
+			}
+
+			break;
+
+		case 'E' :
+			prt_examples(stdout);
+			exit(0);
+
+		case 'b' :	/* batch */
+			backgrnd=0;
+			break;
+
+		case 'C':
+			if (sscanf(optarg, "%i", &write_check_inter) != 1 ) {
+				fprintf(stderr, "%s%s: --c option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+		       break;
+
+		case 'c':
+			if (sscanf(optarg, "%i", &file_check_inter) != 1 ) {
+				fprintf(stderr, "%s%s: --c option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+
+		case 'd':
+			auto_dir=optarg;
+#ifdef CRAY
+			unsetenv("TMPDIR");	/* force the use of auto_dir */
+#endif
+			if ( stat(auto_dir, &statbuf) == -1 ) {
+			    if ( mkdir(auto_dir, 0777) == -1 ) {
+				if ( errno != EEXIST ) {
+				    fprintf(stderr,
+				        "%s%s: Unable to make dir %s\n", 
+				        Progname, TagName, auto_dir);
+				    exit(1);
+			        }
+			    }
+			}
+			else {
+			    if ( ! (statbuf.st_mode & S_IFDIR) )  {
+				fprintf(stderr,
+				    "%s%s: %s already exists and is not a directory\n",
+				    Progname, TagName, auto_dir);
+				exit(1);
+			    }
+			}
+			break;
+
+		case 'D':
+			if (sscanf(optarg, "%i", &Debug) != 1 ) {
+				fprintf(stderr, "%s%s: --D option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'e':
+			if (sscanf(optarg, "%i", &Maxerrs) != 1 ) {
+				fprintf(stderr, "%s%s: --e option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'f':
+			auto_file=optarg;
+			break;
+
+		case 'g':
+			if ((ret=sscanf(optarg, "%i%c", &grow_incr, &chr)) < 1 ||
+				grow_incr < 0 ) {
+
+				fprintf(stderr, "%s%s: --g option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			if ( ret == 2 ) {
+				if ( chr == 'b' || chr == 'B' )
+					grow_incr *= 4096;
+				else {
+					fprintf(stderr,
+						"%s%s: --g option arg invalid\n",
+						Progname, TagName);
+					usage();
+					exit(1);
+				}
+			}
+			break;
+
+		case 'H':
+			if (sscanf(optarg, "%f", &delaysecs) != 1 || delaysecs < 0 ) {
+
+				fprintf(stderr, "%s%s: --H option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'i':
+			if (sscanf(optarg, "%i", &iterations) != 1 ||
+				iterations < 0 ) {
+
+				fprintf(stderr, "%s%s: --i option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'I':
+#if NEWIO
+			if((io_type=lio_parse_io_arg1(optarg)) == -1 ) {
+			    fprintf(stderr,
+				"%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
+				Progname, TagName);
+			    exit(1);
+			}
+			if( io_type & LIO_RANDOM )
+				using_random++;
+#else
+			if((io_type=parse_io_arg(optarg)) == -1 ) {
+			    fprintf(stderr,
+				"%s%s: --I arg is invalid, must be s, p, f, a, l, L or r.\n",
+				Progname, TagName);
+			    exit(1);
+			}
+			if( io_type == 99 ) /* hold-over until tlibio.h */
+				using_random++;
+#endif
+			break;
+
+		case 'l':
+			lockfile++;
+			if ( lockfile > 2 )
+			   lockfile=2;	/* lockfile can only be 1 or 2 */
+			break;
+
+		case 'L':
+			if (sscanf(optarg, "%i", &time_iterval) != 1 ||
+				time_iterval < 0 ) {
+				fprintf(stderr, "%s%s: --L option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'n':
+			if (sscanf(optarg, "%i:%i", &num_procs, &forker_mode) < 1 ||
+                                num_procs < 0 ) {
+
+                                fprintf(stderr, "%s%s: --n option arg invalid\n",
+                                        Progname, TagName);
+                                usage();
+                                exit(1);
+                        }
+
+			break;
+
+		case 'N':
+			if (sscanf(optarg, "%i", &num_auto_files) != 1 ||
+				num_auto_files < 0 ) {
+
+				fprintf(stderr, "%s%s: --N option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'O':
+			if (sscanf(optarg, "%i", &Alignment) != 1 ||
+				num_auto_files < 0 ) {
+
+				fprintf(stderr, "%s%s: --O option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'o':
+		        if ( strcmp(optarg, "random") == 0 ){
+			    open_flags=RANDOM_OPEN;
+			    using_random++;
+
+		        } else if ((open_flags=parse_open_flags(optarg, NULL)) == -1 ) {
+		            fprintf(stderr, "%s%s: --o arg contains invalid flag\n",
+				Progname, TagName);
+		            exit(1);
+		        }
+		        break;
+
+
+		case 'p' :	/* pre allocate space */
+#ifdef linux
+			printf("%s%s: --p is illegal option on linux system\n",
+				Progname, TagName);
+			exit(1);
+#else
+			pre_alloc_space++;
+#endif
+			break;
+
+		case 'P':
+#ifdef CRAY
+			if (strcmp(optarg, "PANIC") != 0 ) {
+				fprintf(stderr, "%s%s: --P arg must be PANIC\n", Progname, TagName);
+				exit(1);
+			}
+			Upanic_on_error++;
+			printf("%s: Will call upanic after writes\n");
+#else
+			printf("%s%s: --P is illegal option on non-cray system\n",
+				Progname, TagName);
+			exit(1);
+#endif
+			break;
+
+		case 'q':	/* file content or pattern */
+			switch(optarg[0]) {
+			case 'A':
+			    Pattern = PATTERN_ALT;
+			    break;
+			case 'a':
+			    Pattern = PATTERN_ASCII;
+			    break;
+			case 'p':
+			    Pattern = PATTERN_PID;
+			    break;
+			case 'o':
+			    Pattern = PATTERN_OFFSET;
+			    break;
+			case 'c':
+			    Pattern = PATTERN_CHKER;
+			    break;
+			case 'C':
+			    Pattern = PATTERN_CNTING;
+			    break;
+			case 'r':
+			    Pattern = PATTERN_RANDOM;
+			    using_random++;
+			    break;
+			case 'z':
+			    Pattern = PATTERN_ZEROS;
+			    break;
+			case 'O':
+			    Pattern = PATTERN_ONES;
+			    break;
+			default:
+			    fprintf(stderr,
+				"%s%s: --C option arg invalid, A, a, p, o, c, C, r, z, or 0\n",
+				Progname, TagName);
+			    usage();
+			    exit(1);
+			}
+			break;
+
+		case 'R':	/* random lseek before write arg: [min-]max*/
+			if (sscanf(optarg, "%i-%i", &min_lseek, &max_lseek) != 2 ) {
+			    min_lseek=1;    /* same as default in define */
+			    if (sscanf(optarg, "%i%c", &max_lseek, &chr) != 1 ) {
+				fprintf(stderr, "%s%s: --R option arg invalid: [min-]max\n",
+				    Progname, TagName);
+				exit(1);
+			    }
+			}
+			if ( max_lseek < LSK_EOFMINUSGROW ) {
+			    fprintf(stderr, "%s%s: --R option, max_lseek is invalid\n",
+				Progname, TagName);
+                            exit(1);
+			}
+			Mode |= MODE_RAND_LSEEK;
+			using_random++;
+		        break;
+
+		case 'r':	/* random io size arg: [min-]max[:mult] */
+
+			/* min-max:mult format */
+			if (sscanf(optarg, "%i-%i:%i%c", &min_size, &max_size,
+							&mult_size, &chr) != 3 ) {
+			  min_size=1;   
+			  /* max:mult format */
+		  	  if (sscanf(optarg, "%i:%i%c", &max_size,
+							&mult_size, &chr) != 2 ) {
+			    /* min-max format */
+		    	    if (sscanf(optarg, "%i-%i%c", &min_size,
+							&max_size, &chr) != 2 ) {
+			      min_size=1;   
+		      	      if (sscanf(optarg, "%i%c", &max_size, &chr) != 1 ) {
+				fprintf(stderr,
+				     "%s%s: --r option arg invalid: [min-]max[:mult]\n",
+			    	Progname, TagName);
+				exit(1);
+		      	      }
+		    	    }
+		  	  }
+			}
+
+			if ( max_size < 0 ) {
+			    fprintf(stderr, "%s%s: --r option, max_size is invalid\n",
+				Progname, TagName);
+                            exit(1);
+			}
+			/*
+			 * If min and max are the same, no randomness
+			 */
+			if ( min_size != max_size ) {
+			    Mode |= MODE_RAND_SIZE;
+			    using_random++;
+ 			}
+		        break;
+
+		case 'S':
+			if (sscanf(optarg, "%i", &seq_auto_files) != 1 ||
+				seq_auto_files < 0 ) {
+
+				fprintf(stderr, "%s%s: --S option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 's':	/* format: seed[,seed...] */
+			
+			/* count the number of seeds */
+			cptr=optarg;
+			for(Nseeds=1; *cptr ; Nseeds++) {
+			    if ( (filename=strchr(cptr, ',')) == NULL )
+				break;
+			    cptr=filename;
+			    cptr++;
+			}
+			Seeds=(int *)malloc(Nseeds*sizeof(int));
+
+			/*
+			 * check that each seed is valid and put them in 
+			 * the newly malloc'ed Seeds arrary.
+			 */
+			filename=cptr=optarg;
+			for(Nseeds=0; *cptr; Nseeds++) {
+			    if ( (filename=strchr(cptr, ',')) == NULL ) {
+				if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
+                                    fprintf(stderr, "%s%s: --s option arg %s invalid\n",
+                                        Progname, TagName, cptr);
+                                    usage();
+                                    exit(1);
+				}
+				Nseeds++;
+                                break;
+			    }
+
+			    *filename='\0';
+			    if ( sscanf(cptr, "%i", &Seeds[Nseeds]) < 1 ) {
+                               fprintf(stderr, "%s%s: --s option arg %s invalid\n",
+                                        Progname, TagName, cptr);
+                                usage();
+                                exit(1);
+			    }
+			    *filename=',';   /* restore string */
+                            cptr=filename;
+			    cptr++;
+			}
+			break;
+
+		case 't':
+			if ((ret=sscanf(optarg, "%i%c", &trunc_incr, &chr)) < 1 ||
+				trunc_incr < 0 ) {
+
+				fprintf(stderr, "%s%s: --t option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			if ( ret == 2 ) {
+				if ( chr == 'b' || chr == 'B' )
+					trunc_incr *= 4096;
+				else {
+					fprintf(stderr,
+						"%s%s: --t option arg invalid\n",
+						Progname, TagName);
+					usage();
+					exit(1);
+				}
+			}
+			break;
+
+		case 'T':	/* truncate interval */
+			if (sscanf(optarg, "%i%c", &trunc_inter, &chr) != 1 ||
+				trunc_inter < 0 ) {
+
+				fprintf(stderr, "%s%s: --T option arg invalid\n",
+					Progname, TagName);
+				usage();
+				exit(1);
+			}
+			break;
+
+		case 'u':
+			remove_files++;
+			break;
+
+		case 'U':   /* how often to unlink file */
+		       /* 
+			* formats:   
+			*      A-B  - randomly pick interval between A and B 
+			*      X    - unlink file every X iteration
+			*/
+                       if (sscanf(optarg, "%i-%i", &unlink_inter, 
+						&unlink_inter_ran) == 2 ) {
+
+			   if ( unlink_inter < 0 || unlink_inter_ran < 0 ) {
+                                fprintf(stderr, "%s%s: --U option arg invalid\n",
+                                        Progname, TagName);
+                                usage();
+                                exit(1);
+			   }
+			   /* ensure unlink_inter contains smaller value */
+			   if ( unlink_inter > unlink_inter_ran ) {
+				tmp=unlink_inter_ran;
+				unlink_inter_ran=unlink_inter;
+				unlink_inter=tmp;
+			   }
+			   using_random++;
+
+                       } else if (sscanf(optarg, "%i%c", &unlink_inter, &chr) != 1 ||
+                                unlink_inter < 0 ) {
+
+                            fprintf(stderr, "%s%s: --U option arg invalid\n",
+                                 Progname, TagName);
+                            usage();
+                            exit(1);
+                        }
+			break;
+
+	        case 'x':
+			if ( reexec != REXEC_DONE )
+			    reexec=REXEC_DOIT;
+			break;
+
+		case 'w':
+			Mode |= MODE_GROW_BY_LSEEK;
+			break;
+
+		case 'W':
+			sprintf( TagName, "(%.39s)", optarg );
+			break;
+
+		case 'y':
+			Sync_with_others=1;
+			break;
+
+		case '?':
+			usage();
+			exit(1);
+			break;
+		}
+	}
+
+	if( Debug == 1 ){
+		cptr = getenv("TOUTPUT");
+		if( (cptr != NULL) && (strcmp( cptr, "NOPASS" ) == 0) ){
+			Debug = 0;
+		}
+	}
+
+	if ( Pattern == PATTERN_RANDOM ) {
+	    no_file_check=1;
+	    if ( write_check_inter || file_check_inter )
+                printf("%s%s: %d Using random pattern - no data checking will be performed!\n",
+		    Progname, TagName, getpid());
+	}
+	else if ( max_lseek == LSK_EOFPLUSGROW || Mode & MODE_GROW_BY_LSEEK ) {
+	    no_file_check=1;
+
+	    if ( file_check_inter )
+	        printf("%s%s: %d Using random lseek beyond EOF or lseek grow,\n\
+no whole file checking will be performed!\n", Progname, TagName, getpid());
+
+	}
+
+	if ( Mode & MODE_RAND_SIZE )
+	    grow_incr=max_size;
+
+	set_sig();
+
+	Opid=getpid();
+	Pid=Opid;
+
+	if ( backgrnd ) {
+	    if ( Debug > 1 )
+		printf("%s: %d DEBUG2 forking, returning control to the user\n",
+		    Progname, Opid);
+	    background(Progname);	/* give user their prompt back */
+	}
+
+#if CRAY
+	if ( Sync_with_others )
+	   setpgrp();
+#endif
+
+	if ( Debug > 3 ) {
+#if NEWIO
+	    lio_set_debug(Debug-3);
+#else
+	    set_iowrite_debug(Debug-3);
+#endif
+	}
+
+	/*
+	 * Print some program information here if debug is turned on to
+	 * level 3 or higher.
+	 */
+
+        if ( Debug > 2 ) {
+	    
+	    if (  Mode & MODE_GROW_BY_LSEEK )
+		printf("%s: %d DEBUG lseeking past end of file, writting a \"w\"\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_OFFSET )
+		printf("%s: %d DEBUG3 %d<byteoffset>%d per word pattern multi-writers.\n",
+		    Progname, Pid, STATIC_NUM, STATIC_NUM);
+	    else if ( Pattern == PATTERN_PID )
+		printf("%s: %d DEBUG3 <pid><byteoffset><pid> per word pattern - 1 writer\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_ASCII )
+		printf("%s: %d DEBUG3 ascii pattern (vi'able)- allows multiple writers\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_ALT )
+		printf("%s: %d DEBUG3 alt bit pattern - allows multiple writers\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_CHKER )
+		printf("%s: %d DEBUG3 checkerboard pattern - allows multiple writers\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_CNTING )
+		printf("%s: %d DEBUG3 counting pattern - allows multiple writers\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_RANDOM )
+		printf("%s: %d DEBUG3 random integer pattern - no write/file checking\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_ONES )
+		printf("%s: %d DEBUG3 all ones pattern - allows multiple writers\n",
+		    Progname, Pid);
+	    else if ( Pattern == PATTERN_ZEROS )
+		printf("%s: %d DEBUG3 all zeros pattern - allows multiple writers\n",
+		    Progname, Pid);
+	
+	    else
+		printf("%s: %d DEBUG3 unknown pattern\n",
+		    Progname, Pid);
+	    if ( bytes_to_consume )
+	        printf("%s: %d DEBUG3 bytes_to_consume = %d\n",
+		    Progname, Pid, bytes_to_consume);
+	    printf("%s: %d DEBUG3 Maxerrs = %d, pre_alloc_space = %d, filelocking = %d\n", 
+		Progname, Pid, Maxerrs, pre_alloc_space, lockfile);
+
+	    printf("%s: %d DEBUG3 Debug = %d, remove files in cleanup : %d\n",
+		Progname, Pid, Debug, remove_files);
+
+	    printf("%s: %d DEBUG3 Mode = %#o\n", Progname, Pid, Mode);
+
+	    if ( open_flags == RANDOM_OPEN )
+	       printf("%s: %d DEBUG3 open_flags = (random), io_type = %#o\n", Progname,
+		 Pid, io_type);
+	    else
+	       printf("%s: %d DEBUG3 open_flags = %#o, io_type = %#o\n", Progname,
+		 Pid, open_flags, io_type);
+
+	    if ( Mode & MODE_RAND_SIZE ) {
+	        printf("%s: %d DEBUG3 random write/trunc:  min=%d, max=%d, mult = %d\n",
+		    Progname, Pid, min_size, max_size, mult_size);
+	    }
+	    else {
+		printf("%s: %d DEBUG3 grow_incr = %d\n", 
+		    Progname, Pid, grow_incr);
+	    }
+	    if ( Mode & MODE_RAND_LSEEK ) {
+		if ( max_lseek == LSK_EOF )
+	          printf("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile>\n",
+		    Progname, Pid, min_lseek);
+		else if ( max_lseek == LSK_EOFPLUSGROW )
+	          printf("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile+iosize>\n",
+		    Progname, Pid, min_lseek);
+		else if ( max_lseek == LSK_EOFMINUSGROW )
+	          printf("%s: %d DEBUG3 random lseek:  min=%d, max=<endoffile-iosize>\n",
+		    Progname, Pid, min_lseek);
+		else
+	          printf("%s: %d DEBUG3 random lseek:  min=%d, max=%d\n",
+		    Progname, Pid, min_lseek, max_lseek);
+	    }
+
+	    printf("%s: %d DEBUG3 check write interval = %d, check file interval = %d\n",
+		Progname, Pid, write_check_inter, file_check_inter);
+
+	    printf("%s: %d DEBUG3 trunc interval = %d, trunc_incr = %d\n",
+		Progname, Pid, trunc_inter, trunc_incr);
+
+	    if ( no_file_check )
+		printf("%s: %d DEBUG3 no whole file checking will be done\n",
+		    Progname, Pid);
+	    
+	    if ( unlink_inter_ran == -1 ) {
+		printf("%s: %d DEBUG3 unlink_inter = %d\n", 
+		        Progname, Pid, unlink_inter);
+	    } else {
+		printf("%s: %d DEBUG3 unlink_inter = %d, unlink_inter_ran = %d\n", 
+                        Progname, Pid, unlink_inter, unlink_inter_ran);
+	    }  
+
+	    if ( Debug > 8 ) {
+	       num=sizeof(Open_flags)/sizeof(int);
+	       printf("%s: %d DEBUG9 random open flags values:\n", Progname, Pid);
+	       for(ind=0; ind<num; ind++) {
+		    printf("\t%#o\n", Open_flags[ind]);
+	       }
+	    }
+	}  /* end of DEBUG > 2 */
+
+	if ( Debug > 1 && num_procs > 1 ) {
+	    printf("%s: %d DEBUG2 about to fork %d more copies\n", Progname,
+		Opid, num_procs-1);
+	}
+
+	fflush(stdout);	/* ensure pending i/o is flushed before forking */
+	fflush(stderr);
+
+	forker(num_procs, forker_mode, Progname);
+
+	Pid=getpid();	/* reset after the forks */
+	/*
+	 * If user specified random seed(s), get that random seed value.
+	 * get random seed if it was not specified by the user.
+	 * This is done after the forks, because pid is used to get the seed.
+         */
+	if ( Nseeds == 1 ) {
+	    /*
+	     * If only one seed specified, all processes will get that seed. 
+	     */
+	    Seed=Seeds[0];
+	} else if ( Nseeds > 1 ) {
+	    /*
+	     * More than one seed was specified.
+	     * The original process gets the first seed.  Each
+	     * process will be get the next seed in the specified list.
+	     */
+	    if ( Opid == Pid ) {
+		Seed=Seeds[0];
+	    } else {
+		/*
+		 * If user didn't specify enough seeds, use default method.
+		 */
+		if ( Forker_npids >= Nseeds ) 
+	    	    Seed=time(0) + Pid;  /* default random seed */
+		else {
+		    Seed=Seeds[Forker_npids];
+		}
+	    }
+	} else {
+	    /* 
+	     * Generate a random seed based on time and pid.
+	     * It has a good chance of being unique for each pid.
+	     */
+	    Seed=time(0) + Pid;  /* default random seed */
+	}
+
+	random_range_seed(Seed);
+
+        if ( using_random && Debug > 0 )
+	    printf("%s%s: %d DEBUG1 Using random seed of %d\n",
+		Progname, TagName, Pid, Seed);
+
+	if ( unlink_inter_ran > 0 ) {
+	    /*
+	     * Find unlinking file interval.  This must be done after
+	     * the seed was set.   This allows multiple copies to
+	     * get different intervals.
+	     */
+	    tmp=unlink_inter;
+	    unlink_inter=random_range(tmp, unlink_inter_ran, 1, NULL);
+
+	    if ( Debug > 2 )
+		printf("%s: %d DEBUG3 Unlink interval is %d (random %d - %d)\n",
+		    Progname, Pid, unlink_inter, tmp, unlink_inter_ran);
+	}
+
+	/*
+	 * re-exec all childern if reexec is set to REXEC_DOIT.
+	 * This is useful on MPP systems to get the
+	 * child process on another PE.
+	 */
+	if ( reexec == REXEC_DOIT && Opid != Pid ) {
+	    if ( exec_path == NULL ) {
+		exec_path = argv[0];
+		/* Get space for cmd (2 extra, 1 for - and 1 fro NULL */
+		argv[0] = (char *)malloc(strlen(exec_path) + 2);
+		sprintf(argv[0], "-%s", exec_path);
+	    }
+	  
+	    if ( Debug > 2 )
+	        printf("%s: %d DEBUG3 %s/%d: execvp(%s, argv)\n",
+		    Progname, Pid, __FILE__, __LINE__, argv[0]);
+
+	    execvp(argv[0], argv);
+        }
+
+	/*** begin filename stuff here *****/
+	/*
+	 * Determine the number of files to be dealt with
+	 */
+	if ( optind == argc ) {
+		/*
+		 * no cmd line files, therfore, set
+		 * the default number of auto created files
+		 */
+		if ( ! num_auto_files && ! seq_auto_files )
+			num_auto_files=1;
+	}
+	else {
+		first_file_ind=optind;
+		num_files += argc-optind;
+	}
+
+	if ( num_auto_files ) {
+		num_files += num_auto_files;
+	}
+
+	if ( seq_auto_files ) {
+		num_files += seq_auto_files;
+	}
+
+	/*
+	 * get space for file names
+	 */
+	if ((filenames=(char *)malloc(num_files*PATH_MAX)) == NULL) {
+		fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, num_files*PATH_MAX,
+			strerror(errno));
+		exit(1);
+	}
+
+	/*
+	 * fill in filename cmd files then auto files.
+	 */
+
+	num=0;
+	if ( first_file_ind ) {
+		for(ind=first_file_ind; ind<argc; ind++, num++) {
+			strcpy((char *)filenames+(num*PATH_MAX), argv[ind]);
+		}
+	}
+
+	/*
+	 * construct auto filename and insert them into filenames space
+	 */
+		
+	for(ind=0;ind<num_auto_files; ind++, num++) {
+		sprintf((char *)filenames+(num*PATH_MAX), "%s.%d",
+			tempnam(auto_dir, auto_file), ind );
+	}
+
+	/*
+	 * construct auto seq filenames
+	 */
+	for(ind=1; ind<=seq_auto_files; ind++, num++) {
+		sprintf((char *)filenames+(num*PATH_MAX), "%s/%s%d",
+			auto_dir, auto_file, ind);
+	}
+
+/**** end filename stuff ****/
+
+	if ( time_iterval > 0 )
+		start_time=time(0);
+
+	/*
+	 * get space for I/O buffer
+	 */
+	if ( grow_incr ) {
+		if ((Buffer=(char *)malloc(grow_incr+Alignment)) == NULL) {
+			fprintf(stderr, "%s%s: %d %s/%d: malloc(%d) failed: %s\n",
+				Progname, TagName, Pid, __FILE__, __LINE__, grow_incr, strerror(errno));
+			exit(1);
+		}
+		if ( Alignment )
+		Buffer = Buffer + Alignment;
+
+	}
+
+	if ( Debug > 2 ) {
+		printf("%s: %d DEBUG3 num_files = %d\n",
+			Progname, Pid, num_files);
+	}
+
+#ifndef linux
+	if ( pre_alloc_space ) {
+		if ( iterations == 0 ) {
+		    fprintf(stderr, "%s%s: %d %s/%d: can NOT pre-alloc and grow forever\n",
+			Progname, TagName, Pid, __FILE__, __LINE__);
+		    exit(1);
+		}
+		if ( Mode & MODE_RAND_SIZE ) {
+		    fprintf(stderr,
+			"%s%s: %d %s/%d: can NOT pre-alloc and do random io size\n",
+			Progname, TagName, Pid, __FILE__, __LINE__);
+		    exit(1);
+		}
+
+		total_grow_value=grow_incr * iterations;
+
+		/*
+		 * attempt to limit 
+		 */
+		if ( bytes_to_consume && bytes_to_consume < total_grow_value ) {
+			total_grow_value=bytes_to_consume;
+		}
+	}
+#endif
+
+	/*
+	 * If delaying between iterations, get amount time to
+	 * delaysecs in clocks or usecs.
+	 * If on the CRAY, delaytime is in clocks since
+	 * _rtc() will be used, which does not have the overhead
+         * of gettimeofday(2).
+	 */
+	if ( delaysecs ) {
+#if CRAY
+	   int hz;
+	   hz=sysconf(_SC_CLK_TCK);
+	   delaytime=(int)((float)hz * delaysecs);
+#else
+	   delaytime=(int)((float)USECS_PER_SEC * delaysecs);
+#endif
+        }
+
+	/*
+	 * This is the main iteration loop.
+	 * Each iteration, all files can  be opened, written to,
+	 * read to check the write, check the whole file, 
+	 * truncated, and closed.   
+	 */
+	for(Iter_cnt=1; ! stop ; Iter_cnt++) {
+
+	    if ( iterations && Iter_cnt >= iterations+1 ) {
+		strcpy(reason, "Hit iteration value");
+		stop=1;
+		continue;
+	    }
+
+	    if (  (time_iterval > 0) && (start_time + time_iterval < time(0)) ) {
+		sprintf(reason, "Hit time value of %d", time_iterval);
+		stop=1;
+		continue;
+	    }
+
+	    if ( bytes_to_consume && bytes_consumed >= bytes_to_consume) {
+		sprintf(reason, "Hit bytes consumed value of %d", bytes_to_consume);
+		stop=1;
+                continue;
+            }
+
+	    /*
+	     * This loop will loop through all files.
+	     * Each iteration, a single file can  be opened, written to,
+	     * read to check the write, check the whole file, 
+	     * truncated, and closed.   
+	     */
+	    for(ind=0; ind<num_files; ind++) {
+
+		fflush(stdout);
+		fflush(stderr);
+
+		filename=(char *)filenames+(ind*PATH_MAX);
+		Fileinfo.filename=(char *)filenames+(ind*PATH_MAX);
+
+
+		if ( open_flags ==  RANDOM_OPEN ) {
+		   ret=Open_flags[random_range(0, sizeof(Open_flags)/sizeof(int)-1, 1, NULL)];
+		}
+
+		else
+		   ret=open_flags;
+
+		Fileinfo.openflags=ret;
+
+		if ( Debug > 3 ) {
+		    printf("%s: %d DEBUG3 %s/%d: %d Open filename = %s, open flags = %#o %s\n",
+			Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret, 
+		        openflags2symbols(ret, ",", NULL));
+		} else if ( Debug > 2 ) {
+		    printf("%s: %d DEBUG3 %s/%d: %d filename = %s, open flags = %#o\n",
+			Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, ret);
+		}
+
+		/*
+		 * open file with desired flags.
+		 */
+		if ( (fd=open(filename, ret, 0777)) == -1 ) {
+		    fprintf(stderr,
+                        "%s%s: %d %s/%d: open(%s, %#o, 0777) returned -1, errno:%d %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, filename, ret, errno, strerror(errno));
+			handle_error();
+			continue;
+		}
+
+		Fileinfo.fd=fd;
+
+		lkfile(fd, LOCK_EX, LKLVL1);   /* lock if lockfile is LKLVL1 */
+
+#ifndef linux
+		/*
+		 * preallocation is only done once, if specified.
+		 */
+		if ( pre_alloc_space ) {
+			if (pre_alloc(fd, total_grow_value) != 0 ) {
+				cleanup();
+				exit(2);
+			}
+			if ( Debug > 1 ) {
+				printf("%s: %d DEBUG2 %s/%d: pre_allocated %d for file %s\n",
+				    Progname, Pid, __FILE__, __LINE__, total_grow_value, filename);
+			}
+			lkfile(fd, LOCK_UN, LKLVL1);   /* release lock */
+			close(fd);
+			Iter_cnt=0;	/* reset outside loop to restart from one */
+			continue;
+		}
+#endif
+
+		/*
+		 * grow file by desired amount.
+		 * growfile() will set the Grow_incr variable and 
+                 * possiblly update the Mode variable indicating
+		 * if we are dealing with a FIFO file.
+		 */
+
+		if (growfile(fd, filename, grow_incr, Buffer) != 0 ) {
+			handle_error();
+			lkfile(fd, LOCK_UN, LKLVL1);   /* release lock */
+			close(fd);
+			continue;
+		}
+
+		/*
+		 * check if last write is not corrupted
+		 */
+		if ( check_write(fd, write_check_inter, filename,
+							Mode) != 0 ) {
+		    handle_error();
+                }
+
+		/*
+		 * Check that whole file is not corrupted.
+		 */
+		if ( check_file(fd, file_check_inter, filename,
+						no_file_check) != 0 ) {
+		    handle_error();
+		}
+
+		/*
+		 * shrink file by desired amount if it is time 
+		 */
+
+		if ( shrinkfile(fd, filename, trunc_incr, trunc_inter, Mode) != 0 ) {
+		    handle_error();
+		}
+
+		lkfile(fd, LOCK_UN, LKLVL1);   /* release lock */
+
+		if ( Debug > 4 )
+		    printf("%s: %d DEBUG5 %s/%d: %d Closing file %s fd:%d \n", 
+			Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename, fd);
+		close(fd);
+
+		/*
+		 * Unlink the file if that is desired
+		 */
+		if ( unlink_inter && (Iter_cnt % unlink_inter == 0) ) {
+		
+		    if ( Debug > 4 )
+			printf("%s: %d DEBUG5 %s/%d: %d Unlinking file %s\n", 
+			    Progname, Pid, __FILE__, __LINE__, Iter_cnt, filename);
+
+		    unlink(filename);
+		}
+
+	        /*
+	         * delay while staying active for "delaysecs" seconds.
+	         */
+	        if ( delaytime ) {
+		
+		    int ct, end;
+#ifdef CRAY
+		    ct=_rtc();
+		    end=ct+delaytime;
+        	    while ( ct < end ) {
+		        ct = _rtc();
+		    }
+#else
+		    struct timeval curtime;
+		    gettimeofday(&curtime, NULL);
+		    ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
+		    end=ct+delaytime;
+                    while ( ct < end ) {
+
+		        gettimeofday(&curtime, NULL);
+		        ct=curtime.tv_sec*USECS_PER_SEC + curtime.tv_usec;
+		    }
+#endif
+	        }
+	    }
+#ifndef linux
+	    /*
+	     * if Iter_cnt == 0, then we pre allocated space to all files
+	     * and we are starting outside loop over.  Set pre_alloc_space
+	     * to zero otherwise we get in infinite loop
+	     */
+	    if ( Iter_cnt == 0 ) {
+		pre_alloc_space=0;
+	    }
+#endif
+
+
+	}   /* end iteration for loop */
+
+
+        if ( Debug ) {
+	    printf("%s%s: %d %s/%d: DONE %d iterations to %d files. %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, num_files, reason);
+	}
+	fflush(stdout);
+	fflush(stderr);
+
+	cleanup();
+
+	if ( Errors ) {
+		if ( Debug > 2 ) {
+		    printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
+			Progname, TagName, Pid, Errors);
+		    printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
+		}
+		exit(1);
+	}
+	if ( Debug > 2 )
+	    printf("%s%s: %d DEBUG3 %s/%d: no errors, exiting with value of 0\n", Progname, TagName, Pid, __FILE__, __LINE__);
+	exit(0);
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+set_sig()
+{
+   int sig;
+
+	
+        /*
+         * now loop through all signals and set the handlers
+         */
+
+        for (sig = 1; sig < NSIG; sig++) {
+            switch (sig) {
+                case SIGKILL:
+                case SIGSTOP:
+                case SIGCONT:
+#ifdef CRAY
+                case SIGINFO:
+                case SIGRECOVERY:
+#endif /* CRAY */
+#ifdef SIGCKPT
+	        case SIGCKPT:
+#endif /* SIGCKPT */
+#ifdef SIGRESTART
+	        case SIGRESTART:
+#endif /* SIGRESTART */
+                case SIGCLD:
+                    break;
+
+                default:
+#ifdef sgi
+		    sigset( sig, sig_handler );
+#else
+/* linux and cray */
+                    signal(sig, sig_handler);
+#endif
+                break;
+            }
+        } /* endfor */
+
+
+        return 0;
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+void
+sig_handler(sig)
+int sig;
+{
+    int exit_stat = 2;
+
+    if ( sig == SIGUSR2 ) {
+	fprintf(stdout, "%s%s: %d %s/%d: received SIGUSR2 (%d) - stopping.\n",
+	    Progname, TagName, Pid, __FILE__, __LINE__, sig);
+#ifndef sgi
+        signal(sig, sig_handler);	/* allow us to get this signal more than once */
+#endif
+        
+    } else if( sig == SIGINT ){
+	/* The user has told us to cleanup, don't pretend it's an error. */
+	exit_stat=0;
+	if ( Debug != 0 ){
+		fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
+		    Pid, __FILE__, __LINE__, sig);
+	}
+    } else {
+	fprintf(stderr, "%s%s: %d %s/%d: received unexpected signal: %d\n", Progname, TagName,
+	    Pid, __FILE__, __LINE__, sig);
+    }
+
+    notify_others();
+    cleanup();
+    if ( Debug > 2 ){
+	printf("%s%s: %d DEBUG3 %s/%d: Exiting with a value of %d\n",
+	       Progname, TagName, Pid, __FILE__, __LINE__, exit_stat);
+    }
+    exit(exit_stat);
+}
+
+/***********************************************************************
+ * this function attempts to send SIGUSR2 to other growfiles processes
+ * telling them to stop.
+ *  
+ ***********************************************************************/
+static void
+notify_others()
+{
+    static int send_signals = 0;
+    int ind;
+    extern int Forker_pids[];
+    extern int Forker_npids;
+
+    if ( Sync_with_others && send_signals == 0 ) {
+
+#if CRAY
+	send_signals=1; /* only send signals once */
+	if ( Debug > 1 )
+	    printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pgrp\n",
+		  Progname, TagName, Pid, __FILE__, __LINE__);
+	killm(C_PGRP, getpgrp(), SIGUSR2);
+#else
+	send_signals=1; /* only send signals once */
+
+        for (ind=0; ind< Forker_npids; ind++) {
+	    if ( Forker_pids[ind] != Pid )
+	        if ( Debug > 1 )
+		    printf("%s%s: %d DEBUG2 %s/%d: Sending SIGUSR2 to pid %d\n",
+		        Progname, TagName, Pid, __FILE__, __LINE__, Forker_pids[ind]);
+	        kill(Forker_pids[ind], SIGUSR2);
+        }
+#endif
+    }
+
+}
+
+/***********************************************************************
+ * this function will count the number of errors encountered.
+ * This function will call upanic if wanted or cleanup and
+ * and exit is Maxerrs were encountered.
+ ***********************************************************************/
+int
+handle_error()
+{
+    Errors++;
+
+#ifdef CRAY
+    if ( Errors & Upanic_on_error ) {
+        upanic(PA_PANIC);
+    }
+#endif
+
+    if ( Maxerrs && Errors >= Maxerrs ) {
+	printf("%s%s: %d %s/%d: %d Hit max errors value of %d\n", 
+	    Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, Maxerrs);
+	notify_others();
+	cleanup();
+
+        if ( Debug > 2 ) {
+            printf("%s%s: %d DEBUG3 %d error(s) encountered\n",
+                        Progname, TagName, Pid, Errors);
+            printf("%s%s: %d DEBUG3 %s/%d: exiting with value of 1\n", Progname, TagName, Pid, __FILE__, __LINE__);
+        }
+
+	exit(1);
+    }
+
+    return 0;
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+cleanup()
+{
+    int ind;
+
+	if ( remove_files ) {
+	    if ( Debug > 2 )
+		printf("%s: %d DEBUG3 Removing all %d files\n", 
+		    Progname, Pid, num_files);
+	    for(ind=0; ind<=num_files; ind++) {
+		unlink(filenames+(ind*PATH_MAX));
+	    }
+	}
+	if ( using_random && Debug > 1 )
+	    printf("%s%s: %d DEBUG2 Used random seed: %d\n",
+		Progname, TagName, Pid, Seed);
+	return 0;
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+void
+usage()
+{
+	fprintf(stderr,
+	"Usage: %s%s [-bhEluy][[-g grow_incr][-i num][-t trunc_incr][-T trunc_inter]\n",
+	Progname, TagName );
+	fprintf(stderr,
+	"[-d auto_dir][-e maxerrs][-f auto_file][-N num_files][-w][-c chk_inter][-D debug]\n");
+	fprintf(stderr,
+	"[-s seed][-S seq_auto_files][-p][-P PANIC][-I io_type][-o open_flags][-B maxbytes]\n");
+	fprintf(stderr,
+	"[-r iosizes][-R lseeks][-U unlk_inter][-W tagname] [files]\n");
+
+	return;
+
+}	/* end of usage */
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+void
+help()
+{
+	usage();
+
+fprintf(stdout, "\
+  -h             Specfied to print this help and exit.\n\
+  -b             Specfied to execute in sync mode.(def async mode)\n\
+  -B maxbytes    Max bytes to consume by all files.  growfiles exits when more\n\
+                 than maxbytes have been consumed. (def no chk)  If maxbytes ends\n\
+                 with the letter 'b', maxbytes is multiplied by BSIZE\n\
+  -C write_chk   Specifies how often to check the last write (default 1)\n\
+  -c file_chk    Specifies how often to check whole file (default 0)\n\
+  -d auto_dir    Specifies the directory to auto created files. (default .)\n\
+  -D debug_lvl   Specifies the debug level (default 1)\n\
+  -E             Print examples and exit\n\
+  -e errs        The number errors that will terminate this program (def 100)\n\
+  -f auto_file   Specifies the base filename files created. (default \"gf\")\n\
+  -g grow_incr   Specfied to grow by incr for each num. (default 4096)\n\
+                 grow_incr may end in b for blocks\n\
+		 If -r option is used, this option is ignored and size is random\n\
+  -H delay       Amount of time to delay between each file (default 0.0)\n\
+  -I io_type Specifies io type: s - sync, p - polled async, a - async (def s)\n\
+		 l - listio sync, L - listio async, r - random\n\
+  -i iteration   Specfied to grow each file num times. 0 means forever (default 1)\n\
+  -l             Specfied to do file locking around write/read/trunc\n\
+		 If specified twice, file locking after open to just before close\n\
+  -L time        Specfied to exit after time secs, must be used with -i.\n\
+  -N num_files   Specifies the number of files to be created.\n\
+                 The default is zero if cmd line files.\n\
+                 The default is one if no cmd line files.\n\
+  -n num_procs   Specifies the number of copies of this cmd.\n\
+  -o op_type     Specifies open flages: (def O_RDWR,O_CREAT) op_type can be 'random'\n\
+  -O offset      adjust i/o buffer alignment by offset bytes\n\
+  -P PANIC       Specifies to call upanic on error.\n\
+  -p             Specifies to pre-allocate space\n\
+  -q pattern     pattern can be a - ascii, p - pid with boff, o boff (def)\n\
+		 A - Alternating bits, r - random, O - all ones, z - all zeros,\n\
+		 c - checkboard, C - counting\n\
+  -R [min-]max   random lseek before write and trunc, max of -1 means filesz,\n\
+		 -2 means filesz+grow, -3 filesz-grow. (min def is 0)\n\
+  -r [min-]max   random io write size (min def is 1)\n\
+  -S seq_auto_files Specifies the number of seqental auto files (default 0)\n\
+  -s seed[,seed...] Specifies the random number seed (default time(0)+pid)\n\
+  -t trunc_incr  Specfied the amount to shrink file. (default 4096)\n\
+                 trunc_inter may end in b for blocks\n\
+		 If -R option is used, this option is ignored and trunc is random\n\
+  -T trunc_inter Specfied the how many grows happen before shrink. (default 0)\n\
+  -u             unlink files before exit\n\
+  -U ui[-ui2]    Unlink files each ui iteration (def 0)\n\
+  -w             Specfied to grow via lseek instead of writes.\n\
+  -W tag-name	 Who-am-i.  My Monster tag name.  (used by Monster).\n\
+  -x		 Re-exec children before continuing - useful on MPP systems\n\
+  -y             Attempt to sync copies - if one fails it will send sigusr2 to others\n\
+  Action to each file every iteration is open, write, write check\n\
+  file check, trunc and closed.\n");
+
+	return;
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+void
+prt_examples(FILE *stream)
+{
+	/* This example creates 200 files in directory dir1.  It writes */
+	/* 4090 bytes 100 times then truncates 408990 bytes off the file */
+	/* The file contents are checked every 1000 grow. */
+    fprintf(stream,
+	 "# run forever: writes of 4090 bytes then on every 100 iterval\n\
+# truncate file by 408990 bytes.  Done to 200 files in dir1.\n\
+%s -i 0 -g 4090 -T 100 -t 408990 -l -C 10 -c 1000 -d dir1 -S 200\n\n", Progname);
+
+	/* same as above with 5000 byte grow and a 499990 byte tuncate */
+    fprintf(stream,
+	 "# same as above with writes of 5000 bytes and truncs of 499990\n\
+%s -i 0 -g 5000 -T 100 -t 499990 -l -C 10 -c 1000 -d dir2 -S 200\n\n", Progname);
+
+	/* This example beats on opens and closes */
+    fprintf(stream,
+	 "# runs forever: beats on opens and closes of file ocfile - no io\n\
+%s -i 0 -g 0 -c 0 -C 0 ocfile\n\n", Progname);
+
+    fprintf(stream,
+	 "# writes 4096 to files until 50 blocks are written\n\
+%s -i 0 -g 4096 -B 50b file1 file2\n\n", Progname);
+	
+    fprintf(stream,
+	 "# write one byte to 750 files in gdir then unlinks them\n\
+%s -g 1 -C 0 -d gdir -u -S 750\n\n", Progname);
+
+    fprintf(stream,
+	"# run 30 secs: random iosize, random lseek up to eof\n\
+%s -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 g_rand1 g_rand2\n\n", Progname);
+
+    fprintf(stream,
+	"# run 30 secs: grow by lseek then write single byte, trunc every 10 itervals\n\
+%s -g 5000 -wlu -i 0 -L 30 -C 1 -T 10  g_sleek1 g_lseek2\n\n", Progname);
+
+    fprintf(stream, 
+	"# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
+# rand io types doing a trunc every 5 iterations, with unlinks.\n\
+%s -i0 -r 1-50000 -R 0--2 -I r -C1 -l -n5 -u -U 100-200 gf_rana gf_ranb\n\n", 
+	    Progname);
+
+    fprintf(stream, 
+	"# run forever: 5 copies of random iosize, random lseek to beyond eof,\n\
+# random open flags, rand io types doing a trunc every 10 iterations.\n\
+%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", 
+	    Progname);
+
+
+	return;
+}
+
+/***********************************************************************
+ *
+ * The file descriptor current offset is assumed to be the end of the
+ * file.  
+ * Woffset will be set to the offset before the write.
+ * Grow_incr will be set to the size of the write or lseek write.
+ ***********************************************************************/
+int
+growfile(fd, file, grow_incr, buf)
+int fd;
+char *file;
+int grow_incr;
+char *buf;
+{
+   int noffset;
+   int ret;
+   int cur_offset;
+   char *errmsg;
+   int fsize;		/* current size of file */
+   int size_grew;	/* size the file grew */
+   struct stat stbuf;
+   int tmp = 0;
+
+        /*
+         * Do a stat on the open file.
+         * If the file is a fifo, set the bit in Mode variable.
+         * This fifo check must be done prior to growfile() returning.
+	 * Also get the current size of the file.
+         */
+        if ( fstat(fd, &stbuf) != -1 ) {
+            if ( S_ISFIFO(stbuf.st_mode) ) {
+		Fileinfo.mode |= MODE_FIFO;
+                Mode |= MODE_FIFO;
+                if ( Debug > 3 )
+                    printf("%s: %d DEBUG4 %s/%d: file is a fifo - no lseek or truncs,\n",
+                        Progname, Pid, __FILE__, __LINE__);
+            }
+	    fsize = stbuf.st_size;
+
+        } else {
+	    fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
+
+	    return -1;
+	}
+
+
+        if ( grow_incr <= 0 ) {   /* don't attempt i/o if grow_incr <= 0 */ 
+
+	    Grow_incr=grow_incr;
+	    if ( Debug > 2 )
+		printf("%s: %d DEBUG3 %s/%d: Not attempting to grow, growsize == %d\n",
+		    Progname, Pid, __FILE__, __LINE__, grow_incr);
+	    return grow_incr;
+	}
+
+	if ( Mode & MODE_RAND_SIZE ) {
+	    grow_incr=random_range(min_size, max_size, mult_size, &errmsg);
+	    if (errmsg != NULL) {
+		fprintf(stderr, "%s%s: %d %s/%d: random_range() failed - %s\n", Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
+		return -1;
+	    }
+	    Grow_incr=grow_incr;
+	}
+	else
+	    Grow_incr=grow_incr;
+
+	if ( ! (Mode & MODE_FIFO) ) {
+	    if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
+	        fprintf(stderr, "%s%s: %d %s/%d: tell failed: %s\n",
+		    Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
+	        return -1;
+	    }
+        }
+
+	if ( Mode & MODE_GROW_BY_LSEEK ) {
+                Woffset=fsize;
+		if ( Debug > 2 ) {
+		    printf("%s: %d DEBUG3 %s/%d: Current size of file is %d\n", Progname,
+			Pid, __FILE__, __LINE__, Woffset);
+		    printf("%s: %d DEBUG3 %s/%d: lseeking to %d byte with SEEK_END\n", Progname,
+			Pid, __FILE__, __LINE__, grow_incr-1);
+		}
+
+		if ((noffset=lseek(fd, grow_incr-1, SEEK_END)) == -1 ) {
+			fprintf(stderr, "%s%s: %s/%d: lseek(fd, %d, SEEK_END) failed: %s\n",
+				Progname, TagName, __FILE__, __LINE__, grow_incr-1, strerror(errno));
+			return -1;
+		}
+
+		lkfile(fd, LOCK_EX, LKLVL0);	 /* get exclusive lock */
+		
+#if NEWIO
+		ret=lio_write_buffer(fd, io_type, "w", 1, SIGUSR1, &errmsg,0);
+#else
+		ret=write_buffer(fd, io_type, "w", 1, 0, &errmsg); 
+#endif
+
+		if ( ret != 1 ) {
+			fprintf(stderr, "%s%s: %d %s/%d: %d %s\n", 
+			    Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
+			if ( ret == -ENOSPC ) {
+				cleanup();
+				exit(2);
+			}
+		}
+/***
+		write(fd, "w", 1);
+****/
+
+		lkfile(fd, LOCK_UN, LKLVL0);
+
+                if ( Debug > 2 )
+                    printf("%s: %d DEBUG3 %s/%d: %d wrote 1 byte to file\n",
+                            Progname, Pid, __FILE__, __LINE__, Iter_cnt);
+
+	} else {  /* end of grow by lseek */
+
+		if ( Fileinfo.openflags & O_APPEND ) {
+		   /*
+		    * Deal with special case of the open flag containing O_APPEND.
+		    * If it does, the current offset does not matter since the write
+		    * will be done end of the file.
+		    */
+		    if ( Debug > 4 )
+			printf("%s: %d DEBUG5 %s/%d: dealing with O_APPEND condition\n",
+			    Progname, Pid, __FILE__, __LINE__ );
+		    lkfile(fd, LOCK_EX, LKLVL0);	 /* get exclusive lock */
+
+		    /*
+		     * do fstat again to get size of the file.
+		     * This is done inside a file lock (if locks are being used).
+		     */
+        	    if ( fstat(fd, &stbuf) != -1 ) {
+            		Woffset = stbuf.st_size;
+        	    } else {
+            		fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
+                	Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
+	
+			lkfile(fd, LOCK_UN, LKLVL0);     /* release lock */
+            		return -1;
+        	    }
+		    if ( Debug > 2 )
+			printf("%s: %d DEBUG3 %s/%d: dealing with O_APPEND condition (offset:fsz:%d)\n",
+			    Progname, Pid, __FILE__, __LINE__, (int)stbuf.st_size);
+
+
+		} else if ( Mode & MODE_RAND_LSEEK ) {
+                   if ( max_lseek == LSK_EOF ) {	/* within file size */
+                        noffset=random_range(min_lseek, fsize, 1, NULL);
+                   }		
+		   else if ( max_lseek == LSK_EOFPLUSGROW ) {	
+		        /* max to beyond file size */
+			noffset=random_range(min_lseek, fsize+grow_incr, 1, NULL);
+		   }
+		   else if ( max_lseek == LSK_EOFMINUSGROW ) {	
+		        /* 
+			 * Attempt to not grow the file.
+			 * If the i/o will fit from min_lseek to EOF,
+			 * pick offset to allow it to fit.
+			 * Otherwise, pick the min_lseek offset and grow
+			 * file by smallest amount.
+			 * If min_lseek is != 0, there will be a problem
+			 * with whole file checking if file is ever smaller
+			 * than min_lseek.
+			 */
+			if ( fsize <= min_lseek + grow_incr )
+			    noffset=min_lseek;  /* file will still grow */
+			else
+			    noffset=random_range(min_lseek, fsize-grow_incr, 1, NULL);
+		   }
+                   else {
+                        noffset=random_range(min_lseek, max_lseek, 1, NULL);
+                   }
+
+		   if ((Woffset=lseek(fd, noffset, SEEK_SET)) == -1 ) {
+                        fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l2 failed: %s\n",
+                                Progname, TagName, Pid, __FILE__, __LINE__, fd, noffset, strerror(errno));
+                        return -1;
+		   }
+                   else if ( Debug > 2 )
+                        printf("%s: %d DEBUG3 %s/%d: lseeked to random offset %d (fsz:%d)\n",
+                            Progname, Pid, __FILE__, __LINE__, Woffset,
+			    (int)stbuf.st_size);
+
+                }
+
+		/*
+		 * lseek to end of file only if not fifo
+		 */
+		else if ( ! (Mode & MODE_FIFO) ) {
+		    if ((Woffset=lseek(fd, 0, SEEK_END)) == -1 ) {
+			fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, 0, SEEK_END) failed: %s\n",
+				Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
+			return -1;
+		    }
+                    else if ( Debug > 2 )
+                        printf("%s: %d DEBUG3 %s/%d: lseeked to end of file, offset %d\n",
+                            Progname, Pid, __FILE__, __LINE__, Woffset);
+		}
+
+		if ( Pattern == PATTERN_OFFSET )
+		    datapidgen(STATIC_NUM, buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_PID )
+		    datapidgen(Pid, buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_ASCII )
+		    dataasciigen(NULL, buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_RANDOM )
+		    databingen('r', buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_ALT )
+		    databingen('a', buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_CHKER )
+		    databingen('c', buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_CNTING )
+		    databingen('C', buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_ZEROS )
+		    databingen('z', buf, grow_incr, Woffset);
+		else if ( Pattern == PATTERN_ONES )
+		    databingen('o', buf, grow_incr, Woffset);
+		else
+		    dataasciigen(NULL, buf, grow_incr, Woffset);
+
+		if ( Debug > 2 )
+		    printf("%s: %d DEBUG3 %s/%d: attempting to write %d bytes\n",
+			Progname, Pid, __FILE__, __LINE__, grow_incr);
+
+		lkfile(fd, LOCK_EX, LKLVL0);	 /* get exclusive lock */
+
+/*****
+		ret=write(fd, buf, grow_incr);
+
+		tmp=tell(fd);
+
+		lkfile(fd, LOCK_UN, LKLVL0);	
+
+		if ( ret != grow_incr) {
+			fprintf(stderr, "%s: %s/%d: write failed: %s\n",
+				Progname, __FILE__, __LINE__, strerror(errno));
+			return -1;
+		}
+*****/
+
+#if NEWIO
+		ret=lio_write_buffer(fd, io_type, buf, grow_incr,
+			 SIGUSR1, &errmsg,0);
+#else
+		ret=write_buffer(fd, io_type, buf, grow_incr, 0, &errmsg);
+#endif
+
+		if( Mode & MODE_FIFO ){
+			/* If it is a fifo then just pretend the file
+			 * offset is where we think it should be.
+			 */
+			tmp = Woffset + grow_incr;
+		}
+		else{
+			if( (tmp=lseek(fd,0,SEEK_CUR)) < 0 ){ /* get offset after the write */
+				fprintf(stderr, "%s%s: %s/%d: tell(2) failed: %d  %s\n",
+					Progname, TagName, __FILE__, __LINE__, errno, strerror(errno) );
+				return -1;
+			}
+#if NEWIO
+#ifdef sgi
+			/* If this is POSIX I/O and it is via aio_{read,write}
+			 * or lio_listio then after completion of the I/O the
+			 * value of the file offset for the file is
+			 * unspecified--which means we cannot trust what
+			 * tell() told us.  Fudge it here.
+			 */
+			if( (io_type & LIO_IO_ASYNC_TYPES) || (io_type & LIO_RANDOM) ){
+				if( tmp != Woffset + grow_incr ){
+					if( Debug > 5 ){
+						printf("%s: %d DEBUG6 %s/%d: posix fudge, forcing tmp (%d) to match Woffset+grow_incr (%d)\n",
+						       Progname, Pid, __FILE__, __LINE__, tmp, Woffset+grow_incr);
+					}
+					tmp = Woffset + grow_incr;
+				}
+			}
+#endif
+#endif
+		}
+
+		lkfile(fd, LOCK_UN, LKLVL0);	
+
+		if ( ret != grow_incr ) {
+			fprintf(stderr, "%s%s: %d %s/%d: %d %s\n", 
+			    Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
+			if ( ret == -ENOSPC ) {
+				cleanup();
+				exit(2);
+			}
+			return -1;
+		}
+
+		/*
+		 * Check for a condition where the file was truncated just before
+		 * the write. 
+		 */
+		if ( tmp != Woffset + grow_incr) {
+		    /*
+		     * The offset after the write was not as expected.
+		     * This could be caused by the following:
+		     *  - file truncated after the lseek and before the write.
+		     *  - the file was written to after fstat and before the write
+		     *    and the file was opened with O_APPEND.
+		     *
+		     * The pattern written to the file will be considered corrupted.
+		     */
+		    if ( Debug > 0 && lockfile ) {
+		        printf("%s%s: %d DEBUG1 %s/%d: offset after write(%d) not as exp(%d+%d=%d)\n", 	
+			    Progname, TagName, Pid, __FILE__, __LINE__, tmp, Woffset, grow_incr, Woffset+grow_incr);
+			printf("%s%s: %d DEBUG1 %s/%d: %d Assuming file changed by another process, resetting offset:%d (expect pattern mismatch)\n",
+				Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, tmp-grow_incr);
+		    }
+		    if( Debug > 4 ){
+			printf("%s: %d DEBUG5 %s/%d: about to chop Woffset.  tmp=%d, grow_incr=%d, Woffset was %d\n",
+			       Progname, Pid, __FILE__, __LINE__, tmp, grow_incr, Woffset);
+		    }
+		    Woffset=tmp-grow_incr;
+		    if( Woffset < 0 )
+			Woffset = 0;
+		}
+
+	}  /* end of grow by write */
+
+
+	/*
+	 * Woffset - holds start of grow (start of write expect in grow by lseek)
+	 * Grow_incr - holds size of grow (write).
+	 * fsize - holds size of file before write
+	 */
+	size_grew=(Woffset + Grow_incr) - fsize;
+	if ( Debug > 1) {
+	     if ( Mode & MODE_FIFO ) {
+		printf("%s: %d DEBUG2 %s/%d: file is fifo, %d wrote %d bytes\n",
+		    Progname, Pid, __FILE__, __LINE__, Grow_incr, Iter_cnt);
+	     }
+
+	     else if ( size_grew > 0 )
+		printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), grew file by %d bytes\n",
+                        Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset, size_grew);
+	     else
+		printf("%s: %d DEBUG2 %s/%d: %d wrote %d bytes(off:%d), did not grow file\n",
+                        Progname, Pid, __FILE__, __LINE__, Iter_cnt, Grow_incr, Woffset);
+	}
+
+    	bytes_consumed += size_grew;
+	return 0;
+
+}	/* end of growfile */
+
+/***********************************************************************
+ * shrinkfile file by trunc_incr.  file can not be made smaller than
+ * size zero.  Therefore, if trunc_incr is larger than file size,
+ * file will be truncated to zero.
+ * The file descriptor current offset is assumed to be the end of the
+ * file.
+ *
+ ***********************************************************************/
+int
+shrinkfile(fd, filename, trunc_incr, trunc_inter, just_trunc)
+int fd;
+char *filename;
+int trunc_incr;
+int trunc_inter;	/* interval */
+int just_trunc;		/* lseek has already been done for you */
+{
+    static int shrink_cnt = 0;
+    int cur_offset;
+    int new_offset;
+    int ret;
+#ifdef CRAY
+    int offset;
+#endif
+
+	shrink_cnt++;
+
+	if ( trunc_inter == 0 || (shrink_cnt % trunc_inter != 0))  {
+	    if ( Debug > 3 )
+		printf("%s: %d DEBUG4 %s/%d: Not shrinking file - not time, iter=%d, cnt=%d\n",
+		    Progname, Pid, __FILE__, __LINE__, trunc_inter, shrink_cnt);
+	    return 0;	/* not this time */
+	}
+
+	if ( Mode & MODE_FIFO ) {
+	    if ( Debug > 5 )
+		printf("%s: %d DEBUG5 %s/%d: Not attempting to shrink a FIFO\n",
+		    Progname, Pid, __FILE__, __LINE__);
+	    return 0;	/* can not truncate fifo */
+	}
+
+	lkfile(fd, LOCK_EX, LKLVL0);
+
+	if ((cur_offset=lseek(fd,0,SEEK_CUR)) == -1 ) {
+	    fprintf(stderr, "%s%s: %d %s/%d: tell(%d) failed: %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, fd, strerror(errno));
+	    lkfile(fd, LOCK_UN, LKLVL0);
+	    return -1;
+	}
+
+        if ( Mode & MODE_RAND_LSEEK ) {
+            if ( max_lseek <= -1 ) {
+                if ( (new_offset=file_size(fd)) == -1 ) {
+	            lkfile(fd, LOCK_UN, LKLVL0);
+		    return -1;
+		}
+			
+		if ( new_offset < min_lseek )
+		    new_offset=min_lseek;
+		else
+                    new_offset=random_range(min_lseek, new_offset, 1, NULL);
+            }
+            else {
+                new_offset=random_range(min_lseek, max_lseek, 1, NULL);
+            }
+
+#ifdef CRAY
+            if ((offset=lseek(fd, new_offset, SEEK_SET)) == -1 ) {
+                fprintf(stderr, "%s%s: %d %s/%d: lseek(%d, %d, SEEK_SET) l3 failed: %s\n",
+                    Progname, TagName, Pid, __FILE__, __LINE__, fd, new_offset, strerror(errno));
+	        lkfile(fd, LOCK_UN, LKLVL0);
+                return -1;
+            }
+            else if ( Debug > 3 )
+                printf("%s: %d DEBUG4 %s/%d: lseeked to random offset %d\n",
+                    Progname, Pid, __FILE__, __LINE__, offset);
+    
+#endif
+        }
+
+	else {	/* remove trunc_incr from file */
+
+	    new_offset = cur_offset-trunc_incr;
+
+	    if ( new_offset < 0 )
+		new_offset=0;
+	
+#ifdef CRAY
+	    if (  lseek(fd, new_offset, SEEK_SET) == -1 ) {
+		fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, SEEK_SET) l4 failed: %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, new_offset, strerror(errno));
+	        lkfile(fd, LOCK_UN, LKLVL0);
+		return -1;
+	    }
+            else if ( Debug > 3 )
+                printf("%s: %d DEBUG4 %s/%d: lseeked to offset %d, %d bytes from end\n",
+                    Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
+#endif
+	}
+
+
+#ifdef CRAY
+	ret=trunc(fd);
+#else
+	ret=ftruncate(fd, new_offset );
+	if( (ret == 0) && (Debug > 3) ){
+                printf("%s: %d DEBUG4 %s/%d: ftruncated to offset %d, %d bytes from end\n",
+                    Progname, Pid, __FILE__, __LINE__, new_offset, trunc_incr);
+	}
+#endif
+
+	lkfile(fd, LOCK_UN, LKLVL0);
+
+	if ( ret == -1 ) {
+#ifdef CRAY
+		fprintf(stderr, "%s%s: %d %s/%d: trunc failed: %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
+#else
+		fprintf(stderr, "%s%s: %d %s/%d: ftruncate failed: %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, strerror(errno));
+#endif
+		return -1;
+	}
+
+	if ( Debug > 2 ) {
+	    printf("%s: %d DEBUG2 %s/%d: trunc file by %d bytes, to size of = %d bytes\n",
+		Progname, Pid, __FILE__, __LINE__, cur_offset-new_offset, new_offset);
+	}
+	
+
+        bytes_consumed -= (cur_offset - new_offset);
+	return 0;
+
+}	/* end of shrinkfile */
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+check_write(fd, cf_inter, filename, mode)
+int fd;
+int cf_inter;   /* check file interval */
+char *filename; /* needed for error messages */
+int mode;       /* write mode */
+{
+    int fsize;
+    static int cf_count = 0;
+    int ret = 0;
+    int tmp;
+    char *errmsg;
+    char *ptr;
+
+    cf_count++;
+
+    if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
+	if ( Debug > 4 )
+	    printf("%s: %d DEBUG5 %s/%d: no write check, not time iter=%d, cnt=%d\n",
+		Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
+	return 0;	 /* no check done */
+    }
+
+    if ( Grow_incr <= 0 ) {
+        if ( Debug > 3 )
+	    printf("%s: %d DEBUG4 %s/%d: No write validation,  Grow_incr = %d, offset = %d\n",
+	        Progname, Pid, __FILE__, __LINE__, Grow_incr, Woffset);
+        return 0;	/* no check */
+    }
+
+
+    
+    /*	
+     * Get the shared file lock.  We need to hold the lock from before
+     * we do the stat until after the read.
+     */
+    lkfile(fd, LOCK_SH, LKLVL0);
+
+    if ((fsize=file_size(fd)) == -1 )  {
+        lkfile(fd, LOCK_UN, LKLVL0);
+        return -1;
+
+    } else if ( fsize <= Woffset ) {
+	/*
+	 * The file was truncated between write and now.
+	 * The contents of our last write is totally gone, no check.
+	 */
+	if ( Debug > 1 )
+	    printf("%s%s: %d DEBUG2 %s/%d: %d File size (%d) smaller than where last wrote (%d)- no write validation\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, Woffset);
+        lkfile(fd, LOCK_UN, LKLVL0);
+        return 0;	/* no validation, but not an error */
+ 
+    } else if ( fsize < (Woffset + Grow_incr)) {
+	/*
+	 * The file was truncated between write and now.
+	 * Part of our last write has been truncated, adjust our Grow_incr
+	 * to reflect this.
+	 */
+
+	tmp=Grow_incr;
+	Grow_incr=fsize-Woffset;
+
+	if ( Debug > 1 )  {
+
+	    printf("%s%s: %d DEBUG2 %s/%d: %d fsz:%d, lost(%d)of wrt(off:%d, sz:%d), adj=%d\n",
+	    Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, fsize, tmp-Grow_incr, Woffset, tmp, Grow_incr);
+	}
+
+    }
+
+    if ( Debug > 2 )
+        printf("%s: %d DEBUG3 %s/%d: about to do write validation, offset = %d, size = %d\n",
+	    Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
+
+    if ( ! (mode & MODE_FIFO)  ) {
+
+        if ( lseek(fd, Woffset, 0) == -1 ) {
+            fprintf(stderr, "%s%s: %d %s/%d: lseek(fd, %d, 0) failed: %s\n",
+	        Progname, TagName, Pid, __FILE__, __LINE__, Woffset, strerror(errno));
+        }
+        if ( Debug > 3 )
+	    printf("%s: %d DEBUG4 %s/%d: lseeked to offset:%d\n",
+	        Progname, Pid, __FILE__, __LINE__, Woffset);
+    }
+
+    /*
+     * Read last writes data
+     */
+#if NEWIO
+    ret=lio_read_buffer(fd, io_type, Buffer, Grow_incr, SIGUSR1, &errmsg,0);
+#else
+    ret=read_buffer(fd, io_type, Buffer, Grow_incr, 0, &errmsg);
+#endif
+
+    /*
+     * report the error and debug information before releasing
+     * the file lock
+     */
+    if ( ret != Grow_incr ) {
+        fprintf(stderr, "%s%s: %d %s/%d: %d CW %s\n", Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
+        {
+	    struct stat stbuf;
+	    fstat(fd, &stbuf);
+	    if ( Debug > 2 )
+	        printf("%s%s: %d DEBUG3 %s/%d: fd:%d, offset:%d, fsize:%d, openflags:%#o\n",
+	            Progname, TagName, Pid, __FILE__, __LINE__, fd,
+		    lseek(fd,SEEK_CUR,0),
+		    (int)stbuf.st_size,
+		    Fileinfo.openflags);
+        }
+
+	lkfile(fd, LOCK_UN, LKLVL0);
+	return 1;
+    }
+
+
+    lkfile(fd, LOCK_UN, LKLVL0);
+
+    if ( Mode & MODE_GROW_BY_LSEEK ) {
+	/* check that all zeros upto last character */
+	for(ptr=Buffer; ptr < (Buffer+Grow_incr-1); ptr++) {
+	    if ( *ptr != '\0' ) {
+	        fprintf(stderr,
+		    "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
+		    Progname, TagName, Pid, __FILE__, __LINE__, 
+		    (int)(Woffset+(Grow_incr-(Buffer-ptr))),
+		    0, *ptr, filename);
+	        fflush(stderr);
+		return 1;
+	    }
+	}
+	/* check that the last char is a 'w' */
+	if ( *ptr != 'w' ) {
+	    fprintf(stderr,
+	  "%s%s: %d %s/%d: data mismatch at offset %d, exp:%#o(zerofilled), act:%#o in file %s\n",
+	        Progname, TagName, Pid, __FILE__, __LINE__, 
+		(int)(Woffset+(Grow_incr-(Buffer-ptr))), 'w',
+		*ptr, filename);
+	    fflush(stderr);
+	    return 1;
+	}
+	return 0;   /* all is well */
+	
+    }
+    else if ( Pattern == PATTERN_OFFSET )
+	ret=datapidchk(STATIC_NUM, Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_PID )
+	ret=datapidchk(Pid, Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_ASCII )
+        ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_RANDOM )
+	;	/* no check for random */
+    else if ( Pattern == PATTERN_ALT )
+        ret=databinchk('a', Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_CHKER )
+        ret=databinchk('c', Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_CNTING )
+  	ret=databinchk('C', Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_ZEROS )
+    	ret=databinchk('z', Buffer, Grow_incr, Woffset, &errmsg);
+    else if ( Pattern == PATTERN_ONES )
+    	ret=databinchk('o', Buffer, Grow_incr, Woffset, &errmsg);
+    else
+	ret=dataasciichk(NULL, Buffer, Grow_incr, Woffset, &errmsg);
+
+    if ( ret >= 0 ) {
+	fprintf(stderr, "%s%s: %d %s/%d: %d CW %s in file %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
+
+	if ( Debug > 0 )
+	    printf("%s%s: %d DEBUG1 %s/%d: **fd:%d, lk:%d, offset:%d, sz:%d open flags:%#o %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, fd, lockfile, 
+		Woffset, Grow_incr, Fileinfo.openflags, openflags2symbols(Fileinfo.openflags, ",", NULL));
+
+	fflush(stderr);
+	return 1;
+    }
+
+    if ( Debug > 6 )
+        printf("%s: %d DEBUG7 %s/%d: No corruption detected on write validation , offset = %d, size = %d\n",
+            Progname, Pid, __FILE__, __LINE__, Woffset, Grow_incr);
+
+    return 0;	/* all is well */
+}
+
+
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+check_file(fd, cf_inter, filename, no_file_check)
+int fd;
+int cf_inter;	/* check file interval */
+char *filename;	/* needed for error messages */
+int no_file_check;	/* if set, do not do file content check */
+{
+    int fsize;
+    static int cf_count = 0;
+    char *buf;
+    int ret;
+    int ret_val = 0;
+    int rd_cnt;
+    int rd_size;
+    char *errmsg;
+
+	cf_count++;
+
+	if ( cf_inter == 0 || (cf_count % cf_inter != 0)) {
+		if ( Debug > 4 )
+		    printf("%s: %d DEBUG5 %s/%d: No file check - not time, iter=%d, cnt=%d\n",
+			Progname, Pid, __FILE__, __LINE__, cf_inter, cf_count);
+		return 0;	 /* no check done */
+	}
+
+	/*
+	 * if we can't determine file content, don't bother checking
+	 */
+        if ( no_file_check ) {
+		if ( Debug > 4 )
+		    printf("%s: %d DEBUG5 %s/%d: No file check, lseek grow or random lseeks\n",
+			Progname, Pid, __FILE__, __LINE__);
+		return 0;
+	}
+
+	/*
+	 * Lock the file.  We need to have the file lock before
+	 * the stat and until after the last read to prevent
+	 * a trunc/truncate from "corrupting" our data.
+	 */
+	lkfile(fd, LOCK_SH, LKLVL0);
+	
+	if ((fsize=file_size(fd)) == -1 )  {
+	    lkfile(fd, LOCK_UN, LKLVL0);
+	    return -1;
+	}
+
+        if ( fsize == 0 ) {
+	    if ( Debug > 2 )
+            printf("%s: %d DEBUG3 %s/%d: No file validation, file size == 0\n",
+                Progname, Pid, __FILE__, __LINE__);
+
+	    lkfile(fd, LOCK_UN, LKLVL0);
+	    return 0;
+	}
+
+	if ( Debug > 2 )
+            printf("%s: %d DEBUG3 %s/%d: about to do file validation\n",
+	        Progname, Pid, __FILE__, __LINE__);
+
+        if ( fsize > MAX_FC_READ ) {
+	    /*
+	     * read the file in MAX_FC_READ chuncks.
+	     */
+
+	    if ((buf=(char *)malloc(MAX_FC_READ)) == NULL ) {
+	        fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
+		    __FILE__, __LINE__, MAX_FC_READ, strerror(errno));
+	       lkfile(fd, LOCK_UN, LKLVL0);
+	       return -1;
+	    }
+
+	    lseek(fd, 0, SEEK_SET);
+
+	    lkfile(fd, LOCK_SH, LKLVL0);  /* get lock on file before getting file size */
+
+	    rd_cnt=0;
+	    while (rd_cnt < fsize ) {
+	        if ( fsize - rd_cnt > MAX_FC_READ )
+		    rd_size=MAX_FC_READ;
+	        else
+		    rd_size=fsize - rd_cnt;
+				
+#if NEWIO
+	        ret=lio_read_buffer(fd, io_type, buf, rd_size,
+		    SIGUSR1, &errmsg,0);
+#else
+	        ret=read_buffer(fd, io_type, buf, rd_size, 0, &errmsg);
+#endif
+
+	        if (ret != rd_size ) {
+		    fprintf(stderr, "%s%s: %d %s/%d: %d CFa %s\n", 
+			Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
+		    free(buf);
+		    lkfile(fd, LOCK_UN, LKLVL0);
+		    return -1;
+	        }
+/**
+	        read(fd, buf, rd_size);
+***/
+
+	        if ( Pattern == PATTERN_OFFSET )
+	            ret=datapidchk(STATIC_NUM, buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_PID )
+	            ret=datapidchk(Pid, buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_ASCII )
+	            ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_RANDOM )
+	   	  	;  /* no checks for random */
+	        else if ( Pattern == PATTERN_ALT )
+	            ret=databinchk('a', buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_CHKER )
+	            ret=databinchk('c', buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_CNTING )
+	            ret=databinchk('C', buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_ZEROS )
+	            ret=databinchk('z', buf, rd_size, rd_cnt, &errmsg);
+	        else if ( Pattern == PATTERN_ONES )
+	            ret=databinchk('o', buf, rd_size, rd_cnt, &errmsg);
+	        else
+	            ret=dataasciichk(NULL, buf, rd_size, rd_cnt, &errmsg);
+		
+		    
+	        if ( ret >= 0 ) {
+		    fprintf(stderr,
+		        "%s%s: %d %s/%d: %d CFp %s in file %s\n",
+		        Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
+		    fflush(stderr);
+		    ret_val=1;
+		    lkfile(fd, LOCK_UN, LKLVL0);
+		    break;
+	        }
+	        rd_cnt += rd_size;
+	    }
+
+	    lkfile(fd, LOCK_UN, LKLVL0);
+
+	    free(buf);
+
+	}
+	else {
+	    /*
+	     * Read the whole file in a single read 
+	     */
+	    if((buf=(char *)malloc(fsize)) == NULL ) {
+			fprintf(stderr, "%s%s: %s/%d: malloc(%d) failed: %s\n", Progname, TagName,
+				__FILE__, __LINE__, fsize, strerror(errno));
+			fflush(stderr);
+			return -1;
+	    }
+
+	    lseek(fd, 0, SEEK_SET);
+
+/****
+	    read(fd, buf, fsize);
+****/
+#if NEWIO
+	    ret=lio_read_buffer(fd, io_type, buf, fsize, SIGUSR1, &errmsg,0);
+#else
+	    ret=read_buffer(fd, io_type, buf, fsize, 0, &errmsg);
+#endif
+
+	    /* unlock the file as soon as we can */
+	    lkfile(fd, LOCK_UN, LKLVL0);
+
+
+	    if ( ret != fsize ) {
+		fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s\n", 
+		    Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg);
+		ret_val=1;
+	    }
+	    else  {
+	        if ( Pattern == PATTERN_OFFSET )
+		    ret=datapidchk(STATIC_NUM, buf, fsize, 0, &errmsg);
+	        else if ( Pattern == PATTERN_PID )
+		    ret=datapidchk(Pid, buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_ASCII )
+		    ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_RANDOM )
+		    ;	/* no check for random */
+		else if ( Pattern == PATTERN_ALT )
+		    ret=databinchk('a', buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_CHKER )
+		    ret=databinchk('c', buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_CNTING )
+		    ret=databinchk('C', buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_ZEROS )
+		    ret=databinchk('z', buf, fsize, 0, &errmsg);
+		else if ( Pattern == PATTERN_ONES )
+		    ret=databinchk('o', buf, fsize, 0, &errmsg);
+		else
+		    ret=dataasciichk(NULL, buf, fsize, 0, &errmsg);
+
+		if ( ret >= 0 ) {
+		    fprintf(stderr, "%s%s: %d %s/%d: %d CFw %s in file %s\n",
+			Progname, TagName, Pid, __FILE__, __LINE__, Iter_cnt, errmsg, filename);
+		    fflush(stderr);
+		    ret_val=1;
+		}
+	    }
+	    free(buf);
+	}
+
+	return ret_val;
+
+}	/* end of check_file */
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+file_size(int fd)
+{
+    struct stat sb;
+
+        if (fstat(fd, &sb) < 0) {
+            fprintf(stderr, "%s%s: %d %s/%d: Unable to fstat(%d, &buf), errno:%d %s\n",
+                Progname, TagName, Pid, __FILE__, __LINE__, fd, errno, strerror(errno));
+	    return -1;
+	
+        }
+
+        return sb.st_size;
+}
+
+/***********************************************************************
+ *  do file lock/unlock action.
+ ***********************************************************************/
+int
+lkfile(int fd, int operation, int lklevel)
+{
+    char *errmsg;
+
+    
+    if ( lockfile == lklevel) {
+	
+        if ( Debug > 5 ) {
+	    switch (operation) {
+ 	    case LOCK_UN:
+	        printf("%s: %d DEBUG6 %s/%d: Attempting to release lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+
+ 	    case LOCK_SH:
+	        printf("%s: %d DEBUG6 %s/%d: Attempting to get read/shared lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+
+ 	    case LOCK_EX:
+	        printf("%s: %d DEBUG6 %s/%d: Attempting to get write/exclusive lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+	    }
+	}
+
+	/*
+	 * Attempt to get/release desired lock.
+	 * file_lock will attempt to do action over and over again until
+	 * either an unretryable error or the action is completed.
+	 */
+
+        if ( file_lock(fd, operation, &errmsg) != 0 ) {
+	    printf("%s%s: %d %s/%d: Unable to perform lock operation. %s\n",
+		Progname, TagName, Pid, __FILE__, __LINE__, errmsg);
+
+	    /* do we count this as an error? handle_error();  */
+	    return -1;
+        }
+
+        if ( Debug > 2 ) {
+	    switch (operation) {
+ 	    case LOCK_UN:
+	        printf("%s: %d DEBUG3 %s/%d: Released lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+
+ 	    case LOCK_SH:
+	        printf("%s: %d DEBUG3 %s/%d: Got read/shared lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+
+ 	    case LOCK_EX:
+	        printf("%s: %d DEBUG3 %s/%d: Got write/exclusive lock on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, fd);
+		break;
+	
+	    default:
+	        printf("%s: %d DEBUG3 %s/%d: Completed action %d on fd %d\n", 
+		    Progname, Pid, __FILE__, __LINE__, operation, fd);
+		break;
+	    }
+	}
+   }
+
+   return 0;
+}
+
+#ifndef linux
+/***********************************************************************
+ *
+ ***********************************************************************/
+int
+pre_alloc(fd, size)
+int fd;
+int size;
+{
+
+#ifdef CRAY
+    long avl;
+
+        if ( ialloc(fd, size, IA_CONT, &avl) == -1 ) {
+                fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: ialloc failed: %d  %s\n",
+			Progname, TagName,
+                        __FILE__, __LINE__, errno, strerror(errno));
+                return -1;
+        }
+#endif
+
+#ifdef sgi
+    struct flock f;
+
+	f.l_whence = 0;
+	f.l_start = 0;
+	f.l_len = size;
+
+	/* non-zeroing reservation */
+	if( fcntl( fd, F_RESVSP, &f ) == -1 ){
+                fprintf(stderr, "%s%s %s/%d: Unable to pre-alloc space: fcntl(F_RESVSP) failed: %d  %s\n",
+			Progname, TagName,
+                        __FILE__, __LINE__, errno, strerror(errno));
+		return -1;
+	}
+
+#endif
+
+	return 0;
+}
+#endif