New additions:
 - tst_ library code.
 - new quickhit tests
 - more general code cleanup
diff --git a/INSTALL b/INSTALL
index f9b02a6..c6cdac2 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,4 +1,4 @@
-$Id: INSTALL,v 1.2 2000/05/08 20:31:30 alaffin Exp $
+$Id: INSTALL,v 1.3 2000/07/27 17:13:18 alaffin Exp $
 
 Building and Installation of Test Tools.
 
@@ -8,9 +8,6 @@
 were not necessary.  Instead, a minimal approach was taken and the
 build process reflects that.  Simply:
 
-cd <tool>
 make
 
-At the time of release, <tool> is doio.  The build process builds the
-tools in question and leaves them among the sources.  There are no
-install routines, yet.
+This does two things, builds the test libraries and then the tests.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..926df0b
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,15 @@
+
+CFLAGS+=
+LDFLAGS+=
+
+all: libltp.a
+	@$(MAKE) -C doio $@
+	@$(MAKE) -C tests $@
+
+libltp.a:
+	@$(MAKE) -C lib $@
+
+clean:
+	@$(MAKE) -C lib $@
+	@$(MAKE) -C doio $@
+	@$(MAKE) -C tests $@
diff --git a/doio/Makefile b/doio/Makefile
index 18f7fb8..27240eb 100644
--- a/doio/Makefile
+++ b/doio/Makefile
@@ -1,23 +1,21 @@
 
-CFLAGS+=
-LDFLAGS+=
-TARGETS=doio iogen rwtest growfiles
+CFLAGS+= -I../include
+LDFLAGS+= -L../lib -lltp
 
+TARGETS=doio growfiles rwtest iogen
 SRCS=$(wildcard *.c)
 OBJS=$(patsubst %.c,%.o,$(SRCS))
 
 all: $(TARGETS)
 
-doio: doio.o random_range.o string_to_tokens.o pattern.o write_log.o
-	$(CC) -o $@ $^ $(LDFLAGS)
+doio: doio.o
+	$(CC) -o $@ $^ -I. $(CFLAGS) $(LDFLAGS)
 
-growfiles: growfiles.o dataascii.o open_flags.o tlibio.o random_range.o \
-           file_lock.o datapid.o databin.o forker.o string_to_tokens.o 
-	$(CC) -o $@ $^ $(LDFLAGS)
+growfiles: growfiles.o
+	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
-iogen: iogen.o str_to_bytes.o string_to_tokens.o random_range.o \
-       open_flags.o
-	$(CC) -o $@ $^ $(LDFLAGS)
+iogen: iogen.o
+	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
 rwtest: rwtest.ks doio iogen
 	cp rwtest.ks rwtest
diff --git a/doio/growfiles.c b/doio/growfiles.c
index 1911fe7..f61091b 100644
--- a/doio/growfiles.c
+++ b/doio/growfiles.c
@@ -81,6 +81,7 @@
 #include <string.h>
 #include "dataascii.h"
 #include "random_range.h"
+#include "databin.h"
 
 #ifdef CRAY
 #include <sys/panic.h>
diff --git a/include/databin.h b/include/databin.h
new file mode 100644
index 0000000..b71fbc0
--- /dev/null
+++ b/include/databin.h
@@ -0,0 +1,44 @@
+#ifndef _DATABIN_H_
+#define _DATABIN_H_
+
+/*******************************************************************************
+* NAME
+*       databingen - fill a buffer with a data pattern
+*
+* SYNOPSIS
+*       (void) databingen(mode, buffer, bsize, offset)
+*       int     mode;
+*       char    *buffer;
+*       int     bsize;
+*	int 	offset;
+*
+* DESCRIPTION
+*       datagen fills the buffer pointed to by 'buffer' with 'bsize' bytes
+*       of data of the form indicated by 'mode'.  
+*	All modes (expect r -random) are file offset based.
+*	This allows more than process to do writing to the file without
+*	corrupting it if the same modes were used.
+*	They data modes to choose from, these are:
+*
+*               'a' - writes an alternating bit pattern (i.e. 0x5555555...)
+*
+*               'c' - writes a checkerboard pattern (i.e. 0xff00ff00ff00...)
+*
+*		'C' - writes counting pattern (i.e. 0 - 07, 0 - 07, ...);
+*
+*		'o' - writes all bits set (i.e. 0xffffffffffffff...)
+*
+*		'z' - writes all bits cleared (i.e. 0x000000000...);
+*
+*               'r' - writes random integers
+*
+* RETURN VALUE
+*       None
+*
+*******************************************************************************/
+
+void databingen( int mode, unsigned char *buffer, int bsize, int offset );
+
+void databinchedk( int mode, unsigned char *buffer, int bsize, int offset, char **errmsg);
+
+#endif
diff --git a/include/file_lock.h b/include/file_lock.h
new file mode 100644
index 0000000..8c9a948
--- /dev/null
+++ b/include/file_lock.h
@@ -0,0 +1,40 @@
+/*
+ * 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/
+ */
+#ifndef _FILE_LOCK_H_
+#define _FILE_LOCK_H_
+
+extern char Fl_syscall_str[128];
+
+int file_lock( int , int, char ** );
+int record_lock( int , int , int , int , char ** );
+
+#endif /* _FILE_LOCK_H_ */
diff --git a/include/forker.h b/include/forker.h
new file mode 100644
index 0000000..eb0acae
--- /dev/null
+++ b/include/forker.h
@@ -0,0 +1,63 @@
+/*
+ * 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/
+ */
+#ifndef _FORKER_H_
+#define _FORKER_H_
+
+#define MAX_PIDS	4098
+
+extern int Forker_pids[MAX_PIDS];      /* holds pids of forked processes */
+extern int Forker_npids;               /* number of entries in Forker_pids */
+
+/*
+ * This function will fork and the parent will exit zero and
+ * the child will return.  This will orphan the returning process
+ * putting it in the background.
+ */
+int background( char * );
+
+/*
+ * Forker will fork ncopies-1 copies of self. 
+ *
+ * arg 1: Number of copies of the process to be running after return.
+ *        This value minus one is the number of forks performed. 
+ * arg 2: mode: 0 - all children are first generation descendents.
+ *              1 - each subsequent child is a descendent of another
+ *              descendent, resulting in only one direct descendent of the
+ *              parent and each other child is a child of another child in
+ *              relation to the parent.
+ * arg 3: prefix: string to preceed any error messages.  A value of NULL
+ *              results in no error messages on failure.
+ * returns: returns to parent the number of children forked.
+ */
+int forker( int , int , char * );
+
+#endif /* _FORKER_H_ */
diff --git a/include/mc_getopt.h b/include/mc_getopt.h
new file mode 100644
index 0000000..d574fb5
--- /dev/null
+++ b/include/mc_getopt.h
@@ -0,0 +1,40 @@
+
+/* $Header: /cvsroot/ltp/ltp/include/Attic/mc_getopt.h,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+/*
+ *	(C) COPYRIGHT CRAY RESEARCH, INC.
+ *	UNPUBLISHED PROPRIETARY INFORMATION.
+ *	ALL RIGHTS RESERVED.
+ */
+
+#ifndef __MC_GETOPT_H__
+#define __MC_GETOPT_H__ 1
+
+/*
+ * Possible return value of mc_getopt
+ */
+
+#define MC_UNKNOWN_OPTION       "UNKNOWN_OPTION"
+#define MC_AMBIGUOUS_OPTION     "AMBIGUOUS_OPTION"
+#define MC_MISSING_OPTARG       "MISSING_OPTARG"
+#define MC_DONE                 NULL
+
+/*
+ * Mc_getopt flags argument bits
+ */
+#define MC_FULL_TOKEN_MATCH     01
+#define MC_CASE_INSENSITIVE     02
+
+extern int   mc_optind;
+extern char *mc_optarg;
+extern char *mc_optopt;
+
+/*
+ * Prototypes
+ */
+
+extern char *mc_getopt(int argc, char * const argv[], int flags, const char *optstring);
+extern char *mc_getoptv(int argc, char * const argv[], int flags, int nopts, char * const opt_arr[]);
+
+#endif  /* __MC_GETOPT_H__ */
+
diff --git a/include/pattern.h b/include/pattern.h
new file mode 100644
index 0000000..74f841c
--- /dev/null
+++ b/include/pattern.h
@@ -0,0 +1,90 @@
+/*
+ * 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/
+ */
+#ifndef _PATTERN_H_
+#define _PATTERN_H_
+
+/*
+ * pattern_check(buf, buflen, pat, patlen, patshift)
+ *
+ * Check a buffer of length buflen against repeated occurrances of
+ * a pattern whose length is patlen.  Patshift can be used to rotate
+ * the pattern by patshift bytes to the left.
+ *
+ * Patshift may be greater than patlen, the pattern will be rotated by
+ * (patshift % patshift) bytes.
+ *
+ * pattern_check returns -1 if the buffer does not contain repeated
+ * occurrances of the indicated pattern (shifted by patshift).
+ *
+ * The algorithm used to check the buffer relies on the fact that buf is 
+ * supposed to be repeated copies of pattern.  The basic algorithm is
+ * to validate the first patlen bytes of buf against the pat argument
+ * passed in - then validate the next patlen bytes against the 1st patlen
+ * bytes - the next (2*patlen) bytes against the 1st (2*pathen) bytes, and
+ * so on.  This algorithm only works when the assumption of a buffer full
+ * of repeated copies of a pattern holds, and gives MUCH better results
+ * then walking the buffer byte by byte.
+ *
+ * Performance wise, It appears to be about 5% slower than doing a straight
+ * memcmp of 2 buffers, but the big win is that it does not require a
+ * 2nd comparison buffer, only the pattern.
+ */
+int pattern_check( char * , int , char * , int , int );
+
+/*
+ * pattern_fill(buf, buflen, pat, patlen, patshift)
+ *
+ * Fill a buffer of length buflen with repeated occurrances of
+ * a pattern whose length is patlen.  Patshift can be used to rotate
+ * the pattern by patshift bytes to the left.
+ *
+ * Patshift may be greater than patlen, the pattern will be rotated by
+ * (patshift % patlen) bytes.
+ *
+ * If buflen is not a multiple of patlen, a partial pattern will be written
+ * in the last part of the buffer.  This implies that a buffer which is
+ * shorter than the pattern length will receive only a partial pattern ...
+ *
+ * pattern_fill always returns 0 - no validation of arguments is done.
+ *
+ * The algorithm used to fill the buffer relies on the fact that buf is 
+ * supposed to be repeated copies of pattern.  The basic algorithm is
+ * to fill the first patlen bytes of buf with the pat argument
+ * passed in - then copy the next patlen bytes with the 1st patlen
+ * bytes - the next (2*patlen) bytes with the 1st (2*pathen) bytes, and
+ * so on.  This algorithm only works when the assumption of a buffer full
+ * of repeated copies of a pattern holds, and gives MUCH better results
+ * then filling the buffer 1 byte at a time.
+ */
+int pattern_fill( char * , int , char * , int , int );
+
+#endif
diff --git a/include/rmobj.h b/include/rmobj.h
new file mode 100644
index 0000000..4808ca2
--- /dev/null
+++ b/include/rmobj.h
@@ -0,0 +1,12 @@
+#ifndef _RMOBJ_H_
+#define _RMOBJ_H_
+
+/*
+ * rmobj() - Remove the specified object.  If the specified object is a
+ *           directory, recursively remove everything inside of it.  If
+ *           there are any problems, set errmsg (if it is not NULL) and
+ *           return -1.  Otherwise return 0.
+ */
+int rmobj( char *object , char **errmesg );
+
+#endif
diff --git a/include/test.h b/include/test.h
new file mode 100644
index 0000000..c7872fb
--- /dev/null
+++ b/include/test.h
@@ -0,0 +1,216 @@
+/*
+ * 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/
+ */
+
+/* $Id: test.h,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+#ifndef __TEST_H__
+#define __TEST_H__
+
+#include <stdio.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define TPASS    0    /* Test passed flag */
+#define TFAIL    1    /* Test failed flag */
+#define TBROK    2    /* Test broken flag */
+#define TWARN    4    /* Test warning flag */
+#define TRETR    8    /* Test retire flag */
+#define TINFO    16   /* Test information flag */
+#define TCONF    32   /* Test not appropriate for configuration flag */
+
+/*
+ * To determine if you are on a Umk or Unicos system,
+ * use sysconf(_SC_CRAY_SYSTEM).  But since _SC_CRAY_SYSTEM
+ * is not defined until 90, it will be define here if not already
+ * defined.
+ * if ( sysconf(_SC_CRAY_SYSTEM) == 1 )
+ *    on UMK
+ * else   # returned 0 or -1 
+ *    on Unicos
+ * This is only being done on CRAY systems.
+ */
+#ifdef CRAY
+#ifndef _SC_CRAY_SYSTEM
+#define _SC_CRAY_SYSTEM  140
+#endif /* ! _SC_CRAY_SYSTEM */
+#endif /* CRAY */
+
+/*
+ * Ensure that NUMSIGS is defined.
+ * It should be defined in signal.h or sys/signal.h on
+ * UNICOS/mk and IRIX systems.   On UNICOS systems,
+ * it is not defined, thus it is being set to UNICOS's NSIG.
+ * Note:  IRIX's NSIG (signals are 1-(NSIG-1)) 
+ *      is not same meaning as UNICOS/UMK's NSIG  (signals 1-NSIG)
+ */
+#ifndef NUMSIGS
+#define NUMSIGS NSIG
+#endif
+
+
+/* defines for unexpected signal setup routine (set_usig.c) */
+#define FORK    1		/* SIGCLD is to be ignored */
+#define NOFORK  0		/* SIGCLD is to be caught */
+#define DEF_HANDLER 0	/* tells set_usig() to use default signal handler */
+
+/*
+ * The following defines are used to control tst_res and t_result reporting.
+ */
+
+#define TOUTPUT	   "TOUTPUT"		/* The name of the environment variable */
+					/* that can be set to one of the following */
+					/* strings to control tst_res output */
+					/* If not set, TOUT_VERBOSE_S is assumed */
+
+#define TOUT_VERBOSE_S  "VERBOSE"	/* All test cases reported */
+#define TOUT_CONDENSE_S "CONDENSE"	/* ranges are used where identical messages*/
+					/* occur for sequential test cases */
+#define TOUT_NOPASS_S   "NOPASS"	/* No pass test cases are reported */
+#define TOUT_DISCARD_S  "DISCARD"	/* No output is reported */
+
+#define TST_NOBUF	"TST_NOBUF"	/* The name of the environment variable */
+					/* that can be set to control whether or not */
+					/* tst_res will buffer output into 4096 byte */
+					/* blocks of output */
+					/* If not set, buffer is done.  If set, no */
+					/* internal buffering will be done in tst_res */
+					/* t_result does not have internal buffering */
+
+/*
+ * The following defines are used to control tst_tmpdir, tst_wildcard and t_mkchdir
+ */
+
+#define TDIRECTORY  "TDIRECTORY"	/* The name of the environment variable */
+					/* that if is set, the value (directory) */
+					/* is used by all tests as their working */
+					/* directory.  tst_rmdir and t_rmdir will */
+					/* not attempt to clean up. */
+					/* This environment variable should only */
+					/* be set when doing system testing since */
+					/* tests will collide and break and fail */
+					/* because of setting it. */
+
+#define TEMPDIR	"/tmp"			/* This is the default temporary directory. */
+					/* The environment variable TMPDIR is */
+					/* used prior to this valid by tempnam(3). */
+					/* To control the base location of the */
+					/* temporary directory, set the TMPDIR */
+					/* environment variable to desired path */
+
+/*
+ * The following contains support for error message passing.
+ * See test_error.c for details.
+ */
+#define  TST_ERR_MESG_SIZE      1023    /* max size of error message */
+#define  TST_ERR_FILE_SIZE      511     /* max size of module name used by compiler */
+#define  TST_ERR_FUNC_SIZE      127     /* max size of func name */
+
+typedef struct {
+    int  te_line;                       /* line where last error was reported.  Use */
+                                        /* "__LINE__" and let compiler do the rest */
+    int  te_level;                      /* If set, will prevent current stored */
+                                        /* error to not be overwritten */
+    char te_func[TST_ERR_FUNC_SIZE+1];  /* name of function of last error */
+                                        /* Name of function or NULL */
+    char te_file[TST_ERR_FILE_SIZE+1];  /* module of last error.  Use */
+                                        /* "__FILE__" and let compiler do the rest */
+    char te_mesg[TST_ERR_MESG_SIZE+1];  /* string of last error */
+
+} _TST_ERROR;
+
+extern _TST_ERROR Tst_error;            /* defined in test_error.c */
+#if __STDC__
+extern void tst_set_error(char *file, int line, char *func, char *fmt, ...);
+#else
+extern void tst_set_error();
+#endif
+extern void tst_clear_error();
+
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify the number of iterations.
+ * It is supported in parse_opts.c and USC_setup.c.
+ */
+#define USC_ITERATION_ENV       "USC_ITERATIONS"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify to iteration until desired time
+ * in floating point seconds has gone by.
+ * Supported in USC_setup.c.
+ */
+#define USC_LOOP_WALLTIME	"USC_LOOP_WALLTIME"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify that no functional checks are wanted.
+ * It is supported in parse_opts.c and USC_setup.c.
+ */
+#define USC_NO_FUNC_CHECK	"USC_NO_FUNC_CHECK"
+
+/*
+ * The following define contains the name of an environmental variable
+ * that can be used to specify the delay between each loop iteration.
+ * The value is in seconds (fractional numbers are allowed).
+ * It is supported in parse_opts.c.
+ */
+#define USC_LOOP_DELAY		"USC_LOOP_DELAY"
+
+
+#ifndef CRAY
+/*
+ * The following prototypes are needed to remove compile errors
+ * on IRIX systems when compiled with -n32 and -64.
+ */
+extern void tst_res(int ttype, char *fname, char *arg_fmt, ...);
+extern void tst_resm(int ttype, char *arg_fmt, ...);
+extern void tst_brk(int ttype, char *fname, void (*func)(), 
+							char *arg_fmt, ...);
+extern void tst_brkloop(int ttype, char *fname, void (*func)(), 
+							char *arg_fmt, ...);
+extern void tst_brkm(int ttype, void (*func)(), char *arg_fmt, ...);
+extern void tst_brkloopm(int ttype, void (*func)(), char *arg_fmt, ...);
+
+extern int  tst_environ();
+extern void tst_exit();
+extern void tst_flush();
+
+/* prototypes for the t_res.c functions */
+extern void t_result(char *tcid, int tnum, int ttype, char *tmesg);
+extern void tt_exit();
+extern int  t_environ();
+extern void t_breakum(char *tcid, int total, int typ, char *msg, void (*fnc)());
+
+#endif /* ! CRAY */
+
+#endif	/* end of __TEST_H__ */
diff --git a/include/usctest.h b/include/usctest.h
new file mode 100644
index 0000000..1d57920
--- /dev/null
+++ b/include/usctest.h
@@ -0,0 +1,373 @@
+/*
+ * 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/
+ */
+
+/* $Id: usctest.h,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+/**********************************************************
+ * 
+ *    IRIX/Linux Feature Test and Evaluation - Silicon Graphics, Inc.
+ * 
+ *    FUNCTION NAME 	: usctest.h
+ * 
+ *    FUNCTION TITLE	: System Call Test Macros
+ * 
+ *    SYNOPSIS:
+ *	See DESCRIPTION below.
+ * 
+ *    AUTHOR		: William Roske
+ * 
+ *    INITIAL RELEASE	: UNICOS 7.0
+ * 
+ *    DESCRIPTION
+ * 	TEST(SCALL) - calls a system call
+ *	TEST_VOID(SCALL) - same as TEST() but for syscalls with no return value.
+ *	TEST_CLEANUP - print the log of errno return counts if STD_ERRNO_LOG 
+ *		       is set.
+ *	TEST_PAUSEF(HAND) - Pause for SIGUSR1 if the pause flag is set.
+ *		      Use "hand" as the interrupt handling function
+ *	TEST_PAUSE -  Pause for SIGUSR1 if the pause flag is set.
+ *		      Use internal function to do nothing on signal and go on.
+ *	TEST_LOOPING(COUNTER) - Conditional to check if test should
+ *		      loop.  Evaluates to TRUE (1) or FALSE (0).
+ *	TEST_ERROR_LOG(eno) - log that this errno was received,
+ *		      if STD_ERRNO_LOG is set.
+ *	TEST_EXP_ENOS(array) - set the bits in TEST_VALID_ENO array at
+ *		      positions specified in integer "array"
+ *
+ *    RETURN VALUE
+ * 	TEST(SCALL) - Global Variables set:
+ *			int TEST_RETURN=return code from SCALL
+ *			int TEST_ERRNO=value of errno at return from SCALL
+ * 	TEST_VOID(SCALL) - Global Variables set:
+ *			int TEST_ERRNO=value of errno at return from SCALL
+ *	TEST_CLEANUP - None.
+ *	TEST_PAUSEF(HAND) -  None.
+ *	TEST_PAUSE -  None.
+ *	TEST_LOOPING(COUNTER) - True if COUNTER < STD_LOOP_COUNT or
+ *			STD_INFINITE is set.
+ *	TEST_ERROR_LOG(eno) - None
+ *	TEST_EXP_ENOS(array) - None
+ *
+ *    KNOWN BUGS
+ *      If you use the TEST_PAUSE or TEST_LOOPING macros, you must
+ *	link in parse_opts.o, which contains the code for those functions.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+
+#ifndef  __USCTEST_H__
+#define __USCTEST_H__ 1
+
+#ifndef _SC_CLK_TCK
+#include <unistd.h>
+#endif
+
+#include <sys/param.h>
+
+/* 
+ * Ensure that PATH_MAX is defined 
+ */
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX  MAXPATHLEN
+#else
+#define PATH_MAX  1024
+#endif
+#endif
+
+#ifndef CRAY
+#ifndef BSIZE 
+#define BSIZE BBSIZE
+#endif
+#endif
+
+/*
+ * Define standard options.
+ * These value should match the values in USC_common.h.
+ */
+
+#define NOFUNC		"nofunc"		/* no func check flag */
+#define ITERATIONS	"iterations:"		/* # iterations */
+#define DURATION	"duration:"		/* walltime floating point */
+#define DELAY		"delay:"		/* delay each iteration */
+#define TIMING		"timing"		/* sys call timing flag */
+#define ERRNO_LOGGING	"errno_logging"		/* errno logging flag */
+#define SETUP_PAUSE	"pause_for_sigusr1"	/* wait sigusr1 signal in setup */
+#define COPIES          "copies:"               /* number copies */
+#define USC_HELP	"Help"			/* basic help */
+
+#define  ITERATIONS_HELP  \
+"  -iterations cnt : Execute test \"cnt\" times (Default is 1).\n\
+                    A value of 0 will cause the test to run indefinitely.\n"
+
+#define DELAY_HELP  \
+"  -delay secs     : Delay for \"secs\" seconds each iteration (def 0.0)\n"
+
+#define DURATION_HELP \
+"  -duration secs  : Iterate for elapsed time of \"secs\" (def 0.0)\n"
+
+#define NOFUNC_HELP  \
+"  -nofunc         : Turn OFF Functional testing.  Just exercise the system call.\n"
+
+#define SETUP_PAUSE_HELP \
+"  -pause_for_sigusr1    : Pause for SIGUSR1 before entering testing loop.\n"
+
+#define TIMING_HELP \
+"  -timing         : Turn ON timing statistics (min, max and avg time in system call).\n"
+
+#define ERRNO_LOGGING_HELP  \
+"  -errno_logging  : Turn ON errno logging.\n"
+
+#define COPIES_HELP  \
+"  -copies num     : fork so there num copies (def 1)\n"
+
+#define USC_HELP_HELP \
+"  -Help           : parse_opts standard help and exit.\n"
+
+/*
+ * Defines used for genating usage
+ */
+#define NOFUNC_USE  	    "[-nofunc]"
+#define ITERATIONS_USE      "[-iterations cnt]"
+#define DURATION_USE        "[-duration secs]"
+#define DELAY_USE           "[-delay secs]"
+#define TIMING_USE          "[-timing]"
+#define ERRNO_LOGGING_USE   "[-errno_logging]"
+#define SETUP_PAUSE_USE     "[-pause_for_sigusr1]"
+#define COPIES_USE          "[-copies num]"
+#define HELP_USE            "[-Help]"
+
+/***********************************************************************
+ * Define option_t structure type.
+ * Entries in this struct are used by the parse_opts routine
+ * to indicate valid options and return option arguments
+ ***********************************************************************/
+typedef struct {		
+  char *option;      	/* Valid option string (one option only) like "a:" */
+  int  *flag;		/* pointer to location to set true if option given */
+  char **arg;		/* pointer to location to place argument, if needed */
+} option_t;
+
+/***********************************************************************
+ * The following globals are defined in parse_opts.c but must be 
+ * externed here because they are used in the macros defined below.
+ ***********************************************************************/
+extern int STD_FUNCTIONAL_TEST,	/* turned off by -f to not do functional test */
+           STD_TIMING_ON,	/* turned on by -t to print timing stats */
+           STD_PAUSE,		/* turned on by -p to pause before loop */
+           STD_INFINITE,	/* turned on by -c0 to loop forever */
+           STD_LOOP_COUNT,	/* changed by -cn to set loop count to n */
+           STD_ERRNO_LOG,	/* turned on by -e to log errnos returned */
+           STD_ERRNO_LIST[],	/* counts of errnos returned.  indexed by errno */
+	   STD_COPIES,
+	   STD_argind;
+
+extern float STD_LOOP_DURATION, /* wall clock time to iterate */
+	     STD_LOOP_DELAY;    /* delay time after each iteration */
+
+#define USC_MAX_ERRNO	2000
+    
+/**********************************************************************
+ * Prototype for parse_opts routine
+ **********************************************************************/
+extern char *parse_opts();
+
+/*
+ * define a structure 
+ */
+struct usc_errno_t {
+    int flag;
+};
+
+/***********************************************************************
+ ****
+ **** 
+ ****
+ **********************************************************************/
+#ifdef  _USC_LIB_
+
+extern int TEST_RETURN;
+extern int TEST_ERRNO;
+
+#else
+/***********************************************************************
+ * Global array of bit masks to indicate errnos that are expected.
+ * Bits set by TEST_EXP_ENOS() macro and used by TEST_CLEANUP() macro.
+ ***********************************************************************/
+struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
+
+/***********************************************************************
+ * Globals for returning the return code and errno from the system call
+ * test macros.
+ ***********************************************************************/
+int TEST_RETURN;
+int TEST_ERRNO;
+
+/***********************************************************************
+ * temporary variables for determining max and min times in TEST macro
+ ***********************************************************************/
+long btime, etime, tmptime;	
+
+#endif  /* _USC_LIB_ */
+
+/***********************************************************************
+ * structure for timing accumulator and counters 
+ ***********************************************************************/
+struct tblock {
+    long tb_max;
+    long tb_min;
+    long tb_total;
+    long tb_count;
+};
+
+/***********************************************************************
+ * The following globals are externed here so that they are accessable
+ * in the macros that follow.
+ ***********************************************************************/
+extern struct tblock tblock;
+extern void STD_go();
+extern int (*_TMP_FUNC)(void);
+extern char *STD_opts_help();
+extern char *STD_opts();
+
+
+/***********************************************************************
+ * TEST: calls a system call 
+ * 
+ * parameters:
+ *	SCALL = system call and parameters to execute
+ *
+ ***********************************************************************/
+#define TEST(SCALL) TEST_RETURN = (unsigned) SCALL;  TEST_ERRNO=errno;
+
+/***********************************************************************
+ * TEST_VOID: calls a system call
+ * 
+ * parameters:
+ *	SCALL = system call and parameters to execute
+ *
+ * Note: This is IDENTICAL to the TEST() macro except that it is intended
+ * for use with syscalls returning no values (void syscall()).  The 
+ * Typecasting nothing (void) into an unsigned integer causes compilation
+ * errors.
+ *
+ ***********************************************************************/
+#define TEST_VOID(SCALL)  SCALL; TEST_ERRNO=errno;
+
+/***********************************************************************
+ * TEST_CLEANUP: print system call timing stats and errno log entries
+ * to stdout if STD_TIMING_ON and STD_ERRNO_LOG are set, respectively.
+ * Do NOT print ANY information if no system calls logged.
+ * 
+ * parameters:
+ *	none
+ *
+ ***********************************************************************/
+#define TEST_CLEANUP 	\
+if ( STD_ERRNO_LOG ) {						\
+	for (tmptime=0; tmptime<USC_MAX_ERRNO; tmptime++) {		\
+	     if ( STD_ERRNO_LIST[tmptime] )	{			\
+	         if ( TEST_VALID_ENO[tmptime].flag )			\
+		     tst_resm(TINFO, "ERRNO %d:\tReceived %d Times",	\
+			      tmptime, STD_ERRNO_LIST[tmptime]);	\
+	         else							\
+		     tst_resm(TINFO,					\
+			      "ERRNO %d:\tReceived %d Times ** UNEXPECTED **",	\
+			      tmptime, STD_ERRNO_LIST[tmptime]);	\
+	     }								\
+	}								\
+}
+
+/***********************************************************************
+ * TEST_PAUSEF: Pause for SIGUSR1 if the pause flag is set.
+ * 		 Set the user specified function as the interrupt
+ *		 handler instead of "STD_go"
+ * 
+ * parameters:
+ *	none
+ *
+ ***********************************************************************/
+#define TEST_PAUSEF(HANDLER) 					\
+if ( STD_PAUSE ) { 					\
+    _TMP_FUNC = (int (*)())signal(SIGUSR1, HANDLER); 	\
+    pause(); 						\
+    signal(SIGUSR1, (void (*)())_TMP_FUNC);		\
+}
+
+/***********************************************************************
+ * TEST_PAUSE: Pause for SIGUSR1 if the pause flag is set.
+ *	       Just continue when signal comes in.
+ * 
+ * parameters:
+ *	none
+ *
+ ***********************************************************************/
+#define TEST_PAUSE usc_global_setup_hook();
+
+/***********************************************************************
+ * TEST_LOOPING now call the usc_test_looping function.
+ * The function will return 1 if the test should continue
+ * iterating.
+ *
+ ***********************************************************************/
+#define TEST_LOOPING usc_test_looping
+
+/***********************************************************************
+ * TEST_ERROR_LOG(eno): log this errno if STD_ERRNO_LOG flag set
+ * 
+ * parameters:
+ *	int eno: the errno location in STD_ERRNO_LIST to log.
+ *
+ ***********************************************************************/
+#define TEST_ERROR_LOG(eno)		\
+    if ( STD_ERRNO_LOG )		\
+        if ( eno < USC_MAX_ERRNO )		\
+            STD_ERRNO_LIST[eno]++;	\
+
+
+/***********************************************************************
+ * TEST_EXP_ENOS(array): set the bits associated with the nput errnos
+ *	in the TEST_VALID_ENO array.
+ * 
+ * parameters:
+ *	int array[]: a zero terminated array of errnos expected.
+ *
+ ***********************************************************************/
+#define TEST_EXP_ENOS(array)				\
+    tmptime=0;						\
+    while (array[tmptime] != 0) {			\
+	if (array[tmptime] < USC_MAX_ERRNO)		\
+	    TEST_VALID_ENO[array[tmptime]].flag=1;	\
+	tmptime++;					\
+    }
+					
+
+#endif  /* end of __USCTEST_H__ */
diff --git a/lib/Makefile b/lib/Makefile
new file mode 100644
index 0000000..5cda105
--- /dev/null
+++ b/lib/Makefile
@@ -0,0 +1,12 @@
+
+CFLAGS+= -I../include
+LDFLAGS+=
+TARGET=libltp.a
+SRCS=$(wildcard *.c)
+OBJS=$(patsubst %.c,%.o,$(SRCS))
+
+$(TARGET): $(OBJS)
+	$(AR) -cr $@ $^    
+
+clean:
+	rm -f $(TARGET) $(OBJS)
diff --git a/lib/databin.c b/lib/databin.c
index d11aa68..f09c2c8 100644
--- a/lib/databin.c
+++ b/lib/databin.c
@@ -33,6 +33,7 @@
 #include <sys/param.h>
 #include <string.h> /* memset */
 #include <stdlib.h> /* rand */
+#include "databin.h"
 
 #if UNIT_TEST
 #include <malloc.h>
@@ -40,42 +41,6 @@
 
 static char Errmsg[80];
 
-/*******************************************************************************
-* NAME
-*       databingen - fill a buffer with a data pattern
-*
-* SYNOPSIS
-*       (void) databingen(mode, buffer, bsize, offset)
-*       int     mode;
-*       char    *buffer;
-*       int     bsize;
-*	int 	offset;
-*
-* DESCRIPTION
-*       datagen fills the buffer pointed to by 'buffer' with 'bsize' bytes
-*       of data of the form indicated by 'mode'.  
-*	All modes (expect r -random) are file offset based.
-*	This allows more than process to do writing to the file without
-*	corrupting it if the same modes were used.
-*	They data modes to choose from, these are:
-*
-*               'a' - writes an alternating bit pattern (i.e. 0x5555555...)
-*
-*               'c' - writes a checkerboard pattern (i.e. 0xff00ff00ff00...)
-*
-*		'C' - writes counting pattern (i.e. 0 - 07, 0 - 07, ...);
-*
-*		'o' - writes all bits set (i.e. 0xffffffffffffff...)
-*
-*		'z' - writes all bits cleared (i.e. 0x000000000...);
-*
-*               'r' - writes random integers
-*
-* RETURN VALUE
-*       None
-*
-*******************************************************************************/
-
 void
 databingen (mode, buffer, bsize, offset)
 int mode;	/* either a, c, r, o, z or C */
diff --git a/lib/file_lock.c b/lib/file_lock.c
index 00eb582..a67cdc3 100644
--- a/lib/file_lock.c
+++ b/lib/file_lock.c
@@ -39,6 +39,7 @@
 #include <errno.h>
 #include <sys/sysmacros.h>
 #include <string.h> /* memset, strerror */
+#include "file_lock.h"
 
 extern int errno;
 
diff --git a/lib/forker.c b/lib/forker.c
index cc849a2..e1e6b74 100644
--- a/lib/forker.c
+++ b/lib/forker.c
@@ -31,7 +31,7 @@
  */
 /**************************************************************
  *
- *    OS Testing - Cray Research, Inc.
+ *    OS Testing - Silicon Graphics, Inc.
  *
  *    FUNCTION NAME     : forker
  *			  background
@@ -114,19 +114,18 @@
 #include <errno.h>
 #include <unistd.h> /* fork, getpid, sleep */
 #include <string.h>
+#include "forker.h"
 
 extern int errno;
 
-#define MAX_PIDS	4098
-
-int Forker_pids[MAX_PIDS];	/* holds pids of forked processes */
-int Forker_npids=0;	/* number of entries in Forker_pids */
+int Forker_pids[MAX_PIDS];      /* holds pids of forked processes */
+int Forker_npids=0;             /* number of entries in Forker_pids */
 
 /***********************************************************************
  *
  * This function will fork and the parent will exit zero and
  * the child will return.  This will orphan the returning process
- * putting you in the background.
+ * putting it in the background.
  *
  * Return Value
  *   0 : if fork did not fail
diff --git a/lib/mc_getopt.c b/lib/mc_getopt.c
new file mode 100644
index 0000000..07a9b9f
--- /dev/null
+++ b/lib/mc_getopt.c
@@ -0,0 +1,601 @@
+/* $Header: /cvsroot/ltp/ltp/lib/Attic/mc_getopt.c,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+/*
+ *	(C) COPYRIGHT CRAY RESEARCH, INC.
+ *	UNPUBLISHED PROPRIETARY INFORMATION.
+ *	ALL RIGHTS RESERVED.
+ */
+/**********************************************************
+ * 
+ *    OS Testing - Cray Research, Inc.
+ * 
+ *    FUNCTION NAME 	: mc_getopt and mc_getoptv
+ * 
+ *    FUNCTION TITLE	: multiple character option parsing like getopt(3)
+ * 
+ *    SYNOPSIS:
+ *	char *
+ *	mc_getopt(argc, argv, flags, optstring)
+ *	int argc;
+ *	char *argv[];
+ *	int flags;
+ *	char *optstring;
+ *
+ *	mc_getoptv(argc, argv, flags, nopts, opt_arr)
+ *	int argc;
+ *	char *argv[];
+ *	int flags;
+ *      int nopts;
+ *	char *opt_arr[];
+ *
+ *	extern int mc_optind;
+ *	extern char *mc_optarg;
+ *	extern char *mc_optopt;
+ *
+ * 
+ *    AUTHOR		: Richard Logan
+ * 
+ *    DATE		: 01/96
+ * 
+ *    DESCRIPTION
+ *
+ *	The mc_getopt() and mc_getoptv() functions are command line parsers.
+ *	The argc parameter specifies the argument count and the argv parameter
+ *	specifies the argument array.  The optstring argument contains a string
+ *      of recognized option strings; if an option string is followed by a
+ *      colon, the option takes an argument.  Options are whitespace seperated.
+ *	A option string can be a single character or a word.
+ *
+ *	The opt_arr array contains nopts elements.  Each option element in
+ *      opt_arr must be NULL terminated string; if an option string is followed 
+ *      by a colon, the option takes an argument.  A option string can be a 
+ *	single character or a word.  opt_arr must be at least nopts elements
+ *	in size.
+ *
+ *	The variable mc_optind specifies the index of the next element of the
+ *	argv parameter to be processed.  It is initialized to 1, and the
+ *	mc_getopt() function updates it as each element of argv is processed.
+ *
+ *	The mc_getopt() function returns the optstring string that
+ *	uniquely matches the next element of the argv parameter.
+ *	If the option string takes an argument, the mc_getopt()
+ *      function sets the mc_optarg variable to point to the option string 
+ *	argument according to the following rules:
+ *
+ *	o If the argv's option was the last option string in the string, 
+ *	mc_optarg contains
+ *	the next element of the argv array, and the mc_optind variable is
+ *	incremented by 2.  If the resulting value of mc_optind is greater than
+ *	or equal to argc, the mc_getopt() function returns an MC_MISSING_OPTARG
+ *
+ *	o Otherwise, mc_optarg points to the string following the option
+ *	character in that element of the argv parameter, and the mc_optind
+ *	variable is incremented by 1.
+ *
+ *	If any of the following conditions are true when the mc_getopt()
+ *	function is called, the mc_getopt() function returns MC_DONE without
+ *	changing the mc_optind variable:
+ *
+ *	o argv[mc_optind] is a null pointer
+ *
+ *	o *argv[mc_optind] is not the character '-'
+ *
+ *	o argv[mc_optind] points to the string "-"
+ *
+ *	If the argv[mc_optind] parameter points to the "--" string, the mc_getopt
+ *	function returns MC_DONE after incrementing the mc_optind variable.
+ *
+ *	The flags argument can be used to change how an argv option string
+ *	is compared to optstring.  The flags argument is a bitmask.
+ *	The only two bits defined thus far are:
+ *	
+ *	o MC_FULL_TOKEN_MATCH
+ *	o MC_CASE_INSENSITIVE
+ *
+ *	How flags bits can be used to affect mc_getopt()'s actions:
+ *
+ *	o Without the MC_FULL_TOKEN_MATCH bit set, if the argv string exactly
+ *	matches one optstring option, that option will be returned.  
+ *	Otherwise, if the argv string matches the beginning of only one
+ *	optstring option, that optstring option is returned.
+ *
+ *	o With the MC_FULL_TOKEN_MATCH bit set, the argv string must exactly
+ *	match the optstring, excluding the colon ":".  When word options are
+ *	being used, the exact word option string must be in argv to be
+ *	reconized as a match.
+ *
+ *	o Without the MC_CASE_INSENSITIVE bit set, case comparisons are used.
+ *	The -I option is different than the -i option.
+ *
+ *	o With the MC_CASE_INSENSITIVE bit set, all strings are converted to
+ *	lower case before comparisons are made.  This means the -I and -i
+ *	option are the same.  The returned option string will be all lowercase.
+ *	The mc_getoptv() function assumes the option string in the opt_arr
+ *	is already converted to lowercase.
+ *
+ *	If the mc_getopt(v) function encounters an option string that is not
+ *	contained in the optstring parameter, it returns MC_UNKNOWN_OPTION
+ *	string.  If it detects a missing option argument, it returns 
+ *	MC_MISSING_OPTARG string.  Unlike getopt, mc_getopt() will NOT print
+ *	message if an argv option string is not found in optstring.
+ *
+ *	If the argv option string matches more than one optstring strings,
+ *	MC_AMBIGUOUS_OPTION string is returned.
+ *
+ *      mc_getopt(v) will not modify argv or optstring.  It will strdup optstring
+ *	and update some character pointers.  The optstring is parsed only
+ *	once whenever a mc_optind is set to one or once a MC_DONE was returned.
+ *      The strdup space is freed before a MC_DONE is returned.  This means that
+ *	optstring is ignored on all subquent calls.
+ *
+ *
+ *    RETURN VALUES
+ *	The mc_getopt(v) function returns the next option string specified on
+ *	the command line.  The string will be the string as listed in optstring.
+ *
+ *	MC_MISSING_OPTARG is returned if the mc_getopt(v) function detects a
+ *	missing argument.
+ *
+ *	MC_UNKNOWN_OPTION is returned if the mc_getopt(v) function encounters an
+ *	option string not in the optstring argument.
+ *
+ *	MC_AMBIGUOUS_OPTION is returned if the mc_getopt(v) function encounters
+ *	option string that matches two or more optstring argument and there
+ *	is not a single exact match.  This condition could occur if
+ *	flags argument does not have the MC_FULL_TOKEN_MATCH bit set and
+ *	the option string is not a unique string as defined in optstring.
+ *	(i.e.  -it, when optsting contains " iterations:  italic")  It
+ *	could also occur if an optstring option is duplicated
+ *	(i.e.  -iterations, when optsting contains " iterations: iterations").
+ *
+ *	Otherwise, the mc_getopt(v) function returns MC_DONE when all command
+ *	line options are parsed.
+ *
+ *    LIMITATIONS
+ *	mc_getopt() has an internal limit of 256 options
+ *	allowed in optstring.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/param.h>
+
+#include "mc_getopt.h"
+
+#ifndef DEBUG
+#define DEBUG 0		/* used for debugging */
+#endif
+
+/*
+ * Externally accessable variables.
+ */
+int mc_optind = 1;	/* index to next argv token */
+char *mc_optarg; 	/* pointer to option argument string */
+
+char *mc_optopt;	/* pointer to argv or opt_arg option string */
+
+/*
+ * Ensure PATH_MAX is defined.
+ */
+#ifndef PATH_MAX
+#define PATH_MAX	1023
+#endif
+
+/*
+ * Define the max number of option strings that can exist in optstring.
+ */
+#define MAX_OPTIONS	256
+
+/*******************************************************************************
+ *
+ *******************************************************************************/
+#if __STDC__
+char *
+mc_getopt(int argc, char * const argv[], int flags, const char *optstring)
+#else
+char *
+mc_getopt(argc, argv, flags, optstring)
+int argc;
+char * const argv[];
+int flags;
+const char *optstring;
+#endif  /* __STDC__ */
+{
+
+    static char *opt_arr[MAX_OPTIONS]; /* array of pointers to option strings */
+
+    static char *optstr=NULL;  /* strdup'ed optstring, ! NULL, means */
+			/* space allocated */
+    static int nopts;	/* number of opt_arr elements */
+
+    char *token;	/* used in optstring parsing and string comparision */
+    char *cc;		/* used in optstring parsing and converting to lower case */
+    int optarr_ind=0;	/* index into opt_arr */
+    
+
+#if DEBUG > 0
+printf(" Entering mc_getopt, argc = %d, mc_optind = %d, flags = %#o, optstring = '%s'\n",
+    argc, mc_optind, flags, optstring);
+#endif
+
+    if ( mc_optind >= argc || argv[mc_optind] == NULL ||
+	argv[mc_optind][0] != '-' || argv[mc_optind][1] == '\0' ) {
+
+#if DEBUG > 1
+printf(" no more options to process\n");
+#endif
+	if ( optstr != NULL )
+	    free(optstr);
+	return MC_DONE;
+
+    } else if ( strcmp(argv[mc_optind], "--") == 0 ) {
+#if DEBUG > 1
+printf(" option --, no more options to process\n");
+#endif
+	mc_optind++;
+	if ( optstr != NULL )
+	    free(optstr);
+	return MC_DONE;	/* we are done */
+    }
+
+    /*
+     *  We have new argv - reset info for optstr.
+     *  Otherwise old optstr is used.
+     */
+    if ( optstr == NULL || mc_optind == 1 ) {
+
+        /*
+         * copy string so that we don't modify user given string
+         */
+	if ( optstr != NULL )
+	    free(optstr);	/* free old strdup'ed space */
+
+	optstr=strdup(optstring);   /* copy string */
+	nopts=0;
+	optarr_ind=0;
+
+	token=optstr;
+        /*
+         * walk through optstr option string (whitespace separated).
+         */
+        for (;;) {
+	
+            /* skip preceeding separator chars */
+            for (; *token && isspace(*token); token++);
+	
+	    if ( ! *token )	/* no more tokens */
+		break;
+
+            cc = token;	/* start of option string */
+
+            /*
+             * find first separator character after token
+             */
+            for (; *cc && !isspace(*cc); cc++) {
+		/*
+		 * If doing case insensitive comparisons, make all
+		 * optstr characters lowercase.
+		 */
+		if ( flags & MC_CASE_INSENSITIVE && isupper(*cc) )
+		    *cc = tolower(*cc);
+	    }
+
+	    opt_arr[optarr_ind++] = token;
+
+	    if ( ! *cc)	/* no more tokens */
+		break;
+    
+            *cc = '\0';   /* null terminate */
+
+	    token = ++cc;
+
+        }  /* end of for loop */
+
+	nopts=optarr_ind;
+#if DEBUG > 1
+	printf("nopts = %d\n", nopts);
+
+	for(optarr_ind=0; optarr_ind<nopts; optarr_ind++)
+   	    printf(" optstring option (index %2d) : %14s\n",
+	        optarr_ind, opt_arr[optarr_ind]);
+#endif
+    }  /* end of processs optstring */
+
+    /*
+     * Call mc_getoptv with the optstring in opt_arr array format
+     */
+
+    cc=mc_getoptv(argc, argv, flags, nopts, opt_arr);
+
+    if ( optstr != NULL && strcmp(cc, MC_DONE) == 0 )
+        free(optstr);
+
+    return cc;
+}
+
+/***********************************************************************
+ *
+ ***********************************************************************/
+#if __STDC__
+char *
+mc_getoptv(int argc, char * const argv[], int flags, int nopts,
+					char * const opt_arr[])
+#else
+char *
+mc_getoptv(argc, argv, flags, nopts, opt_arr)
+int argc;
+char * const argv[];
+int flags;
+int nopts;
+char * const opt_arr[];
+#endif  /* __STDC__ */
+{
+    char *token;        /* used in string comparision */
+    char *cc;           /* used in converting to lower case */
+    char *cptr;
+    int optarr_ind=0;   /* index into opt_arr */
+
+    int found;          /* count of argv option partical matches to optstr options */
+    int exact;          /* count of argv option exact matches */
+    int cnt;            /* counter */
+    int ind;            /* index into opt_arr for matched option */
+    int reqarg;		/* if opt_arr[ind] requires an arg */
+
+#if DEBUG > 1
+printf(" In mc_getoptv: argv[%d] = %s\n", mc_optind, argv[mc_optind]);
+#endif
+
+    if ( mc_optind >= argc || argv[mc_optind] == NULL ||
+        argv[mc_optind][0] != '-' || argv[mc_optind][1] == '\0' ) {
+
+#if DEBUG > 1
+printf(" no more options to process\n");
+#endif
+        return MC_DONE;
+
+    } else if ( strcmp(argv[mc_optind], "--") == 0 ) {
+#if DEBUG > 1
+printf(" option --, no more options to process\n");
+#endif
+        mc_optind++;
+        return MC_DONE; /* we are done */
+    }
+
+    if ( flags & MC_CASE_INSENSITIVE ) {
+        mc_optopt = &argv[mc_optind][1];
+
+        /*
+         * If doing case insensitive comparison,
+         * copy argv token and make it all lowercase.
+         */
+        cc = token = strdup(&argv[mc_optind++][1]);
+        for( ;  *cc; cc++)
+            if ( isupper(*cc) )
+                *cc = tolower(*cc);
+
+    } else {
+        token = &argv[mc_optind++][1];
+        mc_optopt = token;
+    }
+
+    found=0;
+    exact=0;
+    reqarg=0;
+
+    /*
+     * Compare token to each option string.
+     * Do not stop once a match is found.  There maybe multiple matches.
+     */
+    for(optarr_ind=0; optarr_ind<nopts; optarr_ind++) {
+
+	/*
+	 * compare opt_arr[optarr_ind] to token
+	 * character by character.
+	 */
+
+	cc=token;
+	cptr=opt_arr[optarr_ind];
+	cnt=0;	/* count of match characters */
+
+	while ( *cc && *cptr && *cc++ == *cptr++ ) {
+	    cnt++;
+	}
+
+        /*
+	 * Determine if argv option partially matched opstring option.
+	 */
+	if ( cnt && *cc == '\0' ) { 
+	    /*
+	     * Determine if argv option fully matched opstring option.
+             * Remember that opt_arr[optarr_ind] can have optional ":".
+	     */
+	    if ( *cptr == ':' || *cptr == '\0' ) {
+                exact++;
+                found++;
+                ind=optarr_ind;
+		if ( *cptr == ':' ) {
+		    reqarg=1;
+		} else {
+		    reqarg=0;
+		}
+
+	    /*
+	     * If not doing full token matches, count this partial match.
+	     */
+	    } else if ( ! (flags & MC_FULL_TOKEN_MATCH) ) {
+	        found++;
+                if ( ! exact ) { /* exact matches are used over partial */
+                    ind=optarr_ind;
+
+		    /*
+		     * Determine if this option string ends with ":",
+		     * requiring an argument.
+		     * Find the end of the string first, this
+		     * would allow a colon in the string.
+		     */
+		    while ( *cptr ) 
+			cptr++;
+
+		    if ( *(cptr-1) == ':' ) {
+			reqarg=1;
+		    } else {
+			reqarg=0;
+		    }
+		}
+	    }
+	}    /* end partial match */
+    }   /* end option loop */
+
+#if DEBUG > 2
+printf("optarr_ind = %d, ind = %d, found = %d, exact = %d\n",
+    optarr_ind, ind, found, exact);
+#endif
+
+    /* if doing case insensitive comparison, free space */
+    if ( flags & MC_CASE_INSENSITIVE ) {
+        free(token);
+    }
+
+    if ( found == 0 ) {
+#if DEBUG > 1
+printf("argv option string not found in optstr returning MC_UNKNOWN_OPTION :%s\n", 
+MC_UNKNOWN_OPTION);
+#endif
+        /* argv option string not found in optstr */
+        return MC_UNKNOWN_OPTION;
+
+    } else if ( exact == 1 || found == 1 ) {
+        /* option is uniquely matched */
+#if DEBUG > 1
+printf("argv option found a string match\n");
+#endif
+
+
+        if ( reqarg ) { 	/* option requires argument */
+
+            /* If option argument is missing, return MC_MISSING_OPTARG */
+            if ( mc_optind >= argc ) {
+#if DEBUG > 2
+printf("returning MC_MISSING_OPTARG: %s\n", MC_MISSING_OPTARG);
+#endif
+                return MC_MISSING_OPTARG;
+            }
+
+            mc_optarg = argv[mc_optind++];
+
+        }
+
+#if DEBUG > 2
+printf("returning the option (index %d) %s\n", ind, opt_arr[ind]);
+#endif
+        /* return the full mc_getopt option string */
+        return opt_arr[ind];
+
+    } else {
+
+        /*
+         * This condition will be encountered if
+         * argv option string matches more than optstr option string.
+         * The user could not have entered a unique option string or
+         * the optstr has a duplicate option entered.
+         */
+#if DEBUG > 1
+printf("argv option string not unique\n");
+#endif
+        return MC_AMBIGUOUS_OPTION;
+    }
+}
+
+
+
+#ifdef UNIT_TEST
+
+/****
+ ****  The following code is provided as a basic unit test.
+ ****  Compile this code with UNIT_TEST set and a executable
+ ****  command will be generated.  The optstring is hardcoded,
+ ****  but the programs argc and argv are given to mc_getopt.
+ ****/
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+
+#define	OPTSTR1		" iterate: Testpause I: i "
+    extern int mc_optind;
+    extern char *mc_optarg;
+
+    char *ret;
+    int ind=0;
+
+	mc_optind=1;
+	mc_optarg=NULL;
+	printf("*********** flags = 0, optstr = %s\n", OPTSTR1);
+	while ( (ret=mc_getopt(argc, argv, 0, OPTSTR1)) != MC_DONE ) {
+	   if ( mc_optarg != NULL )
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = %s\n",
+		    ret, mc_optopt, mc_optind, mc_optarg);
+	   else
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = NULL\n",
+		    ret, mc_optopt, mc_optind);
+	   ind++;
+	   mc_optarg=NULL;
+	}
+	if ( mc_optind < argc )
+	    printf("mc_getopt is done,  mc_optind = %d (argv[%d] = %s)\n",
+		mc_optind, mc_optind, argv[mc_optind]);
+	else
+	    printf("mc_getopt is done,  mc_optind = %d (no arguments)\n", mc_optind);
+
+	printf("******************************************************\n");
+
+	
+	mc_optind=1;
+	mc_optarg=NULL;
+	printf("*********** flags = MC_FULL_TOKEN_MATCH, optstr = %s\n", OPTSTR1);
+	while ( (ret=mc_getopt(argc, argv, MC_FULL_TOKEN_MATCH, OPTSTR1)) != MC_DONE ) {
+	   if ( mc_optarg != NULL )
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = %s\n",
+		    ret, mc_optopt, mc_optind, mc_optarg);
+	   else
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = NULL\n",
+		    ret, mc_optopt, mc_optind);
+	   mc_optarg=NULL;
+	}
+	if ( mc_optind < argc )
+	    printf("mc_getopt is done,  mc_optind = %d (argv[%d] = %s)\n",
+		mc_optind, mc_optind, argv[mc_optind]);
+	else
+	    printf("mc_getopt is done,  mc_optind = %d (no arguments)\n", mc_optind);
+
+	mc_optind=1;
+	mc_optarg=NULL;
+	printf("*********** flags = MC_CASE_INSENSITIVE, optstr = %s\n", OPTSTR1);
+	while ( (ret=mc_getopt(argc, argv, MC_CASE_INSENSITIVE, OPTSTR1)) != MC_DONE ) {
+	   if ( mc_optarg != NULL )
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = %s\n",
+		    ret, mc_optopt, mc_optind, mc_optarg);
+	   else
+	        printf("mc_getopt returned %16s, mc_optopt = %8s, mc_optind = %d, mc_optarg = NULL\n",
+		    ret, mc_optopt, mc_optind);
+	   mc_optarg=NULL;
+	}
+	if ( mc_optind < argc )
+	    printf("mc_getopt is done,  mc_optind = %d (argv[%d] = %s)\n",
+		mc_optind, mc_optind, argv[mc_optind]);
+	else
+	    printf("mc_getopt is done,  mc_optind = %d (no arguments)\n", mc_optind);
+
+	return 0;
+}
+
+/**
+Use the following unit test cmd line arguments:
+ -i -itera -4 -I -5 -i -IteRate -6 arg
+
+ ***/
+
+#endif /* UNIT_TEST */
diff --git a/lib/open_flags.c b/lib/open_flags.c
index 0fa76e9..eed39ee 100644
--- a/lib/open_flags.c
+++ b/lib/open_flags.c
@@ -31,7 +31,7 @@
  */
 /**************************************************************
  *
- *    OS Testing - Cray Research, Inc.
+ *    OS Testing - Silicon Graphics, Inc.
  *
  *    FUNCTION NAME     : parse_open_flags
  *			  openflags2symbols
diff --git a/lib/parse_opts.c b/lib/parse_opts.c
new file mode 100644
index 0000000..af5e6dd
--- /dev/null
+++ b/lib/parse_opts.c
@@ -0,0 +1,1206 @@
+/*
+ * 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/
+ */
+
+/* $Id: parse_opts.c,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+/**********************************************************
+ * 
+ *    OS Testing - Silicon Graphics, Inc.
+ * 
+ *    FUNCTION NAME 	: parse_opts
+ * 
+ *    FUNCTION TITLE	: parse standard & user options for system call tests
+ * 
+ *    SYNOPSIS:
+ *	#include "usctest.h"
+ *
+ * 	char *parse_opts(ac, av, user_optarr)
+ *	int    ac;
+ * 	char **av;
+ *	option_t user_optarr[];
+ * 
+ *    AUTHOR		: William Roske/Richard Logan
+ * 
+ *    INITIAL RELEASE	: UNICOS 7.0
+ * 
+ *    DESCRIPTION
+ * 	The parse_opts library routine takes that argc and argv parameters
+ *	recevied by main() and an array of structures defining user options.
+ *	It parses the command line setting flag and argument locations
+ *      associated with the options.  It uses mc_getoptv to do the actual
+ *      cmd line parsing.
+ *
+ *      This module contains the functions usc_global_setup_hook and
+ *      usc_test_looping, which are called by marcos defined in usctest.h.
+ * 
+ *    RETURN VALUE
+ * 	parse_opts returns a pointer to an error message if an error occurs.
+ *	This pointer is (char *)NULL if parsing is successful.
+ * 
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <sys/signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+
+#ifdef _CRAYMPP
+#include <mpp/shmem.h>
+#endif  /* _CRAYMPP */
+
+#if UNIT_TEST
+#include <time.h>
+#endif /* UNIT_TEST */
+
+#include "test.h"
+#define _USC_LIB_   1	/* indicates we are the library to the usctest.h include */
+#include "usctest.h"
+#include "mc_getopt.h"
+
+#ifndef USC_COPIES
+#define USC_COPIES   "USC_COPIES"
+#endif
+
+#ifndef UNIT_TEST
+#define UNIT_TEST	0
+#endif
+
+#ifndef DEBUG
+#define DEBUG	0
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+extern int errno;
+
+/* The timing information block. */
+struct tblock tblock={0,((long) -1)>>1,0,0};
+
+/* temp variable to store old signal action to be restored after pause */
+int (*_TMP_FUNC)(void);
+
+/* Define flags and args for standard options */
+int STD_FUNCTIONAL_TEST=1,	/* flag indicating to do functional testing code */
+    STD_TIMING_ON=0,		/* flag indicating to print timing stats */
+    STD_PAUSE=0,		/* flag indicating to pause before actual start, */
+				/* for contention mode */
+    STD_INFINITE=0,		/* flag indciating to loop forever */
+    STD_LOOP_COUNT=1,		/* number of iterations */
+    STD_COPIES=1,		/* number of copies */
+    STD_ERRNO_LOG=0;		/* flag indicating to do errno logging */
+
+float STD_LOOP_DURATION=0.0,    /* duration value in fractional seconds */
+      STD_LOOP_DELAY=0.0;	/* loop delay value in fractional seconds */
+
+
+char **STD_opt_arr = NULL;	/* array of option strings */
+int    STD_nopts=0,		/* number of elements in STD_opt_arr */
+       STD_argind=1;		/* argv index to next argv element */
+				/* (first argument) */
+				/* To getopt users, it is like optind */
+
+/*
+ * The following variables are to support system testing additions.
+ */
+static int  STD_TP_barrier=0;	/* flag to do barrier in TEST_PAUSE */
+				/* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
+static int  STD_LP_barrier=0;	/* flag to do barrier in TEST_LOOPING */
+				/* 2 - wait_barrier(), 3 - set_barrier(), * - barrier() */
+static int  STD_TP_shmem_sz=0;	/* shmalloc this many words per pe in TEST_PAUSE */
+static int  STD_LD_shmem=0; 	/* flag to do shmem_puts and shmem_gets during delay */
+static int  STD_LP_shmem=0; 	/* flag to do shmem_puts and gets during TEST_LOOPING */
+static int  STD_LD_recfun=0;	/* do recressive function calls in loop delay */
+static int  STD_LP_recfun=0;	/* do recressive function calls in TEST_LOOPING */
+static int  STD_TP_sbrk=0;	/* do sbrk in TEST_PAUSE */
+static int  STD_LP_sbrk=0;	/* do sbrk in TEST_LOOPING */
+static char *STD_start_break=0; /* original sbrk size */
+#ifdef _CRAYMPP
+static long *STD_shmem=NULL;	/* array of shmalloc space */
+static int  MyPE=-1, Npe=-1;	/* */
+#endif
+static int  Debug=0;
+
+/*
+ * Structure for usc_recressive_func argument
+ */
+struct usc_bigstack_t {
+   char space[4096];
+};
+
+static struct usc_bigstack_t *STD_bigstack=NULL;
+
+static int add_option(char *option, char **opt_arr[], int *nopts);
+static int rm_option(char *option, char **opt_arr[], int *nopts);
+
+
+/*
+ * Counter of errnos returned (-e option).  Indexed by errno.
+ * Make the array USC_MAX_ERRNO long.  That is the first Fortran
+ * Lib errno.  No syscall should return an errno that high.
+ */
+int STD_ERRNO_LIST[USC_MAX_ERRNO];
+
+/* define the string length for Mesg and Mesg2 strings */
+#define STRLEN 2048
+
+static char Mesg[STRLEN];	/* holds possible return string */
+static char Mesg2[STRLEN];	/* holds possible return string */
+static void usc_recressive_func();
+
+/*
+ * Define bits for options that might have env variable default
+ */
+#define  OPT_iteration 		01
+#define  OPT_nofunccheck	02
+#define  OPT_duration		04
+#define  OPT_delay		010
+#define  OPT_copies		020
+
+
+/**********************************************************************
+ * parse_opts: 
+ **********************************************************************/
+char *
+parse_opts(int ac, char **av, option_t *user_optarr)
+{
+    int found;		/* flag to indicate that an option specified was */
+			/* found in the user's list */
+    char chr;		/* used in converting option arguments */
+    int k;		/* scratch integer for returns and short time usage */
+    float  ftmp;	/* tmp float for parsing env variables */
+    char *ptr;		/* used in getting env variables */
+    int options=0;	/* no options specified */
+    int ind;		/* index */
+    int cnt;		/* counter */
+    int num;		/* size of a string */
+    char *opt;		/* return of mc_getoptv */
+
+    /*
+     * If not the first time this function is called, release the old STD_opt_arr
+     * vector.
+     */
+
+    if ( STD_opt_arr != NULL ) {
+	free(STD_opt_arr);
+	STD_opt_arr=NULL;
+    }
+
+    /*
+     * Define standard options known to the parse_opts package.
+     * Each option is added to the end of the STD_opt_arr array.
+     */
+    if ( add_option(ITERATIONS, &STD_opt_arr, &STD_nopts) == -1)
+	return Mesg2;
+    if ( add_option(DELAY, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(DURATION, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(NOFUNC, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(SETUP_PAUSE, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(COPIES, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(USC_HELP, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(TIMING, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+    if ( add_option(ERRNO_LOGGING, &STD_opt_arr, &STD_nopts) == -1 )
+	return Mesg2;
+
+    /* validate input array of options and build STD_opt_arr */
+
+    if ( user_optarr != (option_t *) NULL ) {
+	for(cnt=0; user_optarr[cnt].option != (char *) NULL; cnt++ ) {
+	    /*
+	     * Determine if user option already in STD_opt_arr.
+             * If the option is listed twice (in even numbers), it is disabled.
+	     * To disable the option, remove it from the option from STD_opt_arr.
+	     */
+	    for(ind=0; ind<STD_nopts; ind++) {
+		if (strcmp(user_optarr[cnt].option, STD_opt_arr[ind]) == 0 ) {
+		    /*
+		     * user option already in STD_opt_arry, which means to
+		     * disable that option.  Remove that option from STD_opt_arr.
+		     */
+    		    rm_option(user_optarr[cnt].option, &STD_opt_arr, &STD_nopts);
+		    break;
+		}
+	    }
+
+	    /*
+             * User's option is not already in STD_opt_arr so it needs to be
+	     * added.
+	     */
+	    if ( ind >= STD_nopts ) {
+		num=strlen(user_optarr[cnt].option);
+
+        	/*
+		 * If the last character is ":", make sure arg pointer
+		 * is not NULL.
+	         */
+		if ( user_optarr[cnt].option[num-1] == ':' ) {
+
+		    if ( user_optarr[cnt].arg == NULL ) {
+                        sprintf(Mesg2,
+                            "parse_opts: ERROR - option:\"%s\" expecting argument, NO POINTER GIVEN",
+                            user_optarr[cnt].option);
+                        return(Mesg2);
+		    }
+
+		} else {
+		   /*
+		    * The option does not require an argument, make sure 
+		    * user_optarr[cnt].flag is pointing to something.
+		    * The flag is optional when argument is required.
+		    */
+		    if ( user_optarr[cnt].flag == NULL ) {
+			sprintf(Mesg2,
+		    	    "parse_opts: ERROR - option:\"%s\" NO FLAG LOCATION GIVEN",
+                             user_optarr[cnt].option);
+                    return(Mesg2);
+
+		    }
+		}
+
+		/*
+		 * Add the users option to the STD_opt_arr array.
+		 */
+		if ( add_option(user_optarr[cnt].option, &STD_opt_arr, &STD_nopts) == -1 )
+		    return Mesg2;
+		
+	    }    /* new option */
+	}    /* end of options loop */
+    }    /* end of user options */
+
+#if DEBUG > 1
+    printf("STD_nopts = %d\n", STD_nopts);
+#endif
+
+
+    /*
+     *  Loop through av parsing options.
+     */
+    while ( (opt=mc_getoptv(ac, av, 0, STD_nopts, STD_opt_arr)) != MC_DONE ) {
+
+	STD_argind = mc_optind;
+
+#if DEBUG > 0
+	printf("parse_opts: mc_getoptv returned '%s'\n", opt);
+#endif
+        if ( strcmp(opt, MC_UNKNOWN_OPTION) == 0 ) {
+	    sprintf(Mesg2,
+                    "parse_opts: ERROR - Unknown option: \"-%s\"",
+		    mc_optopt);
+	    return Mesg2;
+
+ 	} else if ( strcmp(opt, MC_AMBIGUOUS_OPTION) == 0 ) {
+	    sprintf(Mesg2,
+                    "parse_opts: ERROR - option \"-%s\" is not unique, be more specific",
+		    mc_optopt);
+	    return Mesg2;
+
+	} else if  (  strcmp(opt, MC_MISSING_OPTARG) == 0 ) {
+	    sprintf(Mesg2,
+                    "parse_opts: ERROR - option \"-%s\" is missing its argument",
+		    mc_optopt);
+	    return Mesg2;
+
+    	} else if ( strcmp(opt, ITERATIONS) == 0 ) {
+            options |= OPT_iteration;
+            if ( sscanf(mc_optarg, "%i%c", &STD_LOOP_COUNT, &chr) != 1) {
+                sprintf(Mesg2,
+		    "parse_opts: ERROR - Argument for -%s option MUST be NUMERIC",
+		    mc_optopt);
+                return(Mesg2);
+	    }
+
+            if ( STD_LOOP_COUNT == 0 )   /* if arg is 0, set infinite loop flag */
+                STD_INFINITE=1;
+
+    	} else if ( strcmp(opt, DELAY) == 0 ) {
+            options |= OPT_delay;
+            if ( sscanf(mc_optarg, "%f%c", &STD_LOOP_DELAY, &chr) != 1 ) {
+		sprintf(Mesg2,
+		    "parse_opts: ERROR - Argument for -%s option MUST be NUMERIC",
+		    mc_optopt);
+                return(Mesg2);
+	    }
+
+    	} else if ( strcmp(opt, DURATION) == 0 ) {
+            options |= OPT_duration;
+            if ( sscanf(mc_optarg, "%f%c", &STD_LOOP_DURATION, &chr) != 1 ) {
+		sprintf(Mesg2,
+		    "parse_opts: ERROR - Argument for -%s option MUST be NUMERIC",
+		    mc_optopt);
+                return(Mesg2);
+	    }
+
+            if ( STD_LOOP_DURATION == 0.0 ) {
+                STD_INFINITE=1;
+            }
+
+    	} else if ( strcmp(opt, COPIES) == 0 ) {
+            options |= OPT_copies;
+            if ( sscanf(mc_optarg, "%i%c", &STD_COPIES, &chr) != 1 ) {
+		sprintf(Mesg2,
+		    "parse_opts: ERROR - Argument for -%s option MUST be NUMERIC",
+		    mc_optopt);
+                return(Mesg2);
+	    }
+
+    	} else if ( strcmp(opt, NOFUNC) == 0 ) {
+	    STD_FUNCTIONAL_TEST=0;
+    	} else if ( strcmp(opt, SETUP_PAUSE) == 0 ) {
+	    STD_PAUSE=1;
+    	} else if ( strcmp(opt, TIMING) == 0 ) {
+	    STD_TIMING_ON=1;
+    	} else if ( strcmp(opt, ERRNO_LOGGING) == 0 ) {
+	    STD_ERRNO_LOG=1;
+    	} else if ( strcmp(opt, USC_HELP) == 0 ) {
+	    printf(STD_opts_help());
+	    exit(0);
+	} else {
+            /* Check all the user specified options */
+            found=0;
+	    for(ind=0; user_optarr[ind].option != (char *) NULL; ind++) {
+
+		if ( strcmp(opt, user_optarr[ind].option) == 0 ) {
+                    /* Yup, This is a user option, set the flag and look for argument */
+		    if ( user_optarr[ind].flag != NULL ) {
+                        *user_optarr[ind].flag=1;
+		    }
+                    found++;
+
+		    /* If option requires arg, save pointer  */
+		    num=strlen(user_optarr[ind].option);	
+		    /* save the argument at the user's location */
+                    if ( user_optarr[ind].option[num-1] == ':' ) {  
+                        *user_optarr[ind].arg=mc_optarg;
+                    }
+                    break;  /* option found - break out of the for loop */
+                }
+            }
+	    /* This condition "should never happen".  SO CHECK FOR IT!!!! */
+            if ( ! found ) { 
+                sprintf(Mesg2,
+		    "parse_opts: ERROR - option:\"%s\" NOT FOUND... INTERNAL ERROR", opt);
+                return(Mesg2);
+            }
+	}
+
+    }    /* end of while */
+
+    STD_argind = mc_optind;
+
+    /*
+     * Turn on debug
+     */
+    if ( (ptr=getenv("USC_DEBUG")) != NULL ) {
+	Debug=1;
+        printf("env USC_DEBUG is defined, turning on debug\n");
+    }
+    if ( (ptr=getenv("USC_VERBOSE")) != NULL ) {
+	Debug=1;
+        printf("env USC_VERBOSE is defined, turning on debug\n");
+    }
+
+    /*
+     * If the USC_ITERATION_ENV environmental variable is set to
+     * a number, use that number as iteration count (same as -c option).
+     * The -c option with arg will be used even if this env var is set.
+     */
+    if ( !(options & OPT_iteration) && (ptr=getenv(USC_ITERATION_ENV)) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1) {
+            if ( k == 0 ) {   /* if arg is 0, set infinite loop flag */
+                STD_INFINITE=1;
+		if ( Debug )
+		   printf("Using env %s, set STD_INFINITE to 1\n",
+			USC_ITERATION_ENV);
+            } else {            /* else, set the loop count to the arguement */
+                STD_LOOP_COUNT=k;
+		if ( Debug )
+		   printf("Using env %s, set STD_LOOP_COUNT to %d\n",
+			USC_ITERATION_ENV, k);
+            }
+        }
+    }
+
+    /*
+     * If the USC_NO_FUNC_CHECK environmental variable is set, we'll
+     * unset the STD_FUNCTIONAL_TEST variable.
+     */
+    if ( !(options & OPT_nofunccheck) && (ptr=getenv(USC_NO_FUNC_CHECK)) != NULL ) {
+        STD_FUNCTIONAL_TEST=0; /* Turn off functional testing */
+	if ( Debug )
+	    printf("Using env %s, set STD_FUNCTIONAL_TEST to 0\n",
+		USC_NO_FUNC_CHECK);
+    }
+
+    /*
+     * If the USC_LOOP_WALLTIME environmental variable is set,
+     * use that number as duration (same as -I option).
+     * The -I option with arg will be used even if this env var is set.
+     */
+
+    if ( !(options & OPT_duration) && (ptr=getenv(USC_LOOP_WALLTIME)) != NULL ) {
+        if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
+	    STD_LOOP_DURATION=ftmp;
+	    if ( Debug )
+	        printf("Using env %s, set STD_LOOP_DURATION to %f\n",
+		    USC_LOOP_WALLTIME, ftmp);
+            if ( STD_LOOP_DURATION == 0.0 ) {   /* if arg is 0, set infinite loop flag */
+                STD_INFINITE=1;
+	        if ( Debug )
+	            printf("Using env %s, set STD_INFINITE to 1\n", USC_LOOP_WALLTIME);
+	    }
+        }
+    }
+    if ( !(options & OPT_duration) && (ptr=getenv("USC_DURATION")) != NULL ) {
+        if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
+	    STD_LOOP_DURATION=ftmp;
+	    if ( Debug )
+	        printf("Using env USC_DURATION, set STD_LOOP_DURATION to %f\n", ftmp);
+            if ( STD_LOOP_DURATION == 0.0 ) {   /* if arg is 0, set infinite loop flag */
+                STD_INFINITE=1;
+	        if ( Debug )
+	            printf("Using env USC_DURATION, set STD_INFINITE to 1\n");
+	    }
+        }
+    }
+    /*
+     * If the USC_LOOP_DELAY environmental variable is set,
+     * use that number as delay in factional seconds (same as -P option).
+     * The -P option with arg will be used even if this env var is set.
+     */
+    if ( !(options & OPT_delay) && (ptr=getenv(USC_LOOP_DELAY)) != NULL ) {
+        if ( sscanf(ptr, "%f", &ftmp) == 1 && ftmp >= 0.0 ) {
+	    STD_LOOP_DELAY=ftmp;
+	    if ( Debug )
+		printf("Using env %s, set STD_LOOP_DELAY = %f\n",
+		    USC_LOOP_DELAY, ftmp);
+        }
+    }
+
+    /*
+     * If the USC_COPIES environmental variable is set,
+     * use that number as copies (same as -c option).
+     * The -c option with arg will be used even if this env var is set.
+     */
+    if ( !(options & OPT_copies) && (ptr=getenv(USC_COPIES)) != NULL ) {
+        if ( sscanf(ptr, "%d", &STD_COPIES) == 1 && STD_COPIES >= 0 ) {
+	    if ( Debug )
+		printf("Using env %s, set STD_COPIES = %d\n",
+		    USC_COPIES, STD_COPIES);
+        }
+    }
+
+    /*
+     * The following are special system testing envs to turn on special
+     * hooks in the code.
+     */
+    if ( (ptr=getenv("USC_TP_BARRIER")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+	    STD_TP_barrier=k;
+	}
+        else
+	    STD_TP_barrier=1;
+	if ( Debug )
+	    printf("using env USC_TP_BARRIER, Set STD_TP_barrier to %d\n",
+	        STD_TP_barrier);
+    }
+
+    if ( (ptr=getenv("USC_LP_BARRIER")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+	    STD_LP_barrier=k;
+	}
+        else
+	    STD_LP_barrier=1;
+	if ( Debug ) 
+	    printf("using env USC_LP_BARRIER, Set STD_LP_barrier to %d\n",
+	        STD_LP_barrier);
+    }
+
+    if ( (ptr=getenv("USC_TP_SHMEM")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+            STD_TP_shmem_sz=k;
+	    if ( Debug )
+	        printf("Using env USC_TP_SHMEM, Set STD_TP_shmem_sz to %d\n",
+		    STD_TP_shmem_sz);
+        }
+    }
+
+    if ( (ptr=getenv("USC_LP_SHMEM")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+            STD_LP_shmem=k;
+	    if ( Debug )
+	        printf("Using env USC_LP_SHMEM, Set STD_LP_shmem to %d\n",
+		    STD_LP_shmem);
+        }
+    }
+
+    if ( (ptr=getenv("USC_LD_SHMEM")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+            STD_LD_shmem=k;
+	    if ( Debug )
+	        printf("Using env USC_LD_SHMEM, Set STD_LD_shmem to %d\n",
+		    STD_LD_shmem);
+        }
+    }
+
+    if ( (ptr=getenv("USC_TP_SBRK")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+            STD_TP_sbrk=k;
+	    if ( Debug )
+	        printf("Using env USC_TP_SBRK, Set STD_TP_sbrk to %d\n",
+		    STD_TP_sbrk);
+        }
+    }
+
+    if ( (ptr=getenv("USC_LP_SBRK")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+            STD_LP_sbrk=k;
+	    if ( Debug )
+	        printf("Using env USC_LP_SBRK, Set STD_LP_sbrk to %d\n",
+		    STD_LP_sbrk);
+        }
+    }
+
+    if ( (ptr=getenv("USC_LP_RECFUN")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+	    STD_LP_recfun=k;
+	    if ( STD_bigstack != (struct usc_bigstack_t *)NULL )
+		STD_bigstack=(struct usc_bigstack_t *)
+			malloc(sizeof(struct usc_bigstack_t));
+	    if ( Debug )
+                printf("Using env USC_LP_RECFUN, Set STD_LP_recfun to %d\n",
+		    STD_LP_recfun);
+        }
+    }
+
+    if ( (ptr=getenv("USC_LD_RECFUN")) != NULL ) {
+        if ( sscanf(ptr, "%i", &k) == 1 && k >= 0 ) {
+	    STD_LD_recfun=k;
+	    if ( STD_bigstack != (struct usc_bigstack_t *)NULL )
+		STD_bigstack=(struct usc_bigstack_t *)
+			malloc(sizeof(struct usc_bigstack_t));
+	    if ( Debug )
+                printf("Using env USC_LD_RECFUN, Set STD_LD_recfun to %d\n",
+		    STD_LD_recfun);
+        }
+    }
+ 
+#if UNIT_TEST
+    printf("The following variables after option and env parsing:\n");
+    printf("STD_FUNCTIONAL_TEST = %d\n", STD_FUNCTIONAL_TEST);
+    printf("STD_LOOP_DURATION   = %f\n", STD_LOOP_DURATION);
+    printf("STD_LOOP_DELAY      = %f\n", STD_LOOP_DELAY);
+    printf("STD_COPIES          = %d\n", STD_COPIES);
+    printf("STD_LOOP_COUNT      = %d\n", STD_LOOP_COUNT);
+    printf("STD_INFINITE        = %d\n", STD_INFINITE);
+    printf("STD_TIMING_ON       = %d\n", STD_TIMING_ON);
+    printf("STD_ERRNO_LOG       = %d\n", STD_ERRNO_LOG);
+    printf("STD_PAUSE           = %d\n", STD_PAUSE);
+#endif
+
+    return((char *) NULL);
+
+}    /* end of parse_opts */
+
+/***********************************************************************
+ * This function will remove option from the opt_arr array and
+ * decrement the value of nopts.  If option is not at the end
+ * of the opt_arr, the remaining elements are moved up in the array.
+ *  
+ ***********************************************************************/
+static int
+rm_option(char *option, char **opt_arr[], int *nopts)
+{
+    int ind;
+    int found=0;
+
+    for (ind=0; ind<*nopts; ind++) {
+	if ( found ) {
+	    /*
+	     * Move all opt_arr elements down in the array
+             */
+	    if ( ind == (*nopts) )  {
+		(*opt_arr)[ind] = NULL;
+	    } else  {
+		(*opt_arr)[ind-1] = (*opt_arr)[ind];
+	    }
+		
+        } else if ( strcmp(option, (*opt_arr)[ind]) == 0 ) {
+	    found=ind+1;
+	}
+    }
+    if ( found ) {
+        (*nopts)--;
+#if DEBUG > 1
+	printf("removed %s option from opt_arr, opt_arr[%d] = %s\n",
+option, found-1, (*opt_arr)[found-1]);
+#endif
+    }
+
+    return 0;
+}
+
+/***********************************************************************
+ * This function will add option to the end of opt_arr array and
+ * increment the value of nopts.  The array space will be realloc'ed
+ * to make space for the element.
+ *
+ ***********************************************************************/
+static int
+add_option(char *option, char **opt_arr[], int *nopts)
+{
+
+    if ( (*opt_arr=(char **)realloc(*opt_arr, sizeof(char * ) * (*nopts+1))) ==
+								(char **)NULL ) {
+	sprintf(Mesg2, "parse_opts: ERROR: realloc(arr, %ld) failed, errno:%d %s",
+	    (long)sizeof(char * ) * (*nopts+1), errno, strerror(errno));
+	return -1;
+    }
+
+    (*opt_arr)[*nopts] = option;
+
+#if DEBUG > 1
+    printf("adding opt_arr[%d] = %s\n", *nopts, (*opt_arr)[*nopts]);
+#endif
+    (*nopts)++;
+
+    return 0;
+}
+
+/*********************************************************************
+ * STD_opts() - return a usage string for the STD_OPTIONS.
+ *********************************************************************/
+char *
+STD_opts()
+{
+    int ind;
+
+    Mesg2[0] = '\0';
+
+    /*
+     * generate usage string from the standard options in STD_opt_arr
+     */
+    for(ind=0; ind<STD_nopts; ind++) {
+        if ( strcmp(ITERATIONS, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, ITERATIONS_USE);
+        }else if ( strcmp(DELAY, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, DELAY_USE);
+        }else if ( strcmp(DURATION, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, DURATION_USE);
+        }else if ( strcmp(COPIES, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, COPIES_USE);
+        }else if ( strcmp(NOFUNC, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, NOFUNC_USE);
+        }else if ( strcmp(SETUP_PAUSE, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, SETUP_PAUSE_USE);
+        }else if ( strcmp(TIMING, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, TIMING_USE);
+        }else if ( strcmp(ERRNO_LOGGING, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, ERRNO_LOGGING_USE);
+        }else if ( strcmp(USC_HELP, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg2, HELP_USE);
+	}
+    }
+
+    return Mesg2;
+}
+
+/*********************************************************************
+ * STD_opts_help() - return a help string for the STD_OPTIONS.
+ *********************************************************************/
+char *
+STD_opts_help()
+{
+    int ind;
+
+    sprintf(Mesg, "  Options and option args can NOT be concatenated.\n\
+  You can use smallest unique string that identifies an option\n");
+
+    /*
+     * generate usage string from the standard options in STD_opt_arr
+     */
+    for(ind=0; ind<STD_nopts; ind++) {
+        if ( strcmp(ITERATIONS, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, ITERATIONS_HELP);
+        }else if ( strcmp(DELAY, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, DELAY_HELP);
+        }else if ( strcmp(DURATION, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, DURATION_HELP);
+        }else if ( strcmp(COPIES, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, COPIES_HELP);
+        }else if ( strcmp(NOFUNC, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, NOFUNC_HELP);
+        }else if ( strcmp(SETUP_PAUSE, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, SETUP_PAUSE_HELP);
+        }else if ( strcmp(TIMING, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, TIMING_HELP);
+        }else if ( strcmp(ERRNO_LOGGING, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, ERRNO_LOGGING_HELP);
+        }else if ( strcmp(USC_HELP, STD_opt_arr[ind]) == 0 ) {
+	    strcat(Mesg, USC_HELP_HELP);
+	}
+    }
+
+    return Mesg;
+}
+
+/* 
+ * routine to goto when we get the SIGUSR1 for STD_PAUSE
+ */
+void STD_go(int sig)
+{
+   return;
+}
+
+/***********************************************************************
+ * This function will do desired end of global setup test
+ * hooks.
+ * Currently it will only do a pause waiting for sigusr1 if
+ * STD_PAUSE is set.
+ *
+ ***********************************************************************/
+int
+usc_global_setup_hook()
+{
+    int cnt;
+
+    /*
+     * Fork STD_COPIES-1 copies.
+     */
+    for(cnt=1;cnt<STD_COPIES;cnt++) {
+        switch(fork() ) {
+	    case -1:
+		fprintf(stderr, "%s: fork() failed, errno:%d %s\n",
+                __FILE__, errno, strerror(errno));
+		break;
+	    case 0:  /* child */
+	        cnt=STD_COPIES;   /* to stop the forking */
+		break;
+
+	    default: /* parent */
+		break;
+	}
+    }
+    
+
+
+#ifdef _CRAYMPP
+        MyPE = sysconf(_SC_CRAY_VPE);
+        Npe = sysconf(_SC_CRAY_NPES);
+#endif
+
+    /*
+     * pause waiting for sigusr1.
+     */
+    if ( STD_PAUSE ) {                                      
+        _TMP_FUNC = (int (*)())signal(SIGUSR1, STD_go);   
+        pause();                                          
+        signal(SIGUSR1, (void (*)())_TMP_FUNC);          
+    }
+
+#ifdef _CRAYMPP
+    if ( STD_TP_shmem_sz ) {
+	if ( (STD_shmem=(long *)shmalloc(STD_TP_shmem_sz*sizeof(long)*Npe)) == NULL ) {
+	    STD_TP_shmem_sz=0;
+	}
+        else {
+	    bzero(STD_shmem, STD_TP_shmem_sz*sizeof(long)*Npe);
+	    if ( Debug )
+	        printf("shmalloc(%d*%d*%d=%d) successful, pid:%d\n",
+		    STD_TP_shmem_sz, sizeof(long), Npe,
+		    STD_TP_shmem_sz*sizeof(long)*Npe, getpid());
+	}
+    }
+
+    if ( STD_TP_barrier )  {
+	switch (STD_TP_barrier) {
+	case 2: 
+	   wait_barrier();
+	   if ( Debug )
+	       printf("after wait_barrier, pid : %d\n", getpid());
+	   break;
+
+	case 3:
+	   set_barrier();
+	   if ( Debug ) 
+	       printf("after set_barrier, pid : %d\n", getpid());
+	   break;
+
+	default: 
+	    barrier();
+	    if ( Debug )
+	        printf("after barrier, pid : %d\n", getpid());
+	}
+    }
+
+#endif /* _CRAYMPP */
+
+    if ( STD_TP_sbrk || STD_LP_sbrk) {
+	STD_start_break=sbrk(0);	/* get original sbreak size */
+    }
+
+    if ( STD_TP_sbrk ) {
+	sbrk(STD_TP_sbrk);
+	if ( Debug ) 
+	    printf("after sbrk(%d)\n", STD_TP_sbrk);
+    }
+    return 0;
+}
+
+#define USECS_PER_SEC	1000000  /* microseconds per second */
+
+/***********************************************************************
+ * This function returns the number of get_current_time()'s return
+ * per second.
+ ***********************************************************************/
+
+static int
+get_timepersec()
+{
+#if CRAY
+    return sysconf(_SC_CLK_TCK);   /* clocks per second */
+#else
+    return  USECS_PER_SEC;   /* microseconds per second */
+#endif /* CRAY */
+
+}
+
+/***********************************************************************
+ * this function will get current time in clocks if on a CRAY system
+ * or in microseconds since 1970.
+ ***********************************************************************/
+static int
+get_current_time()
+{
+    struct timeval curtime;
+#if CRAY
+    return _rtc();	/* clocks since last boot */
+#else
+
+    gettimeofday(&curtime, NULL);
+
+    /* microseconds since 1970 */
+    return (curtime.tv_sec*USECS_PER_SEC) + curtime.tv_usec;
+
+#endif
+
+}
+
+/***********************************************************************
+ *
+ * This function will determine if test should continue iterating
+ * If the STD_INFINITE flag is set, return 1.
+ * If the STD_LOOP_COUNT variable is set, compare it against
+ * the counter.
+ * If the STD_LOOP_DURATION variable is set, compare current time against
+ * calculated stop_time.
+ * This function will return 1 until all desired looping methods
+ * have been met.  
+ *
+ * counter integer is supplied by the user program.
+ ***********************************************************************/
+int
+usc_test_looping(counter)
+int counter;
+{
+    static int first_time = 1;
+    static int stop_time = 0;	/* stop time in rtc or usecs */
+    static int delay;		/* delay in clocks or usecs  */
+    int hz=0;			/* clocks per second or usecs per second */
+    int ct, end;		/* current time, end delay time */
+    int keepgoing=0;		/* used to determine return value */
+#ifdef _CRAYMPP
+    long word;
+    int pe;
+#endif
+
+    /*
+     * If this is the first iteration and we are looping for 
+     * duration of STD_LOOP_DURATION seconds (fractional) or
+     * doing loop delays, get the clocks per second.
+     */
+    if ( first_time ) {
+
+	first_time=0;
+	if ( STD_LOOP_DELAY || STD_LOOP_DURATION ) {
+	    hz = get_timepersec();
+	}
+
+	/*
+	 * If looping for duration, calculate stop time in
+	 * clocks.
+	 */
+	
+	if ( STD_LOOP_DURATION) {
+	    ct=get_current_time();
+	    stop_time=(int)((float)hz * STD_LOOP_DURATION) + ct;
+	}
+
+	/*
+	 * If doing delay each iteration, calcuate the number
+	 * of clocks for each delay.
+	 */
+	if ( STD_LOOP_DELAY ) {
+	    delay=(int)((float)hz * STD_LOOP_DELAY);
+	}
+
+    }
+	
+    /*
+     * if delay each iteration, loop for delay clocks.
+     * This will not be done on first iteration.
+     * The delay will happen before determining if
+     * there will be another iteration.
+     */
+    else if ( STD_LOOP_DELAY ) {
+	ct=get_current_time();
+        end=ct+delay;
+        while ( ct < end ) {
+	    /*
+	     * The following are special test hooks in the delay loop.
+	     */
+	    if ( STD_LD_recfun ) {
+		if ( Debug )
+		    printf("calling usc_recressive_func(0, %d, &STD_bigstack)\n", 
+		        STD_LD_recfun);
+		usc_recressive_func(0, STD_LD_recfun, &STD_bigstack);
+	    }
+
+	    ct=get_current_time();
+	}
+    }
+
+    if ( STD_INFINITE ) {
+	keepgoing++;
+    }
+
+    if ( STD_LOOP_COUNT && counter < STD_LOOP_COUNT ) {
+	keepgoing++;
+    }
+
+    if ( STD_LOOP_DURATION != 0.0 && get_current_time() < stop_time ) {
+	keepgoing++;
+    }
+
+    if ( keepgoing == 0 )
+	return 0;
+
+    /*
+     * The following code allows special system testing hooks.
+     */
+
+    if ( STD_LP_recfun ) {
+	if ( Debug )
+	    printf("calling usc_recressive_func(0, %d, &STD_bigstack)\n", 
+	        STD_LP_recfun);
+	usc_recressive_func(0, STD_LP_recfun, &STD_bigstack);
+    }
+
+    if ( STD_LP_sbrk ) {
+	if ( Debug )
+	    printf("about to do sbrk(%d)\n", STD_LP_sbrk);
+	sbrk(STD_LP_sbrk);
+    }
+
+#ifdef _CRAYMPP
+    if ( STD_LP_shmem ) {
+	if ( (pe=MyPE-1) < 0 )	/* put to be lower pe #*/
+	   pe=Npe;
+	word=MyPE;
+
+	if ( Debug )
+	    printf("about to do shmem_put\n");
+        shmem_put(&STD_shmem[pe], &STD_shmem[MyPE], STD_TP_shmem_sz, pe); 
+	
+
+    }
+    if ( STD_TP_barrier )  {
+        switch (STD_TP_barrier) {
+        case 2:
+           wait_barrier();
+	   if ( Debug )
+              printf("after wait_barrier, pid : %d\n", getpid());
+           break;
+
+        case 3:
+           set_barrier();
+	   if ( Debug )
+               printf("after set_barrier, pid : %d\n", getpid());
+           break;
+
+        default:
+            barrier();
+	   if ( Debug )
+                printf("after barrier, pid : %d\n", getpid());
+        }
+    }
+    if ( STD_LP_shmem > 1) {
+        if ( (pe=MyPE+1) > Npe ) /* get from higher pe # */
+           pe=0;
+        word=MyPE;
+
+	if ( Debug )
+        printf("about to do shmem_get\n");
+        shmem_get(&STD_shmem[MyPE], &STD_shmem[pe], STD_TP_shmem_sz, pe);
+    }
+
+
+#endif  /* _CRAYMPP */
+
+
+    if ( keepgoing )
+	return 1;
+    else
+        return 0;	/* done - stop iterating */
+}
+
+
+/*
+ * This function recressively calls itself max times.
+ */ 
+static void
+usc_recressive_func(cnt, max, bstack)
+int cnt;
+int max;
+struct usc_bigstack_t bstack;
+{
+    if ( cnt < max )
+	usc_recressive_func(cnt+1, max, bstack);
+
+}
+
+#if UNIT_TEST
+/******************************************************************************
+ * UNIT TEST CODE
+ * UNIT TEST CODE
+ * 
+ * this following code is provide so that unit testing can
+ * be done fairly easily.
+ ******************************************************************************/
+
+int Help = 0;
+int Help2 = 0;
+char *ptr;
+
+/*
+ * Code from usctest.h that not part of this file since we are the library.
+ */
+
+struct usc_errno_t TEST_VALID_ENO[USC_MAX_ERRNO];
+
+  /***********************************************************************
+   * Globals for returning the return code and errno from the system call
+   * test macros.
+   ***********************************************************************/
+int TEST_RETURN;
+int TEST_ERRNO;
+
+  /***********************************************************************
+   * temporary variables for determining max and min times in TEST macro
+   ***********************************************************************/
+long btime, etime, tmptime;
+
+
+
+/* for test specific parse_opts options */
+option_t Options[] = {
+        { "help",  &Help2, NULL },      /* -help option */
+        { "h",  &Help, NULL },          /* -h option */
+ 	{ TIMING, NULL, NULL},		/* disable -timing option */
+
+#if INVALID_TEST_CASES
+ 	{ "missingflag", NULL, &ptr },  /* error */
+ 	{ "missingarg:", &Help, NULL },  /* error */
+#endif  /* INVALID_TEST_CASES */
+
+        { NULL, NULL, NULL }
+};
+
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+    int lc;
+    char *msg;
+    struct timeval t;
+    int cnt;
+
+    if ( (msg=parse_opts(argc, argv,
+			(option_t *) Options)) != (char *) NULL ) {
+	printf("ERROR : %s\n", msg);
+	exit(1);
+    }
+
+    if ( Help ) {
+	printf("****** -h option *****\n");
+	printf("Usage %s %s[-help]\n", argv[0], STD_opts());
+	printf("%s  -help           : print this help message and exit\n",
+	    STD_opts_help());
+	exit(0);
+    }
+
+    if ( Help2 ) {
+	printf("****** -help option *****\n");
+	printf("Usage %s %s[-help]\n", argv[0], STD_opts());
+	printf("%s  -help           : print this help message and exit\n",
+	    STD_opts_help());
+	exit(0);
+    }
+
+    TEST_PAUSE;
+
+    for (lc=0; TEST_LOOPING(lc); lc++) {
+    
+        TEST( gettimeofday(&t, NULL) );
+        printf("iter=%d: sec:%d, usec:%6.6d %s", lc+1, t.tv_sec,
+	    t.tv_usec, ctime(&t.tv_sec));
+    }
+
+
+    TEST_CLEANUP;
+
+    exit(0);
+}
+
+#endif /* UNIT_TEST */
diff --git a/lib/pattern.c b/lib/pattern.c
index 43528ae..7f4d587 100644
--- a/lib/pattern.c
+++ b/lib/pattern.c
@@ -29,40 +29,14 @@
  * 
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
  */
+#include <string.h>
+#include "pattern.h"
+
 /*
  * The routines in this module are used to fill/check a data buffer
  * with/against a known pattern.
  */
 
-/*
- * pattern_check(buf, buflen, pat, patlen, patshift)
- *
- * Check a buffer of length buflen against repeated occurrances of
- * a pattern whose length is patlen.  Patshift can be used to rotate
- * the pattern by patshift bytes to the left.
- *
- * Patshift may be greater than patlen, the pattern will be rotated by
- * (patshift % patshift) bytes.
- *
- * pattern_check returns -1 if the buffer does not contain repeated
- * occurrances of the indicated pattern (shifted by patshift).
- *
- * The algorithm used to check the buffer relies on the fact that buf is 
- * supposed to be repeated copies of pattern.  The basic algorithm is
- * to validate the first patlen bytes of buf against the pat argument
- * passed in - then validate the next patlen bytes against the 1st patlen
- * bytes - the next (2*patlen) bytes against the 1st (2*pathen) bytes, and
- * so on.  This algorithm only works when the assumption of a buffer full
- * of repeated copies of a pattern holds, and gives MUCH better results
- * then walking the buffer byte by byte.
- *
- * Performance wise, It appears to be about 5% slower than doing a straight
- * memcmp of 2 buffers, but the big win is that it does not require a
- * 2nd comparison buffer, only the pattern.
- */
-
-#include <string.h>
-
 int
 pattern_check(buf, buflen, pat, patlen, patshift)
 char	*buf;
@@ -130,32 +104,6 @@
     return 0;
 }
 
-/*
- * pattern_fill(buf, buflen, pat, patlen, patshift)
- *
- * Fill a buffer of length buflen with repeated occurrances of
- * a pattern whose length is patlen.  Patshift can be used to rotate
- * the pattern by patshift bytes to the left.
- *
- * Patshift may be greater than patlen, the pattern will be rotated by
- * (patshift % patlen) bytes.
- *
- * If buflen is not a multiple of patlen, a partial pattern will be written
- * in the last part of the buffer.  This implies that a buffer which is
- * shorter than the pattern length will receive only a partial pattern ...
- *
- * pattern_fill always returns 0 - no validation of arguments is done.
- *
- * The algorithm used to fill the buffer relies on the fact that buf is 
- * supposed to be repeated copies of pattern.  The basic algorithm is
- * to fill the first patlen bytes of buf with the pat argument
- * passed in - then copy the next patlen bytes with the 1st patlen
- * bytes - the next (2*patlen) bytes with the 1st (2*pathen) bytes, and
- * so on.  This algorithm only works when the assumption of a buffer full
- * of repeated copies of a pattern holds, and gives MUCH better results
- * then filling the buffer 1 byte at a time.
- */
-
 int
 pattern_fill(buf, buflen, pat, patlen, patshift)
 char	*buf;
diff --git a/lib/rmobj.c b/lib/rmobj.c
new file mode 100644
index 0000000..1fc77a7
--- /dev/null
+++ b/lib/rmobj.c
@@ -0,0 +1,210 @@
+/*
+ * 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/
+ */
+
+/* $Id: rmobj.c,v 1.1 2000/07/27 17:13:18 alaffin Exp $ */
+
+/**********************************************************
+ *
+ *    OS Testing - Silicon Graphics, Inc.
+ *
+ *    FUNCTION NAME     : rmobj()
+ *
+ *    FUNCTION TITLE    : Remove an object
+ *
+ *    SYNOPSIS:
+ *      int rmobj(char *obj, char **errmsg)
+ *
+ *    AUTHOR            : Kent Rogers
+ *
+ *    INITIAL RELEASE   : UNICOS 7.0
+ *
+ *    USER DESCRIPTION
+ *      This routine will remove the specified object.  If the specified
+ *      object is a directory, it will recursively remove the directory
+ *      and everything underneath it.  It assumes that it has privilege
+ *      to remove everything that it tries to remove.  If rmobj() encounters
+ *      any problems, and errmsg is not NULL, errmsg is set to point to a
+ *      string explaining the error.
+ *
+ *    DETAILED DESCRIPTION
+ *      Allocate space for the directory and its contents
+ *      Open the directory to get access to what is in it
+ *      Loop through the objects in the directory:
+ *        If the object is not "." or "..":
+ *          Determine the file type by calling lstat()
+ *          If the object is not a directory:
+ *            Remove the object with unlink()
+ *         Else:
+ *            Call rmobj(object) to remove the object's contents
+ *            Determine the link count on object by calling lstat()
+ *            If the link count >= 3:
+ *              Remove the directory with unlink()
+ *            Else
+ *               Remove the directory with rmdir()
+ *      Close the directory and free the pointers
+ *
+ *    RETURN VALUE
+ *      If there are any problems, rmobj() will set errmsg (if it was not
+ *      NULL) and return -1.  Otherwise it will return 0.
+ *
+ ************************************************************/
+#include <errno.h>         /* for errno */
+#include <stdio.h>         /* for NULL */
+#include <stdlib.h>        /* for malloc() */
+#include <string.h>        /* for string function */
+#include <limits.h>        /* for PATH_MAX */
+#include <sys/types.h>     /* for opendir(), readdir(), closedir(), stat() */
+#include <sys/stat.h>      /* for [l]stat() */
+#include <dirent.h>        /* for opendir(), readdir(), closedir() */
+#include "rmobj.h"
+
+#define SYSERR strerror(errno)
+
+int
+rmobj(char *obj, char **errmsg)
+{
+   int           ret_val = 0;       /* return value from this routine */
+   DIR           *dir;              /* pointer to a directory */
+   struct dirent *dir_ent;          /* pointer to directory entries */
+   char          dirobj[PATH_MAX];  /* object inside directory to modify */
+   struct stat   statbuf;           /* used to hold stat information */
+   static char   err_msg[1024];     /* error message */
+
+   /* Determine the file type */
+   if ( lstat(obj, &statbuf) < 0 ) {
+      if ( errmsg != NULL ) {
+         sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
+                 obj, errno, SYSERR);
+         *errmsg = err_msg;
+      }
+      return -1;
+   }
+
+   /* Take appropriate action, depending on the file type */
+   if ( (statbuf.st_mode & S_IFMT) == S_IFDIR ) {
+      /* object is a directory */
+
+      /* Do NOT perform the request if the directory is "/" */
+      if ( !strcmp(obj, "/") ) {
+         if ( errmsg != NULL ) {
+            sprintf(err_msg, "Cannot remove /");
+            *errmsg = err_msg;
+         }
+         return -1;
+      }
+
+      /* Open the directory to get access to what is in it */
+      if ( (dir = opendir(obj)) == NULL ) {
+         if ( rmdir(obj) != 0 ) {
+            if ( errmsg != NULL ) {
+               sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s",
+                       obj, errno, SYSERR);
+               *errmsg = err_msg;
+            }
+            return -1;
+         } else {
+            return 0;
+         }
+      }
+
+      /* Loop through the entries in the directory, removing each one */
+      for ( dir_ent = (struct dirent *)readdir(dir);
+            dir_ent != NULL;
+            dir_ent = (struct dirent *)readdir(dir)) {
+
+         /* Don't remove "." or ".." */
+         if ( !strcmp(dir_ent->d_name, ".") || !strcmp(dir_ent->d_name, "..") )
+            continue;
+
+         /* Recursively call this routine to remove the current entry */
+         sprintf(dirobj, "%s/%s", obj, dir_ent->d_name);
+         if ( rmobj(dirobj, errmsg) != 0 )
+            ret_val = -1;
+      }
+
+      /* Close the directory */
+      closedir(dir);
+
+      /* If there were problems removing an entry, don't attempt to
+         remove the directory itself */
+      if ( ret_val == -1 )
+         return -1;
+
+      /* Get the link count, now that all the entries have been removed */
+      if ( lstat(obj, &statbuf) < 0 ) {
+         if ( errmsg != NULL ) {
+            sprintf(err_msg, "lstat(%s) failed; errno=%d: %s",
+                    obj, errno, SYSERR);
+            *errmsg = err_msg;
+         }
+         return -1;
+      }
+
+      /* Remove the directory itself */
+      if ( statbuf.st_nlink >= 3 ) {
+         /* The directory is linked; unlink() must be used */
+         if ( unlink(obj) < 0 ) {
+            if ( errmsg != NULL ) {
+               sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
+                       obj, errno, SYSERR);
+               *errmsg = err_msg;
+            }
+            return -1;
+         }
+      } else {
+         /* The directory is not linked; rmdir() can be used */
+         if ( rmdir(obj) < 0 ) {
+            if ( errmsg != NULL ) {
+               sprintf(err_msg, "rmdir(%s) failed; errno=%d: %s",
+                       obj, errno, SYSERR);
+               *errmsg = err_msg;
+            }
+            return -1;
+         }
+      }
+   } else {
+      /* object is not a directory; just use unlink() */
+      if ( unlink(obj) < 0 ) {
+         if ( errmsg != NULL ) {
+            sprintf(err_msg, "unlink(%s) failed; errno=%d: %s",
+                    obj, errno, SYSERR);
+            *errmsg = err_msg;
+         }
+         return -1;
+      }
+   }  /* if obj is a directory */
+
+   /*
+    * Everything must have went ok.
+    */
+   return 0;
+}  /* rmobj() */
diff --git a/lib/string_to_tokens.c b/lib/string_to_tokens.c
index 5200aec..6f0d775 100644
--- a/lib/string_to_tokens.c
+++ b/lib/string_to_tokens.c
@@ -31,7 +31,7 @@
  */
 /**********************************************************
  * 
- *    UNICOS Testing - Cray Research, Inc.
+ *    OS Testing - Silicon Graphics, Inc.
  * 
  *    FUNCTION NAME     : string_to_tokens
  * 
diff --git a/lib/tlibio.c b/lib/tlibio.c
index a73aa39..ef75d8e 100644
--- a/lib/tlibio.c
+++ b/lib/tlibio.c
@@ -81,11 +81,7 @@
 #include <stdio.h>
 #include <ctype.h>
 #include <fcntl.h>
-#ifdef CRAY
-#include <sys/unistd.h>
-#else
 #include <unistd.h>
-#endif
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/time.h>          
diff --git a/lib/tst_res.c b/lib/tst_res.c
new file mode 100644
index 0000000..1c9534c
--- /dev/null
+++ b/lib/tst_res.c
@@ -0,0 +1,964 @@
+/*
+ * 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/
+ */
+
+
+/* $Id: tst_res.c,v 1.1 2000/07/27 17:13:19 alaffin Exp $ */
+
+/**********************************************************
+ *
+ *    OS Testing - Silicon Graphics, Inc.
+ *
+ *    FUNCTION NAME     :
+ *      tst_res() -       Print result message (include file contents)
+ *      tst_resm() -      Print result message
+ *      tst_brk() -       Print result message (include file contents)
+ *                        and break remaining test cases
+ *      tst_brkm() -      Print result message and break remaining test
+ *                        cases
+ *      tst_brkloop() -   Print result message (include file contents)
+ *                        and break test cases remaining in current loop
+ *      tst_brkloopm() -  Print result message and break test case
+ *                        remaining in current loop
+ *      tst_flush() -     Print any messages pending because of
+ *                        CONDENSE mode, and flush output stream
+ *      tst_exit() -      Exit test with a meaningful exit value.
+ *      tst_environ() -   Keep results coming to original stdout
+ *
+ *    FUNCTION TITLE    : Standard automated test result reporting mechanism
+ *
+ *    SYNOPSIS:
+ *      #include "test.h"
+ *
+ *      void tst_res(ttype, fname, tmesg [,arg]...)
+ *      int  ttype;
+ *      char *fname;
+ *      char *tmesg;
+ *
+ *      void tst_resm(ttype, tmesg [,arg]...)
+ *      int  ttype;
+ *      char *tmesg;
+ *
+ *      void tst_brk(ttype, fname, cleanup, tmesg, [,argv]...)
+ *      int  ttype;
+ *      char *fname;
+ *      void (*cleanup)();
+ *      char *tmesg;
+ *
+ *      void tst_brkm(ttype, cleanup, tmesg [,arg]...)
+ *      int  ttype;
+ *      void (*cleanup)();
+ *      char *tmesg;
+ *
+ *      void tst_brkloop(ttype, fname, cleanup, char *tmesg, [,argv]...)
+ *      int  ttype;
+ *      char *fname;
+ *      void (*cleanup)();
+ *      char *tmesg;
+ *
+ *      void tst_brkloopm(ttype, cleanup, tmesg [,arg]...)
+ *      int  ttype;
+ *      void (*cleanup)();
+ *      char *tmesg;
+ *
+ *      void tst_flush()
+ *
+ *      void tst_exit()
+ *
+ *      int  tst_environ()
+ *
+ *    AUTHOR            : Kent Rogers (from Dave Fenner's original)
+ *
+ *    CO-PILOT          : Rich Logan
+ *
+ *    DATE STARTED      : 05/01/90 (rewritten 1/96)
+ *
+ *    DESCRIPTION
+ *      See the man page(s).
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>         /* for I/O functions, BUFSIZ */
+#include <stdlib.h>        /* for getenv() */
+#include <stdarg.h>        /* for varargs stuff */
+#include <unistd.h>        /* for access() */
+#include "test.h"          /* for output display mode & result type */
+                           /* defines */
+
+/*
+ * Define some useful macros.
+ */
+#define VERBOSE      1     /* flag values for the T_mode variable */
+#define CONDENSE     2
+#define NOPASS       3
+#define DISCARD      4
+
+#define MAXMESG      80    /* max length of internal messages */
+#define USERMESG     2048  /* max length of user message */
+#define TRUE         1
+#define FALSE        0
+
+/*
+ * EXPAND_VAR_ARGS - Expand the variable portion (arg_fmt) of a result
+ *                   message into the specified string.
+ */
+#define EXPAND_VAR_ARGS(arg_fmt, str) {   \
+   va_list ap; /* varargs mechanism */    \
+                                          \
+   if ( arg_fmt != NULL ) {               \
+      if ( Expand_varargs == TRUE ) {     \
+         va_start(ap, arg_fmt);           \
+         vsprintf(str, arg_fmt, ap);      \
+         va_end(ap);                      \
+         Expand_varargs = FALSE;          \
+      } else {                            \
+         strcpy(str, arg_fmt);            \
+      }                                   \
+   } else {                               \
+      str[0] = '\0';                      \
+   }                                      \
+}  /* EXPAND_VAR_ARGS() */
+
+/*
+ * Define local function prototypes.
+ */
+static void check_env();
+static void tst_condense(int tnum, int ttype, char *tmesg);
+static void tst_print(char *tcid, int tnum, int trange, int ttype, char *tmesg);
+static void cat_file(char *filename);
+
+
+/*
+ * Define some static/global variables.
+ */
+static FILE *T_out = NULL;    /* tst_res() output file descriptor */
+static char *File;            /* file whose contents is part of result */
+static int  T_exitval = 0;    /* exit value used by tst_exit() */
+static int  T_mode = VERBOSE; /* flag indicating print mode: VERBOSE, */
+                              /* CONDENSE, NOPASS, DISCARD */
+
+static int  Expand_varargs = TRUE;  /* if TRUE, expand varargs stuff */
+static char Warn_mesg[MAXMESG];  /* holds warning messages */
+
+/*
+ * These are used for condensing output when NOT in verbose mode.
+ */
+static int  Buffered = FALSE; /* TRUE if condensed output is currently */
+                              /* buffered (i.e. not yet printed) */
+static char *Last_tcid;       /* previous test case id */
+static int  Last_num;         /* previous test case number */
+static int  Last_type;        /* previous test result type */
+static char *Last_mesg;       /* previous test result message */
+
+
+/*
+ * These globals may be externed by the test.
+ */
+int Tst_count = 0;      /* current count of test cases executed; NOTE: */
+                        /* Tst_count may be externed by other programs */
+int Tst_lptotal = 0;    /* tst_brkloop() external */
+int Tst_lpstart = 0;    /* tst_brkloop() external */
+int Tst_range = 1;      /* for specifying multiple results */
+int Tst_nobuf = 1;      /* this is a no-op; buffering is never done, but */
+                        /* this will stay for compatibility reasons */
+
+/*
+ * These globals must be defined in the test.
+ */
+extern char *TCID;      /* Test case identifier from the test source */
+extern int  TST_TOTAL;  /* Total number of test cases from the test */
+                        /* source */
+
+/*
+ * This global is used by the temp. dir. maintenance functions,
+ * tst_tmpdir()/tst_rmdir(), tst_wildcard()/tst_tr_rmdir().  It is the
+ * name of the directory created (if any).  It is defined here, so that
+ * it only has to be declared once and can then be referenced from more
+ * than one module.  Also, since the temp. dir. maintenance functions
+ * rely on the tst_res.c package this seemed like a reasonable place.
+ */
+char *TESTDIR = NULL;
+
+/*
+ * tst_res() - Main result reporting function.  Handle test information
+ *             appropriately depending on output display mode.  Call
+ *             tst_condense() or tst_print() to actually print results.
+ *             All result functions (tst_resm(), tst_brk(), etc.)
+ *             eventually get here to print the results.
+ */
+void
+tst_res(int ttype, char *fname, char *arg_fmt, ...)
+{
+   int  i;
+   char tmesg[USERMESG];     /* expanded message */
+
+#if DEBUG
+   printf("IN tst_res; Tst_count = %d; Tst_range = %d\n",
+          Tst_count, Tst_range); fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg, if necessary.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Save the test result type by ORing ttype into the current exit
+    * value (used by tst_exit()).
+    */
+   T_exitval |= ttype;
+
+   /*
+    * Unless T_out has already been set by tst_environ(), make tst_res()
+    * output go to standard output.
+    */
+   if ( T_out == NULL )
+       T_out = stdout;
+
+   /*
+    * Check TOUTPUT environment variable (if first time) and set T_mode
+    * flag.
+    */
+   check_env();
+
+   /*
+    * A negative or NULL range is invalid.
+    */
+   if ( Tst_range <= 0 ) {
+      Tst_range = 1;
+      tst_print(TCID, 0, 1, TWARN,
+                "tst_res(): Tst_range must be positive");
+   }
+
+   /*
+    * If a filename was specified, set 'File' if it exists.
+    */
+   if ( fname != NULL && access(fname, F_OK) == 0 )
+      File = fname;
+
+   /*
+    * Set the test case number and print the results, depending on the
+    * display type.
+    */
+   if ( ttype == TWARN || ttype == TINFO ) {
+      /*
+       * Handle WARN and INFO results (test case number is 0).
+       */
+      if ( Tst_range > 1 ) {
+         tst_print(TCID, 0, 1, TWARN,
+                   "tst_res(): Range not valid for TINFO or TWARN types");
+      }
+      tst_print(TCID, 0, 1, ttype, tmesg);
+   } else {
+      /*
+       * Handle all other types of results other than WARN and INFO.
+       */
+      if ( Tst_count < 0 )
+         tst_print(TCID, 0, 1, TWARN,
+                   "tst_res(): Tst_count < 0 is not valid");
+
+      /*
+       * Process each display type.
+       */
+      switch ( T_mode ) {
+      case DISCARD:
+         /* do not print any results */
+         break;
+
+      case NOPASS:   /* passing result types are filtered by tst_print() */
+      case CONDENSE:
+         tst_condense(Tst_count + 1, ttype, tmesg);
+         break;
+
+      default: /* VERBOSE */
+         for ( i = 1 ; i <= Tst_range ; i++ )
+            tst_print(TCID, Tst_count + i, Tst_range, ttype, tmesg);
+         break;
+      }  /* end switch() */
+
+      /*
+       * Increment Tst_count.
+       */
+      Tst_count += Tst_range;
+   }  /* if ( ttype == TWARN || ttype == TINFO ) */
+
+   /*
+    * Reset some values.
+    */
+   Tst_range = 1;
+   Expand_varargs = TRUE;
+}  /* tst_res() */
+
+
+/*
+ * tst_condense() - Handle test cases in CONDENSE or NOPASS mode (i.e.
+ *                  buffer the current result and print the last result
+ *                  if different than the current).  If a file was
+ *                  specified, print the current result and do not
+ *                  buffer it.
+ */
+static void
+tst_condense(int tnum, int ttype, char *tmesg)
+{
+   char *file;
+
+#if DEBUG
+   printf("IN tst_condense: tcid = %s, tnum = %d, ttype = %d, tmesg = %s\n",
+          TCID, tnum, ttype, tmesg);
+   fflush(stdout);
+#endif
+
+   /*
+    * If this result is the same as the previous result, return.
+    */
+   if ( Buffered == TRUE ) {
+      if ( strcmp(Last_tcid, TCID) == 0 && Last_type == ttype &&
+           strcmp(Last_mesg, tmesg) == 0 && File == NULL )
+         return;
+
+      /*
+       * This result is different from the previous result.  First,
+       * print the previous result.
+       */
+      file = File;
+      File = NULL;
+      tst_print(Last_tcid, Last_num, tnum - Last_num, Last_type,
+                Last_mesg);
+      free(Last_tcid);
+      free(Last_mesg);
+      File = file;
+   }  /* if ( Buffered == TRUE ) */
+
+   /*
+    * If a file was specified, print the current result since we have no
+    * way of retaining the file contents for comparing with future
+    * results.  Otherwise, buffer the current result info for next time.
+    */
+   if ( File != NULL ) {
+      tst_print(TCID, tnum, Tst_range, ttype, tmesg);
+      Buffered = FALSE;
+   } else {
+      Last_tcid = (char *)malloc(strlen(TCID) + 1);
+      strcpy(Last_tcid, TCID);
+      Last_num = tnum;
+      Last_type = ttype;
+      Last_mesg = (char *)malloc(strlen(tmesg) + 1);
+      strcpy(Last_mesg, tmesg);
+      Buffered = TRUE;
+   }
+}  /* tst_condense() */
+
+
+/*
+ * tst_flush() - Print any messages pending because of CONDENSE mode,
+ *               and flush T_out.
+ */
+void
+tst_flush()
+{
+#if DEBUG
+   printf("IN tst_flush\n");
+   fflush(stdout);
+#endif
+
+   /*
+    * Print out last line if in CONDENSE or NOPASS mode.
+    */
+   if ( Buffered == TRUE && (T_mode == CONDENSE || T_mode == NOPASS) ) {
+      tst_print(Last_tcid, Last_num, Tst_count - Last_num + 1,
+                Last_type, Last_mesg);
+      Buffered = FALSE;
+   }
+   fflush(T_out);
+}  /* tst_flush() */
+
+
+/*
+ * tst_print() - Actually print a line or range of lines to the output
+ *               stream.
+ */
+static void
+tst_print(char *tcid, int tnum, int trange, int ttype, char *tmesg)
+{
+   char type[5];
+
+#if DEBUG
+   printf("IN tst_print: tnum = %d, trange = %d, ttype = %d, tmesg = %s\n",
+          tnum, trange, ttype, tmesg);
+   fflush(stdout);
+#endif
+
+   /*
+    * Save the test result type by ORing ttype into the current exit
+    * value (used by tst_exit()).  This is already done in tst_res(), but
+    * is also done here to catch internal warnings.  For internal warnings, 
+    * tst_print() is called directly with a case of TWARN.
+    */
+   T_exitval |= ttype;
+
+   /*
+    * If output mode is DISCARD, or if the output mode is NOPASS and
+    * this result is not one of FAIL, BROK, or WARN, just return.  This
+    * check is necessary even though we check for DISCARD mode inside of
+    * tst_res(), since occasionally we get to this point without going
+    * through tst_res() (e.g. internal TWARN messages).
+    */
+   if ( T_mode == DISCARD || (T_mode == NOPASS && ttype != TFAIL &&
+                              ttype != TBROK && ttype != TWARN) )
+      return;
+
+   /*
+    * Fill in the type string according to ttype.
+    */
+   switch ( ttype ) {
+   case TPASS:
+      strcpy(type, "PASS");
+      break;
+   case TFAIL:
+      strcpy(type, "FAIL");
+      break;
+   case TBROK:
+      strcpy(type, "BROK");
+      break;
+   case TRETR:
+      strcpy(type, "RETR");
+      break;
+   case TCONF:
+      strcpy(type, "CONF");
+      break;
+   case TWARN:
+      strcpy(type, "WARN");
+      break;
+   case TINFO:
+      strcpy(type, "INFO");
+      break;
+   default:
+      strcpy(type, "????");
+      break;
+   }  /* switch ( ttype ) */
+
+   /*
+    * Build the result line and print it.
+    */
+   if ( T_mode == VERBOSE ) {
+      fprintf(T_out, "%-8s %4d  %s  :  %s\n", tcid, tnum, type, tmesg);
+   } else {
+      /* condense results if a range is specified */
+      if ( trange > 1 )
+         fprintf(T_out, "%-8s %4d-%-4d  %s  :  %s\n",
+                 tcid, tnum, tnum + trange - 1, type, tmesg);
+      else
+         fprintf(T_out, "%-8s %4d       %s  :  %s\n",
+                 tcid, tnum, type, tmesg);
+   }
+
+   /*
+    * If tst_res() was called with a file, append file contents to the
+    * end of last printed result.
+    */
+   if ( File != NULL )
+      cat_file(File);
+   File = NULL;
+}  /* tst_print() */
+
+
+/*
+ * check_env() - Check the value of the environment variable TOUTPUT and
+ *               set the global variable T_mode.  The TOUTPUT environment
+ *               variable should be set to "VERBOSE", "CONDENSE",
+ *               "NOPASS", or "DISCARD".  If TOUTPUT does not exist or
+ *               is not set to a valid value, the default is "VERBOSE".
+ */
+static void
+check_env()
+{
+   static int first_time = 1;
+   char       *value;      /* value of TOUTPUT environment variable */
+
+#if DEBUG
+   printf("IN check_env\n");
+   fflush(stdout);
+#endif
+
+   if ( !first_time )
+      return;
+
+   first_time = 0;
+
+   if ( (value = getenv(TOUTPUT)) == NULL ) {
+      /* TOUTPUT not defined, use default */
+      T_mode = VERBOSE;
+   } else if ( strcmp(value, TOUT_CONDENSE_S) == 0 ) {
+      T_mode = CONDENSE;
+   } else if ( strcmp(value, TOUT_NOPASS_S) == 0 ) {
+      T_mode = NOPASS;
+   } else if ( strcmp(value, TOUT_DISCARD_S) == 0 ) {
+      T_mode = DISCARD;
+   } else {
+      /* default */
+      T_mode = VERBOSE;
+   }
+
+   return;
+}  /* check_env() */
+
+
+/*
+ * tst_exit() - Call exit() with the value T_exitval, set up by
+ *              tst_res().  T_exitval has a bit set for most of the
+ *              result types that were seen (including TPASS, TFAIL,
+ *              TBROK, TWARN, TCONF).  Also, print the last result (if
+ *              necessary) before exiting.
+ */
+void
+tst_exit()
+{
+#if DEBUG
+   printf("IN tst_exit\n"); fflush(stdout);
+   fflush(stdout);
+#endif
+
+   /*
+    * Call tst_flush() flush any ouput in the buffer or the last
+    * result not printed because of CONDENSE mode.
+    */
+   tst_flush();
+
+   /*
+    * Mask out TRETR, TINFO, and TCONF results from the exit status.
+    */
+   exit(T_exitval & ~(TRETR | TINFO | TCONF));
+}  /* tst_exit() */
+
+
+/*
+ * tst_environ() - Preserve the tst_res() output location, despite any
+ *                 changes to stdout.
+ */
+int
+tst_environ()
+{
+   FILE *fdopen();
+
+   if ( (T_out = fdopen(dup(fileno(stdout)), "w")) == NULL )
+      return(-1);
+   else
+      return(0);
+}  /* tst_environ() */
+
+
+/*
+ * tst_brk() - Fail or break current test case, and break the remaining
+ *             tests cases.
+ */
+void
+tst_brk(int ttype, char *fname, void (*func)(), char *arg_fmt, ...)
+{
+   char    tmesg[USERMESG];      /* expanded message */
+
+#if DEBUG
+   printf("IN tst_brk\n"); fflush(stdout);
+   fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg, if necessary.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Only FAIL, BROK, CONF, and RETR are supported by tst_brk().
+    */
+   if ( ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
+        ttype != TRETR ) {
+      sprintf(Warn_mesg, "tst_brk(): Invalid Type: %d.  Using TBROK",
+              ttype);
+      tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+      ttype = TBROK;
+   }
+
+   /*
+    * Print the first result, if necessary.
+    */
+   if ( Tst_count < TST_TOTAL )
+      tst_res(ttype, fname, tmesg);
+
+   /*
+    * Determine the number of results left to report.
+    */
+   Tst_range = TST_TOTAL - Tst_count;
+
+   /*
+    * Print the rest of the results, if necessary.
+    */
+   if ( Tst_range > 0 ) {
+      if ( ttype == TCONF )
+         tst_res(ttype, NULL,
+                 "Remaining cases not appropriate for configuration");
+      else if ( ttype == TRETR )
+         tst_res(ttype, NULL, "Remaining cases retired");
+      else
+         tst_res(TBROK, NULL, "Remaining cases broken");
+   } else {
+      Tst_range = 1;
+      Expand_varargs = TRUE;
+   }  /* if ( Tst_range > 0 ) */
+
+   /*
+    * If no cleanup function was specified, just return to the caller.
+    * Otherwise call the specified function.  If specified function
+    * returns, call tst_exit().
+    */
+   if ( func != NULL ) {
+      (*func)();
+      tst_exit();
+   }
+
+   return;
+}  /* tst_brk() */
+
+
+/*
+ * tst_brkloop() - Fail or break current test case, and break the
+ *                 remaining test cases within test case loop.
+ */
+void
+tst_brkloop(int ttype, char *fname, void (*func)(), char *arg_fmt, ...)
+{
+   char    tmesg[USERMESG];      /* expanded message */
+
+#if DEBUG
+   printf("IN tst_brkloop\n"); fflush(stdout);
+   fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Verify that Tst_lpstart & Tst_lptotal are valid.
+    */
+   if ( Tst_lpstart < 0 || Tst_lptotal < 0 ) {
+      tst_print(TCID, 0, 1, TWARN,
+                "tst_brkloop(): Tst_lpstart & Tst_lptotal must both be assigned non-negative values");
+      Expand_varargs = TRUE;
+      return;
+   }
+
+   /*
+    * Only FAIL, BROK, CONF, and RETR are supported by tst_brkloop().
+    */
+   if ( ttype != TFAIL && ttype != TBROK && ttype != TCONF &&
+        ttype != TRETR ) {
+      sprintf(Warn_mesg,
+              "tst_brkloop(): Invalid Type: %d.  Using TBROK",
+              ttype);
+      tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+      ttype = TBROK;
+   }
+
+   /*
+    * Print the first result, if necessary.
+    */
+   if ( Tst_count < Tst_lpstart + Tst_lptotal )
+      tst_res(ttype, fname, tmesg);
+
+   /*
+    * Determine the number of results left to report.
+    */
+   Tst_range = Tst_lptotal + Tst_lpstart - Tst_count;
+
+   /*
+    * Print the rest of the results, if necessary.
+    */
+   if ( Tst_range > 0 ) {
+      if ( ttype == TCONF )
+         tst_res(ttype, NULL,
+                 "Remaining cases in loop not appropriate for configuration");
+      else if ( ttype == TRETR )
+         tst_res(ttype, NULL, "Remaining cases in loop retired");
+      else
+         tst_res(TBROK, NULL, "Remaining cases in loop broken");
+   } else {
+      Tst_range = 1;
+      Expand_varargs = TRUE;
+   }  /* if ( Tst_range > 0 ) */
+
+   /*
+    * If a cleanup function was specified, call it.
+    */
+   if ( func != NULL )
+      (*func)();
+}  /* tst_brkloop() */
+
+
+/*
+ * tst_resm() - Interface to tst_res(), with no filename.
+ */
+void
+tst_resm(int ttype, char *arg_fmt, ...)
+{
+   char    tmesg[USERMESG];      /* expanded message */
+
+#if DEBUG
+   printf("IN tst_resm\n"); fflush(stdout);
+   fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Call tst_res with a null filename argument.
+    */
+   tst_res(ttype, NULL, tmesg);
+}  /* tst_resm() */
+
+
+/*
+ * tst_brkm() - Interface to tst_brk(), with no filename.
+ */
+void
+tst_brkm(int ttype, void (*func)(), char *arg_fmt, ...)
+{
+   char    tmesg[USERMESG];      /* expanded message */
+
+#if DEBUG
+   printf("IN tst_brkm\n"); fflush(stdout);
+   fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Call tst_brk with a null filename argument.
+    */
+   tst_brk(ttype, NULL, func, tmesg);
+}  /* tst_brkm() */
+
+
+/*
+ * tst_brkloopm() - Interface to tst_brkloop(), with no filename.
+ */
+void
+tst_brkloopm(int ttype, void (*func)(), char *arg_fmt, ...)
+{
+   char    tmesg[USERMESG];      /* expanded message */
+
+#if DEBUG
+   printf("IN tst_brkloopm\n");
+   fflush(stdout);
+#endif
+
+   /*
+    * Expand the arg_fmt string into tmesg.
+    */
+   EXPAND_VAR_ARGS(arg_fmt, tmesg);
+
+   /*
+    * Call tst_brkloop with a null filename argument.
+    */
+   tst_brkloop(ttype, NULL, func, tmesg);
+}  /* tst_brkloopm() */
+
+
+/*
+ * cat_file() - Print the contents of a file to standard out.
+ */
+static void
+cat_file(char *filename)
+{
+   FILE *fp;                  /* file pointer */
+   int  b_read;               /* number of bytes read with read() */
+   int  b_written;            /* number of bytes written with write() */
+   char buffer[BUFSIZ];       /* read/write buffer; BUFSIZ defined in */
+                              /* stdio.h */
+
+#if DEBUG
+   printf("IN cat_file\n"); fflush(stdout);
+#endif
+
+   /*
+    * Open the file for reading.
+    */
+   if ( (fp = fopen(filename, "r")) == NULL ) {
+      sprintf(Warn_mesg,
+              "tst_res(): fopen(%s, \"r\") failed; errno = %d: %s",
+              filename, errno, strerror(errno));
+      tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+      return;
+   }  /* if ( fopen(filename, "r") == -1 ) */
+
+   /*
+    * While something to read, continue to read blocks.
+    * From fread(3) man page: 
+    *   If an error occurs, or the end-of-file is reached, the return
+    *   value is zero.
+    */
+   errno = 0;
+   while ( (b_read = fread((void *)buffer, 1, BUFSIZ, fp)) != (size_t)0 ) {
+      /*
+       * Write what was read to the result output stream.
+       */
+      if ( (b_written = fwrite((void *)buffer, 1, b_read, T_out)) !=
+           b_read ) {
+         sprintf(Warn_mesg,
+                 "tst_res(): While trying to cat \"%s\", fwrite() wrote only %d of %d bytes",
+                 filename, b_written, b_read);
+         tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+         break;
+      }  /* if ( b_written != b_read ) */
+   }  /* while ( fread() != 0 ) */
+
+   /*
+    * Check for an fread() error.
+    */
+   if ( !feof(fp) ) {
+      sprintf(Warn_mesg,
+              "tst_res(): While trying to cat \"%s\", fread() failed, errno = %d: %s",
+              filename, errno, strerror(errno));
+      tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+   }  /* if ( !feof() ) */
+
+   /*
+    * Close the file.
+    */
+   if ( fclose(fp) == EOF ) {
+      sprintf(Warn_mesg,
+              "tst_res(): While trying to cat \"%s\", fclose() failed, errno = %d: %s",
+              filename, errno, strerror(errno));
+      tst_print(TCID, 0, 1, TWARN, Warn_mesg);
+   }  /* if ( fclose(fp) == EOF ) */
+}  /* cat_file() */
+
+
+
+#ifdef UNIT_TEST
+/****************************************************************************
+ * Unit test code: Takes input from stdin and can make the following
+ *                 calls: tst_res(), tst_resm(), tst_brk(), tst_brkm(),
+ *                 tst_flush_buf(), tst_exit().
+ ****************************************************************************/
+int  TST_TOTAL = 10;
+char *TCID = "TESTTCID";
+
+#define RES  "tst_res.c UNIT TEST message; ttype = %d; contents of \"%s\":"
+#define RESM "tst_res.c UNIT TEST message; ttype = %d"
+
+main()
+{
+   int  ttype;
+   int  range;
+   char *chrptr;
+   char chr;
+   char fname[MAXMESG];
+
+   printf("UNIT TEST of tst_res.c.  Options for ttype:\n\
+   -1 : call tst_exit()\n\
+   -2 : call tst_flush()\n\
+   -3 : call tst_brk()\n\
+   -4 : call tst_brkloop()\n\
+   -5 : call tst_res() with a range\n\
+    0 : call tst_res(TPASS, ...)\n\
+    1 : call tst_res(TFAIL, ...)\n\
+    2 : call tst_res(TBROK, ...)\n\
+    4 : call tst_res(TWARN, ...)\n\
+    8 : call tst_res(TRETR, ...)\n\
+   16 : call tst_res(TINFO, ...)\n\
+   32 : call tst_res(TCONF, ...)\n\n");
+
+   while ( 1 ) {
+      printf("Enter ttype (-5,-4,-3,-2,-1,0,1,2,4,8,16,32): ");
+      (void) scanf("%d%c", &ttype, &chr);
+
+
+      switch ( ttype ) {
+      case -1:
+         tst_exit();
+         break;
+
+      case -2:
+         tst_flush();
+         break;
+
+      case -3:
+         printf("Enter the current type (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
+         (void) scanf("%d%c", &ttype, &chr);
+         printf("Enter file name (<cr> for none): ");
+         gets(fname);
+         if ( strcmp(fname, "") == 0 )
+            tst_brkm(ttype, tst_exit, RESM, ttype);
+         else
+            tst_brk(ttype, fname, tst_exit, RES, ttype, fname);
+         break;
+
+      case -4:
+         printf("Enter the size of the loop: ");
+         (void) scanf("%d%c", &range, &chr);
+         Tst_lpstart = Tst_count;
+         Tst_lptotal = range;
+         printf("Enter the current type (1=FAIL, 2=BROK, 8=RETR, 32=CONF): ");
+         (void) scanf("%d%c", &ttype, &chr);
+         printf("Enter file name (<cr> for none): ");
+         gets(fname);
+         if ( strcmp(fname, "") == 0 )
+            tst_brkloopm(ttype, NULL, RESM, ttype);
+         else
+            tst_brkloop(ttype, fname, NULL, RES, ttype, fname);
+         break;
+
+      case -5:
+         printf("Enter the size of the range: ");
+         (void) scanf("%d%c", &Tst_range, &chr);
+         printf("Enter the current type (0,1,2,4,8,16,32): ");
+         (void) scanf("%d%c", &ttype, &chr);
+         /* fall through to tst_res() call */
+
+      default:
+         printf("Enter file name (<cr> for none): ");
+         gets(fname);
+         if ( strcmp(fname, "") == 0 )
+            tst_resm(ttype, RESM, ttype);
+         else
+            tst_res(ttype, fname, RES, ttype, fname);
+         break;
+      }  /* switch() */
+   }  /* while() */
+}
+#endif  /* UNIT_TEST */
diff --git a/lib/tst_sig.c b/lib/tst_sig.c
new file mode 100644
index 0000000..090a946
--- /dev/null
+++ b/lib/tst_sig.c
@@ -0,0 +1,221 @@
+/*
+ * 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/
+ */
+
+/* $Id: tst_sig.c,v 1.1 2000/07/27 17:13:19 alaffin Exp $ */
+
+/*****************************************************************************
+	OS Testing  - Silicon Graphics, Inc.
+
+	FUNCTION IDENTIFIER : tst_sig  Set up for unexpected signals.
+
+	AUTHOR          : David D. Fenner
+
+	CO-PILOT        : Bill Roske
+
+	DATE STARTED    : 06/06/90
+
+	This module may be linked with c-modules requiring unexpected
+	signal handling.  The parameters to tst_sig are as follows:
+
+		fork_flag - set to FORK or NOFORK depending upon whether the
+			calling program executes a fork() system call.  It
+			is normally the case that the calling program treats
+			SIGCLD as an expected signal if fork() is being used.
+
+		handler - a pointer to the unexpected signal handler to
+			be executed after an unexpected signal has been
+			detected.  If handler is set to DEF_HANDLER, a 
+			default handler is used.  This routine should be
+			declared as function returning an int.
+
+		cleanup - a pointer to a cleanup routine to be executed
+			by the unexpected signal handler before tst_exit is
+			called.  This parameter is set to NULL if no cleanup
+			routine is required.  An external variable, T_cleanup
+			is set so that other user-defined handlers have 
+			access to the cleanup routine.  This routine should be
+			declared as returning type void.
+
+***************************************************************************/
+
+#ifndef CRAY
+#define _BSD_SIGNALS	1	/* Specify that we are using BSD signal interface */
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <signal.h>
+#include "test.h"
+
+#define MAXMESG 150		/* size of mesg string sent to tst_res */
+
+void (*T_cleanup)();		/* pointer to cleanup function */
+
+extern int errno;
+static void def_handler();		/* default signal handler */
+
+/****************************************************************************
+ * tst_sig() : set-up to catch unexpected signals.  fork_flag is set to NOFORK
+ *    if SIGCLD is to be an "unexpected signal", otherwise it is set to
+ *    FORK.  cleanup points to a cleanup routine to be executed before
+ *    tst_exit is called (cleanup is set to NULL if no cleanup is desired).
+ *    handler is a pointer to the signal handling routine (if handler is
+ *    set to NULL, a default handler is used).
+ ***************************************************************************/
+
+void
+tst_sig(fork_flag, handler, cleanup)
+int fork_flag;			/* FORK if SIGCLD is expected, NOFORK if unexpected */
+void (*handler)();		/* pointer to signal handler routine or DEF_HANDLER */
+void (*cleanup)();		/* pointer to cleanup routine or NULL */
+{
+	extern char *TCID;		/* test case id string (in calling prog) */
+
+	char mesg[MAXMESG];		/* message buffer for tst_res */
+	int sig;
+
+	/*
+	 * save T_cleanup and handler function pointers
+	 */
+	T_cleanup = cleanup;		/* used by default handler */
+
+	if (handler == DEF_HANDLER) {
+		/* use default handler */
+		handler = def_handler;
+	}
+
+	/*
+	 * now loop through all signals and set the handlers
+	 */
+
+	for (sig = 1; sig < NSIG; sig++) {
+	    /*
+	     * SIGKILL is never unexpected.
+	     * SIGCLD is only unexpected when
+	     *    no forking is being done.
+	     * SIGINFO is used for file quotas and should be expected
+	     */
+
+	    switch (sig) {
+	        case SIGKILL:
+	        case SIGSTOP:
+	        case SIGCONT:
+#ifdef CRAY
+	        case SIGINFO:
+	        case SIGRECOVERY:	/* allow chkpnt/restart */
+#endif  /* CRAY */
+
+#ifdef SIGSWAP
+  case SIGSWAP:
+#endif /* SIGSWAP */
+
+#ifdef SIGCKPT
+	        case SIGCKPT:
+#endif
+#ifdef SIGRESTART
+	        case SIGRESTART:
+#endif
+                /*
+                 * pthread-private signals SIGPTINTR and SIGPTRESCHED.
+                 * Setting a handler for these signals is disallowed when
+                 * the binary is linked against libpthread.
+                 */
+#ifdef SIGPTINTR
+                case SIGPTINTR:
+#endif /* SIGPTINTR */
+#ifdef SIGPTRESCHED
+                case SIGPTRESCHED:
+#endif /* SIGPTRESCHED */
+
+	            break;
+
+	        case SIGCLD:
+	            if ( fork_flag == FORK )
+		        continue;
+
+	        default:
+		    if (signal(sig, handler) == SIG_ERR) {
+		        (void) sprintf(mesg,
+			    "signal() failed for signal %d. error:%d %s.",
+			    sig, errno, strerror(errno));
+		        tst_resm(TWARN, mesg);
+		    }
+		break;
+            }
+#ifdef __sgi
+	    /* On irix  (07/96), signal() fails when signo is 33 or higher */
+	    if ( sig+1 >= 33 )
+		break;
+#endif  /*  __sgi */
+
+	} /* endfor */
+}
+
+
+
+/****************************************************************************
+ * def_handler() : default signal handler that is invoked when
+ *      an unexpected signal is caught.
+ ***************************************************************************/
+
+static void
+def_handler(sig)
+int sig;	/* signal that caused the interrupt */
+{
+	extern int  Tst_count;	/* number of items completed (in tst_res.c) */
+	extern int  TST_TOTAL;	/* total number of test items (in calling prog) */
+	char mesg[MAXMESG];		/* holds tst_res message */
+
+	/* first reset trap for this signal (except SIGCLD - its weird) */
+	if ((sig != SIGCLD) && (sig != SIGSTOP) && (sig != SIGCONT)) {
+		if (signal(sig, def_handler) == SIG_ERR) {
+			(void) sprintf(mesg,
+				"def_handler: signal() failed for signal %d. error:%d %s.",
+				sig, errno, strerror(errno));
+			tst_resm(TWARN, mesg);
+		}
+	}
+
+	(void) sprintf(mesg, "Unexpected signal %d received.", sig);
+
+	/*
+         * Break remaining test cases, do any cleanup, then exit
+	 */
+	tst_brkm(TBROK, 0, mesg);
+
+	/* now cleanup and exit */
+	if (T_cleanup) {
+		(*T_cleanup)();
+	}
+
+	tst_exit();
+}
diff --git a/lib/tst_tmpdir.c b/lib/tst_tmpdir.c
new file mode 100644
index 0000000..e036609
--- /dev/null
+++ b/lib/tst_tmpdir.c
@@ -0,0 +1,351 @@
+/*
+ * 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/
+ */
+
+/* $Id: tst_tmpdir.c,v 1.1 2000/07/27 17:13:19 alaffin Exp $ */
+
+/**********************************************************
+ *
+ *    OS Testing - Silicon Graphics, Inc.
+ *
+ *    FUNCTION NAME     : tst_tmpdir, tst_rmdir
+ *
+ *    FUNCTION TITLE    : Create/remove a testing temp dir
+ *
+ *    SYNOPSIS:
+ *      void tst_tmpdir();
+ *      void tst_rmdir();
+ *
+ *    AUTHOR            : Dave Fenner
+ *
+ *    INITIAL RELEASE   : UNICOS 8.0
+ *
+ *    DESCRIPTION
+ *      tst_tmpdir() is used to create a unique, temporary testing
+ *      directory, and make it the current working directory.
+ *      tst_rmdir() is used to remove the directory created by
+ *      tst_tmpdir().
+ *
+ *      Setting the env variable "TDIRECTORY" will override the creation
+ *      of a new temp dir.  The directory specified by TDIRECTORY will
+ *      be used as the temporary directory, and no removal will be done
+ *      in tst_rmdir().
+ *
+ *    RETURN VALUE
+ *      Neither tst_tmpdir() or tst_rmdir() has a return value.
+ *
+ *#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#*#**/
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>        /* for getenv() */
+#include <string.h>        /* for string functions */
+#include <unistd.h>        /* for sysconf(), getcwd(), rmdir() */
+#include <sys/types.h>     /* for mkdir() */
+#include <sys/stat.h>      /* for mkdir() */
+#include "test.h"
+#include "rmobj.h"
+
+/*
+ * Define some useful macros.
+ */
+#define PREFIX_SIZE     4
+#define STRING_SIZE     256
+#define DIR_MODE        0777  /* mode of tmp dir that will be created */
+
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+
+/*
+ * Define function prototypes.
+ */
+static void tmpdir_cleanup();
+
+/*
+ * Define global variables.
+ */
+extern char *TCID;            /* defined/initialized in main() */
+extern int  TST_TOTAL;        /* defined/initialized in main() */
+extern char *TESTDIR;         /* the directory created; defined in */
+                              /* tst_res.c */
+
+/*
+ * tst_tmpdir() - Create a unique temporary directory and chdir() to it.
+ *                It expects the caller to have defined/initialized the
+ *                TCID/TST_TOTAL global variables.  The TESTDIR global
+ *                variable will be set to the directory that gets used
+ *                as the testing directory.
+ *
+ *                NOTE: This function must be called BEFORE any activity
+ *                that would require CLEANUP.  If tst_tmpdir() fails, it
+ *                cleans up afer itself and calls tst_exit() (i.e. does
+ *                not return).
+ */
+#undef   FN_NAME
+#define  FN_NAME  "tst_tmpdir()"
+
+void
+tst_tmpdir()
+{
+   char prefix[PREFIX_SIZE];     /* first three characters from TCID */
+   int  no_cleanup = 0;          /* !0 means TDIRECTORY env var was set */
+
+   /*
+    * If the TDIRECTORY env variable is not set, a temp dir will be
+    * created.
+    */
+   if ( (TESTDIR = getenv(TDIRECTORY)) == NULL ) {
+      /*
+       * Create a unique name based on the first three characters of the
+       * TCID.  The last byte in "prefix" is for the null.
+       */
+      strncpy(prefix, TCID, PREFIX_SIZE - 1);
+      prefix[PREFIX_SIZE-1] = '\0';
+      if ( (TESTDIR = tempnam(TEMPDIR, prefix)) == NULL )
+         tst_brkm(TBROK, tmpdir_cleanup, "%s: tempnam(%s, %s) failed",
+                  FN_NAME, TEMPDIR, prefix);
+
+      /*
+       * Create the temporary directory.
+       */
+      if ( mkdir(TESTDIR, DIR_MODE) == -1 )
+         tst_brkm(TBROK, tmpdir_cleanup,
+                  "%s: mkdir(%s, %#o) failed; errno = %d: %s", 
+                  FN_NAME, TESTDIR, DIR_MODE, errno, strerror(errno));
+
+      /*
+       * Change the group on this temporary directory to be that of the
+       * gid of the person running the tests.
+       */
+      if ( chown(TESTDIR, -1, getgid()) == -1 )
+         tst_brkm(TBROK, tmpdir_cleanup,
+                  "chown(%s, -1, %d) failed; errno = %d: %s", 
+                  TESTDIR, getgid(), errno, strerror(errno));
+   } else {
+      /*
+       * The TDIRECTORY env. variable is set, so no temp dir is created.
+       * Also, no clean up will be done via tst_rmdir().
+       */
+      no_cleanup++;
+#if UNIT_TEST
+      printf("TDIRECTORY env var is set\n");
+#endif
+   }
+
+#if UNIT_TEST
+      printf("TESTDIR = %s\n", TESTDIR);
+#endif
+
+   /*
+    * Change to the temporary directory.  If the chdir() fails, issue
+    * TBROK messages for all test cases, attempt to remove the
+    * directory (if it was created), and exit.  If the removal also
+    * fails, also issue a TWARN message.   
+    */
+   if ( chdir(TESTDIR) == -1 ) {
+      tst_brkm(TBROK, NULL, "%s: chdir(%s) failed; errno = %d: %s",
+               FN_NAME, TESTDIR, errno, strerror(errno) );
+
+      /* Try to remove the directory */
+      if ( !no_cleanup && rmdir(TESTDIR) == -1 )
+         tst_resm(TWARN, "%s: rmdir(%s) failed; errno = %d: %s",
+                  FN_NAME, TESTDIR, errno, strerror(errno) );
+
+      tmpdir_cleanup();
+   }
+
+#if UNIT_TEST
+   printf("CWD is %s\n", getcwd((char *)NULL, PATH_MAX));
+#endif
+
+   /*
+    *  If we made through all this stuff, return.
+    */
+   return;
+}  /* tst_tmpdir() */
+
+
+/*
+ *
+ * tst_rmdir() - Recursively remove the temporary directory created by
+ *               tst_tmpdir().  This function is intended ONLY as a
+ *               companion to tst_tmpdir().  If the TDIRECTORY
+ *               environment variable is set, no cleanup will be
+ *               attempted.
+ */ 
+#undef   FN_NAME
+#define  FN_NAME  "tst_rmdir()"
+
+void
+tst_rmdir()
+{
+   char *errmsg;
+   char *tdirectory;
+   char current_dir[PATH_MAX];   /* current working directory */
+   char parent_dir[PATH_MAX];    /* directory above TESTDIR */
+   char *basename;               /* basename of the TESTDIR */
+
+   /*
+    * If the TDIRECTORY env variable is set, this indicates that no
+    * temp dir was created by tst_tmpdir().  Thus no cleanup will be
+    * necessary.
+    */
+   if ( (tdirectory = getenv(TDIRECTORY)) != NULL ) {
+#if UNIT_TEST
+      printf("\"TDIRECORY\" env variable is set; no cleanup was performed\n");
+#endif
+      return;
+   }
+   
+   /*
+    * Check that TESTDIR is not NULL.
+    */
+   if ( TESTDIR == NULL ) {
+      tst_resm(TWARN, "%s: TESTDIR was NULL; no removal attempted",
+               FN_NAME);
+      return;
+   }
+
+   /*
+    * Check that the value of TESTDIR is not "*" or "/".  These could
+    * have disastrous effects in a test run by root.
+    */
+   if ( strcmp(TESTDIR, "/") == 0 ) {
+      tst_resm(TWARN,
+               "%s: Recursive remove of root directory not attempted",
+               FN_NAME);
+      return;
+   }
+
+   if ( strchr(TESTDIR, '*') != NULL ) {
+      tst_resm(TWARN, "%s: Recursive remove of '*' not attempted",
+               FN_NAME);
+      return;
+   }
+
+   /*
+    * Get the directory name of TESTDIR.  If TESTDIR is a relative path,
+    * get full path.
+    */
+   if ( TESTDIR[0] != '/' ) {
+      if ( getcwd(current_dir,PATH_MAX) == NULL )
+         strcpy(parent_dir, TESTDIR);
+      else
+         sprintf(parent_dir, "%s/%s", current_dir, TESTDIR);
+   } else {
+      strcpy(parent_dir, TESTDIR);
+   }
+   if ( (basename = strrchr(parent_dir, '/')) != NULL ) {
+      *basename='\0';   /* terminate at end of parent_dir */
+   }
+
+   /*
+    * Change directory to parent_dir (The dir above TESTDIR).
+    */
+   if ( chdir(parent_dir) != 0 )
+      tst_resm(TWARN,
+               "%s: chdir(%s) failed; errno = %d: %s\nAttempting to remove temp dir anyway",
+               FN_NAME, parent_dir, errno, strerror(errno));
+   
+   /*
+    * Attempt to remove the "TESTDIR" directory, using rmobj().
+    */
+   if ( rmobj(TESTDIR, &errmsg) == -1 )
+      tst_resm(TWARN, "%s: rmobj(%s) failed: %s",
+               FN_NAME, TESTDIR, errmsg);
+
+   return;
+}  /* tst_rmdir() */
+
+
+/*
+ * tmpdir_cleanup() - This function is used when tst_tmpdir()
+ *                    encounters an error, and must cleanup and exit.
+ *                    It prints a warning message via tst_resm(), and
+ *                    then calls tst_exit().
+ */
+#undef  FN_NAME
+#define FN_NAME "tst_tmpdir()"
+
+static void
+tmpdir_cleanup()
+{
+   /*
+    * Print a warning message and call tst_exit() to exit the test.
+    */
+   tst_resm(TWARN, "%s: No user cleanup function called before exiting",
+            FN_NAME);
+   tst_exit();
+}  /* tmpdir_cleanup() */
+
+
+#ifdef UNIT_TEST
+/****************************************************************************
+ * Unit test code: Takes input from stdin and can make the following
+ *                 calls: tst_tmpdir(), tst_rmdir().
+ ****************************************************************************/
+int  TST_TOTAL = 10;
+char *TCID = "TESTTCID";
+
+main()
+{
+   int  option;
+   char *chrptr;
+
+   printf("UNIT TEST of tst_tmpdir.c.  Options to try:\n\
+   -1 : call tst_exit()\n\
+    0 : call tst_tmpdir()\n\
+    1 : call tst_rmdir()\n\n");
+
+   while ( 1 ) {
+      printf("Enter options (-1, 0, 1): ");
+      (void) scanf("%d%c", &option, &chrptr);
+
+      switch ( option ) {
+      case -1:
+         tst_exit();
+         break;
+
+      case 0:
+         tst_tmpdir();
+         break;
+
+      case 1:
+         tst_rmdir();
+         break;
+      }  /* switch() */
+   }  /* while() */
+}
+#endif  /* UNIT_TEST */