summaryrefslogtreecommitdiff
path: root/src/tet3/tcm
diff options
context:
space:
mode:
authorjamey <jamey>2005-10-31 23:09:06 +0000
committerjamey <jamey>2005-10-31 23:09:06 +0000
commit429ed4219a23e356fbbf0066a4330353e4e764a2 (patch)
treed928257f9b7715dad66711e065a9765252bfbaae /src/tet3/tcm
parent41fe38e5829b9ef59b67fae5d08ee0ca5ea6b803 (diff)
Importing TET 3.3h (unsupported) sources from http://tetworks.opengroup.org/tet/tet3.3h-unsup.src.tgz.
Omitted the contrib directory: we don't care, and the license situation wasn't entirely clear.
Diffstat (limited to 'src/tet3/tcm')
-rw-r--r--src/tet3/tcm/child.c190
-rw-r--r--src/tet3/tcm/ckversion.c142
-rw-r--r--src/tet3/tcm/dtcm.c1081
-rw-r--r--src/tet3/tcm/dynlink.c67
-rw-r--r--src/tet3/tcm/ictp.c888
-rw-r--r--src/tet3/tcm/inetlib.mk50
-rw-r--r--src/tet3/tcm/litelib.mk43
-rw-r--r--src/tet3/tcm/makefile143
-rw-r--r--src/tet3/tcm/makefile.orig143
-rw-r--r--src/tet3/tcm/shared.mk175
-rw-r--r--src/tet3/tcm/shared.mk.orig175
-rw-r--r--src/tet3/tcm/tcm.c363
-rw-r--r--src/tet3/tcm/tcm.c.orig360
-rw-r--r--src/tet3/tcm/tcm_bs.c226
-rw-r--r--src/tet3/tcm/tcm_in.c305
-rw-r--r--src/tet3/tcm/tcm_xt.c322
-rw-r--r--src/tet3/tcm/tcmchild.c376
-rw-r--r--src/tet3/tcm/tcmchild.c.orig376
-rw-r--r--src/tet3/tcm/tcmfuncs.c408
-rw-r--r--src/tet3/tcm/tcmfuncs.h56
-rw-r--r--src/tet3/tcm/tcmrem.c270
-rw-r--r--src/tet3/tcm/xtilib.mk50
22 files changed, 6209 insertions, 0 deletions
diff --git a/src/tet3/tcm/child.c b/src/tet3/tcm/child.c
new file mode 100644
index 00000000..faf3b5ed
--- /dev/null
+++ b/src/tet3/tcm/child.c
@@ -0,0 +1,190 @@
+/*
+ * SCCS: @(#)child.c 1.22 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)child.c 1.22 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)child.c 1.22 98/09/01 TETware release 3.3
+NAME: child.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: October 1992
+
+DESCRIPTION:
+ tet_tcmc_main() is called from a different main() wrapper for each API,
+ providing the main() function for processes started by tet_exec()
+ and tet_remexec().
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd., December 1993
+ removed reference to dapi.h
+
+ Geoff Clare, UniSoft Ltd., August 1996
+ Changes for TETWare.
+
+ Geoff Clare, UniSoft Ltd., 21 August 1996
+ Made include of <stdio.h> non-conditional.
+
+ Geoff Clare, UniSoft Ltd, Sept 1996
+ Moved tet_blockable_sigs setup to tet_init_blockable_sigs().
+ Changes for TETware-Lite.
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+
+ Geoff Clare, UniSoft Ltd., July 1997
+ Changes to support NT threads.
+
+ Andrew Dingwall, UniSoft Ltd., July 1997
+ Added code to generate a new (unique) context value on Win32 systems,
+ since it is not possible for tet_spawn() to call tet_setcontext()
+ on a Win32 system.
+
+ Andrew Dingwall, UniSoft Ltd., February 1998
+ Use TETware-specific macros to access threads functions and
+ data items.
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+ Note that this includes a change to the calling convention for
+ child processes.
+
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "alarm.h"
+#include "error.h"
+#include "synreq.h"
+#include "dtetlib.h"
+#include "globals.h"
+#include "tcmfuncs.h"
+#include "tet_api.h"
+#include "apilib.h"
+#include "sigsafe.h"
+
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+
+/* global variables, values inhereted from tet_exec() and tet_remexec() */
+#ifdef TET_THREADS
+static int start_errno;
+static int start_child;
+static int start_alrm_flag;
+static long start_block;
+static long start_sequence;
+#endif /* TET_THREADS */
+
+
+int tet_tcmc_main(argc, argv)
+int argc;
+char **argv;
+{
+ register int rc;
+
+
+#ifdef TET_THREADS
+ /* initial thread ID */
+ tet_start_tid = TET_THR_SELF();
+
+ /* set up thread-specific data */
+ if (TET_THR_KEYCREATE(&tet_errno_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_child_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_alrm_flag_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_block_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_sequence_key) != 0)
+ {
+ /* can't use tet_error() yet */
+ (void) fprintf(stderr,
+ "%s: TET_THR_KEYCREATE() failed in TCM startup",
+ tet_progname);
+ exit(EXIT_FAILURE);
+ }
+ TET_THR_SETSPECIFIC(tet_errno_key, (void *) &start_errno);
+ TET_THR_SETSPECIFIC(tet_child_key, (void *) &start_child);
+ TET_THR_SETSPECIFIC(tet_alrm_flag_key, (void *) &start_alrm_flag);
+ TET_THR_SETSPECIFIC(tet_block_key, (void *) &start_block);
+ TET_THR_SETSPECIFIC(tet_sequence_key, (void *) &start_sequence);
+
+ /* initialise all mutexes */
+ tet_mtx_init();
+#endif
+
+ if (argc < TET_TCMC_USER_ARGS + 1)
+ fatal(0, "argument count wrong; process must be executed by",
+ tet_callfuncname());
+
+ /*
+ ** set the global variables from the command line -
+ ** on WIN32 systems there is no fork() in the parent process so
+ ** tet_setcontext() and tet_setblock() have not yet been called;
+ ** so argv[3] and argv[4] are the context and block values from the
+ ** parent and we must simulate calls to tet_setcontext() and
+ ** tet_setblock() in this process
+ **
+ ** the pids get reused too quickly on WIN32 systems to be useful
+ ** as a context value;
+ ** we do the best we can to generate a unique context value
+ ** which can be used to distinguish journal output from that
+ ** of other processes that write to the same journal
+ */
+ tet_thistest = atoi(*(argv + TET_TCMC_THISTEST));
+ tet_activity = atol(*(argv + TET_TCMC_ACTIVITY));
+ tet_context = atol(*(argv + TET_TCMC_CONTEXT));
+# ifdef TET_THREADS
+ tet_next_block = atol(*(argv + TET_TCMC_BLOCK));
+# else
+ tet_block = atol(*(argv + TET_TCMC_BLOCK));
+# endif
+
+ argc -= TET_TCMC_USER_ARGS;
+ argv += TET_TCMC_USER_ARGS;
+ tet_pname = *argv;
+
+ tet_init_blockable_sigs();
+
+ /* initialise the server and transport stuff */
+ tet_tcminit(argc, argv);
+
+ /* start a new block and read in the config variables */
+ tet_setblock();
+ tet_config();
+
+ /* call the user-supplied program */
+ rc = tet_main(argc, argv);
+
+#ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init();
+#endif
+
+ /* log off all the servers and exit */
+ tet_logoff();
+ return(rc);
+}
+
diff --git a/src/tet3/tcm/ckversion.c b/src/tet3/tcm/ckversion.c
new file mode 100644
index 00000000..76d016c6
--- /dev/null
+++ b/src/tet3/tcm/ckversion.c
@@ -0,0 +1,142 @@
+/*
+ * SCCS: @(#)ckversion.c 1.1 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * Copyright (c) 1998 The Open Group
+ * All rights reserved.
+ *
+ * No part of this source code may be reproduced, stored in a retrieval
+ * system, or transmitted, in any form or by any means, electronic,
+ * mechanical, photocopying, recording or otherwise, except as stated
+ * in the end-user licence agreement, without the prior permission of
+ * the copyright owners.
+ * A copy of the end-user licence agreement is contained in the file
+ * Licence which accompanies this distribution.
+ *
+ * Motif, OSF/1, UNIX and the "X" device are registered trademarks and
+ * IT DialTone and The Open Group are trademarks of The Open Group in
+ * the US and other countries.
+ *
+ * X/Open is a trademark of X/Open Company Limited in the UK and other
+ * countries.
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ckversion.c 1.1 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)ckversion.c 1.1 98/09/01 TETware release 3.3
+NAME: ckversion.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: July 1998
+
+DESCRIPTION:
+ function to check the version number of the shared API library
+
+ this file must reside in the staticly-linked part of the TCM
+ no calls to TETware library functions are allowed from this file
+
+MODIFICATIONS:
+
+************************************************************************/
+
+#include <stdio.h>
+#include <string.h>
+#include "dtmac.h"
+#include "globals.h"
+#include "tet_api.h"
+#include "apilib.h"
+#include "tcmfuncs.h"
+
+
+/*
+** the definition of TET_VERSION must be here and not in a header file
+** because we want to pick up the value of the Q keyword that is defined
+** in this file
+**
+** this definition of TET_VERSION (before expansion by SCCS) must be the same
+** as the one in apilib/libvers.c
+*/
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define TET_VERSION "3.3-lite"
+#else /* -START-LITE-CUT- */
+# define TET_VERSION "3.3"
+#endif /* -END-LITE-CUT- */
+
+#define TET_VERSION_STRINGS expected_apilib_version
+#define TET_VERSION_STORAGE_CLASS static
+
+/*
+** apilib/version.c contains a definition of TET_VERSION_STRINGS in terms
+** of the #defines supplied in this file
+*/
+#include "../apilib/version.c"
+
+
+/* static function declarations */
+static int mstrcmp PROTOLIST((char **, char **));
+static void rptversion PROTOLIST((char *, char **));
+
+
+/*
+** tet_check_apilib_version() - check that the version number in
+** the shared API library is what we expect
+**
+** there is no return if they're different
+*/
+
+void tet_check_apilib_version()
+{
+ if (mstrcmp(tet_apilib_version, expected_apilib_version)) {
+ (void) fprintf(stderr,
+ "%s: using wrong version of the API library\n",
+ tet_progname);
+ rptversion("expected", expected_apilib_version);
+ rptversion("found ", tet_apilib_version);
+ exit(1);
+ }
+}
+
+/*
+** mstrcmp() - compare two arrays or strings
+**
+** return -ve value, zero or +ve value if sp1 is found, respectively,
+** to be less than, equal to or greater than sp2
+*/
+
+static int mstrcmp(sp1, sp2)
+char **sp1, **sp2;
+{
+ int rc;
+
+ while (*sp1 && *sp2)
+ if ((rc = strcmp(*sp1++, *sp2++)) != 0)
+ return(rc);
+
+ if (!*sp1 && !*sp2)
+ return(0);
+ else if (!*sp1)
+ return(-1);
+ else
+ return(1);
+}
+
+/*
+** rptversion() - report a version string array to stderr
+*/
+
+static void rptversion(s, sp)
+char *s, **sp;
+{
+ (void) fprintf(stderr, "%s: %s version:", tet_progname, s);
+ while (*sp)
+ (void) fprintf(stderr, " %s", *sp++);
+ (void) putc('\n', stderr);
+ (void) fflush(stderr);
+}
+
diff --git a/src/tet3/tcm/dtcm.c b/src/tet3/tcm/dtcm.c
new file mode 100644
index 00000000..43671300
--- /dev/null
+++ b/src/tet3/tcm/dtcm.c
@@ -0,0 +1,1081 @@
+/*
+ * SCCS: @(#)dtcm.c 1.33 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1996 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ * A copy of the end-user licence agreement is contained in the file
+ * Licence which accompanies this distribution.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+/*
+ * Copyright 1990 Open Software Foundation (OSF)
+ * Copyright 1990 Unix International (UI)
+ * Copyright 1990 X/Open Company Limited (X/Open)
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OSF, UI or X/Open not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OSF, UI and X/Open make
+ * no representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * OSF, UI and X/Open DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OSF, UI or X/Open BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dtcm.c 1.33 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)dtcm.c 1.33 98/09/01 TETware release 3.3
+NAME: 'C' Test Case Manager
+PRODUCT: TETware
+AUTHOR: Geoff Clare, UniSoft Ltd.
+DATE CREATED: 23 July 1990
+SYNOPSIS:
+
+ int tet_tcm_main(int argc, char **argv);
+ int tet_thistest;
+
+DESCRIPTION:
+
+ Tcm_main() is the main program for the Test Case Manager (TCM),
+ called from a different main() wrapper for each API.
+ The command line contains the invocable components (IC's) to be
+ executed. All test purposes in the user-supplied tet_testlist[]
+ array with an icref element corresponding to one of the requested
+ IC's are called, preceded by a call to the function pointed to
+ by tet_startup and followed by tet_cleanup (if each is not NULL).
+ The TCM reads configuration variables from the file specified
+ by the environment variable TET_CONFIG, provides handling of
+ unexpected signals on UNIX-like platforms, and reports the start
+ and end of IC's and the start of test purposes.
+
+ Tet_thistest is set to the test purpose number during execution
+ of each test purpose. Test purposes are numbered in the sequence
+ of the tet_testlist[] array (starting at 1) regardless of
+ execution sequence.
+
+MODIFICATIONS:
+
+ Geoff Clare, UniSoft Ltd, 6 Sept 1990
+ New results file format.
+ If no arguments assume all ICs.
+ Move tet_error() to resfile.c.
+ Change handling of ICs with zero TPs.
+
+ Geoff Clare, UniSoft Ltd, 28 Sept 1990
+ When doing all ICs start from lowest defined IC instead of 1.
+
+ Geoff Clare, UniSoft Ltd, 28 Nov 1990
+ Add tet_nosigreset.
+
+ Geoff Clare, UniSoft Ltd, 6 Sept 1991
+ Add call to tet_delreas().
+
+ DTET development - this file is based on release 1.10 of the TET
+ David G. Sawyer and John-Paul Leyland, UniSoft Ltd, June 1992
+
+ Andrew Dingwall, UniSoft Ltd., October 1992
+ Moved tet_root[] and setup to tcmfuncs.c so that tcmchild
+ processes can see it as well.
+
+ Updated Abort, Delete and results processing to work in a DTET
+ environment.
+
+ Geoff Clare, UniSoft Ltd, July-August 1996
+ Changes for TETWare.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for use with tetware tcc
+
+ Geoff Clare, UniSoft Ltd, Sept 1996
+ Added call to tet_init_blockable_sigs().
+ Changes for TETWare-Lite.
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ Use TET_THR_EQUAL() to compare thread IDs.
+ Restructured tcm source to avoid "ld -r".
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ Changes to support the defined interface between the TCM and
+ the test case.
+ Changed the sigsetjmp()/siglongjmp() code so that the signal number
+ is passed back in a global variable rather than by using the 2nd
+ argument to siglongjmp();
+ (apparently the only thing that can be done with the return value of
+ sigsetjmp() is to perform a comparison on it - for maximum portability
+ it should not be assigned to a variable).
+
+ Geoff Clare, UniSoft Ltd., July 1997
+ Changes to support NT threads.
+
+ Andrew Dingwall, UniSoft Ltd., January 1998
+ Permit the iclist to include IC 0.
+
+ Andrew Dingwall, UniSoft Ltd., February 1998
+ Use TETware-specific macros to access threads functions and
+ data items.
+ Handle an empty iclist correctly.
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+
+************************************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+# include <unistd.h>
+# include <setjmp.h>
+# include <signal.h>
+#include <string.h>
+#include <errno.h>
+#include "dtmac.h"
+#include "tet_api.h"
+#include "error.h"
+#include "dtmsg.h"
+#include "ltoa.h"
+#include "bstring.h"
+#include "dtthr.h"
+#include "alarm.h"
+#include "synreq.h"
+#include "tcmfuncs.h"
+#include "servlib.h"
+#include "dtetlib.h"
+#include "sigsafe.h"
+#include "apilib.h"
+
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define VERSION "3.3-lite"
+#else /* -START-LITE-CUT- */
+# define VERSION "3.3"
+#endif /* -END-LITE-CUT- */
+#define KILLWAIT 10
+
+
+/*
+** the IC list
+**
+** an entry appears in the IC list for each IC number or range of
+** IC numbers that are to be executed
+*/
+
+/* structure of an entry in the IC list */
+struct iclist {
+ int ic_start; /* low IC number in a range */
+ int ic_end; /* high IC number in a range */
+};
+
+/* the IC list itself */
+static struct iclist *iclist;
+static int liclist, niclist;
+
+
+static pid_t toppid;
+
+static int sigreset = 1;
+static int signum;
+static sigjmp_buf skipjmp;
+
+#ifdef TET_THREADS
+static int start_errno;
+static int start_child;
+static int start_alrm_flag;
+static long start_block;
+static long start_sequence;
+#endif /* TET_THREADS */
+
+
+/* static function declarations */
+static void build_icl2 PROTOLIST((char *, int, int));
+static void build_icl3 PROTOLIST((char *, int, int));
+static void build_iclist PROTOLIST((char **, int));
+static void call_1tp PROTOLIST((int, int, int));
+static int call_tps PROTOLIST((int, int));
+static struct iclist *iclalloc PROTOLIST((void));
+static int split PROTOLIST((char *, char **, int, int));
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+static void sync_report PROTOLIST((int, char *));
+#endif /* -END-LITE-CUT- */
+
+static void sigskip PROTOLIST((int));
+static void sigabandon PROTOLIST((int));
+static void sigterm PROTOLIST((void));
+static void setsigs PROTOLIST((void (*) PROTOLIST((int))));
+
+
+static char buf[256];
+
+/* ARGSUSED */
+int
+tet_tcm_main(argc, argv)
+int argc;
+char **argv;
+{
+ char *cp;
+ struct iclist *icp;
+ int iccount, tpcount, icnum, rc;
+#ifndef TET_LITE /* -START-LITE-CUT */
+ int nsys;
+#endif /* -END-LITE-CUT- */
+
+ tet_pname = argv[0]; /* used by tet_error() */
+
+ /* save current PID for checking when unexpected signals
+ cause a longjmp() to main test loop */
+ toppid = GETPID();
+
+#ifdef TET_THREADS
+ /* save initial thread ID for checking on unexpected signals */
+ tet_start_tid = TET_THR_SELF();
+
+ /* set up thread-specific data */
+ if (TET_THR_KEYCREATE(&tet_errno_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_child_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_alrm_flag_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_block_key) != 0 ||
+ TET_THR_KEYCREATE(&tet_sequence_key) != 0)
+ {
+ /* can't use tet_error() yet */
+ (void) fprintf(stderr,
+ "%s: TET_THR_KEYCREATE() failed in TCM startup",
+ tet_pname);
+ exit(EXIT_FAILURE);
+ }
+ TET_THR_SETSPECIFIC(tet_errno_key, (void *) &start_errno);
+ TET_THR_SETSPECIFIC(tet_child_key, (void *) &start_child);
+ TET_THR_SETSPECIFIC(tet_alrm_flag_key, (void *) &start_alrm_flag);
+ TET_THR_SETSPECIFIC(tet_block_key, (void *) &start_block);
+ TET_THR_SETSPECIFIC(tet_sequence_key, (void *) &start_sequence);
+
+ /* initialise all mutexes */
+ tet_mtx_init();
+#endif
+
+ /* blockable signals reported "unexpected" if caught (updated later) */
+ tet_init_blockable_sigs();
+
+ /* set tet_activity from environment */
+ cp = getenv("TET_ACTIVITY");
+ if (cp == NULL || *cp == '\0')
+ tet_activity = 0;
+ else
+ tet_activity = atol(cp);
+
+#ifdef TET_LITE
+ /* open execution results file (do early, so tet_error() can use it) */
+ tet_openres();
+#endif /* TET_LITE */
+
+ /* initialise the server and transport stuff */
+ tet_tcminit(argc, argv);
+
+ /* read in configuration variables */
+ tet_config();
+
+ /* set current context to process ID */
+ tet_setcontext();
+
+ /* build the list of ICs to be executed */
+ build_iclist(argv + 1, argc - 1);
+
+ /* count the number of ICs in the list */
+ iccount = 0;
+ for (icp = iclist; icp < iclist + niclist; icp++) {
+ TRACE3(tet_Ttcm, 8, "IC list element: start = %s, end = %s",
+ tet_i2a(icp->ic_start), tet_i2a(icp->ic_end));
+ for (icnum = icp->ic_start; icnum <= icp->ic_end; icnum++)
+ if (tet_isdefic(icnum))
+ iccount++;
+ }
+
+ /* count number of IC's to be executed and output on TCM Start line */
+ tet_tcmstart(VERSION, iccount);
+
+ /* unexpected signals are fatal during startup */
+ setsigs(sigabandon);
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ /* Do an auto sync -> use ic = -1, tp = 1 */
+ tet_init_synreq();
+ nsys = tet_Nsname;
+ if (tet_tcm_async(MK_ASPNO(-1, 1, S_ICSTART), SV_YES, SV_SYNC_TIMEOUT,
+ tet_synreq, &nsys) < 0) {
+ tet_error(tet_sderrno,
+ "startup function Auto Sync failed");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /* now, analyse the results of an unsuccessful auto sync */
+ if (tet_sderrno != ER_OK) {
+ sync_report(nsys, "startup");
+ tet_exit(EXIT_FAILURE);
+ }
+#endif /* -END-LITE-CUT- */
+
+ /* call user-supplied startup function */
+ if (tet_startup != NULL)
+ {
+ (*tet_startup)();
+#ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init();
+#endif
+ }
+
+ /* see whether tet_nosigreset was set in startup function */
+ if (tet_nosigreset)
+ sigreset = 0;
+
+ /* execute ICs specified on command line */
+ for (icp = iclist; icp < iclist + niclist; icp++)
+ for (icnum = icp->ic_start; icnum <= icp->ic_end; icnum++)
+ if (tet_isdefic(icnum)) {
+ tpcount = tet_gettpcount(icnum);
+ rc = tet_icstart(icnum, tpcount);
+ ASSERT_LITE(rc == 0);
+ if (rc < 0)
+ tet_docleanup(EXIT_FAILURE);
+ tpcount = call_tps(icnum, tpcount);
+ tet_icend(icnum, tpcount);
+ }
+
+ /* unexpected signals are fatal during cleanup */
+ setsigs(sigabandon);
+
+ /* call the user-supplied cleanup routine (if any) and exit */
+ tet_docleanup(EXIT_SUCCESS);
+
+ /* NOTREACHED */
+ return(EXIT_SUCCESS);
+}
+
+/*
+** call_tps() - call each test purpose function in the specified
+** invocable component
+**
+** return the number of TPs actually executed
+*/
+
+static int call_tps(icnum, tpcount)
+int icnum, tpcount;
+{
+ int testcount, testnum, tpnum;
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ long spno;
+#endif /* -END-LITE-CUT- */
+
+ TRACE3(tet_Ttcm, 6, "call_tps(): icnum = %s, tpcount = %s",
+ tet_i2a(icnum), tet_i2a(tpcount));
+
+ testcount = 0;
+ for (tpnum = 1; tpnum <= tpcount; tpnum++) {
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ spno = MK_ASPNO(0, tpnum, S_TPSTART);
+ if (EX_TPNO(spno) != tpnum) {
+ tet_error(0, "too many TPs defined in this IC");
+ break;
+ }
+#endif /* -END-LITE-CUT- */
+ testnum = tet_gettestnum(icnum, tpnum);
+ call_1tp(icnum, tpnum, testnum);
+ testcount++;
+ }
+
+ return(testcount);
+}
+
+/*
+** call_1tp() - call a single test purpose function
+*/
+
+static void call_1tp(icnum, tpnum, testnum)
+int icnum, tpnum, testnum;
+{
+ TRACE4(tet_Ttcm, 6, "call_1tp(): icnum = %s, tpnum = %s, testnum = %s",
+ tet_i2a(icnum), tet_i2a(tpnum), tet_i2a(testnum));
+
+ /* there is no signal handling in WIN32 */
+
+ /* establish the return point for an unexpected signal */
+ if (sigsetjmp(skipjmp, 1) != 0)
+ {
+ /* we've caught an unexpected signal! */
+ (void) sprintf(buf, "unexpected signal %d (%s) received",
+ signum, tet_signame(signum));
+ tet_infoline(buf);
+ tet_result(TET_UNRESOLVED);
+ if (tet_child > 0)
+ {
+ (void) tet_killw(tet_child, KILLWAIT);
+ tet_child = 0;
+ }
+# ifdef TET_THREADS
+ tet_cln_threads(signum);
+ tet_mtx_destroy();
+ tet_mtx_init();
+# endif /* TET_THREADS */
+
+ /* if this is not the top level process, don't fall
+ through to TCM test purpose loop! */
+ if (GETPID() != toppid)
+ exit(EXIT_FAILURE);
+
+ if (signum == SIGTERM)
+ sigterm();
+ }
+ else
+ {
+
+
+ /*
+ ** normal (non-signal) processing of a TP function
+ */
+
+ /* output test start message */
+ tet_tpstart(icnum, tpnum, testnum);
+
+ /* set global current test purpose indicator */
+ tet_thistest = testnum;
+
+ /* see if this TP has been deleted */
+ if (tet_reason(testnum) != NULL)
+ {
+ /* TP deleted in this TCM */
+ TRACE2(tet_Ttcm, 4, "TP %s deleted on this system",
+ tet_i2a(testnum));
+ tet_infoline(tet_reason(testnum));
+ tet_result(TET_UNINITIATED);
+ }
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ else if (tet_sync_del != 0)
+ {
+ /* TP deleted in another TCM */
+ TRACE2(tet_Ttcm, 4, "TP %s deleted on another system",
+ tet_i2a(testnum));
+ tet_result(TET_UNINITIATED);
+ tet_sync_del = 0;
+ }
+#endif /* -END-LITE-CUT- */
+ else
+ {
+
+ /* unexpected signals skip current test
+ NOTE: this is done before every test function
+ to ensure no "local" signal handlers are left
+ in place when skipping to the next test.
+ This safety feature can be disabled by setting
+ tet_nosigreset in the tet_startup function,
+ in which case unexpected signals in later
+ tests could go unnoticed. */
+ if (sigreset)
+ setsigs(sigskip);
+
+ /* call the user-supplied test function */
+ TRACE3(tet_Ttcm, 1,
+ "about to call tet_invoketp(%s, %s)",
+ tet_i2a(icnum), tet_i2a(tpnum));
+ (void) tet_invoketp(icnum, tpnum);
+#ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init();
+#endif
+ TRACE3(tet_Ttcm, 2, "tet_invoketp(%s, %s) RETURN",
+ tet_i2a(icnum), tet_i2a(tpnum));
+ }
+
+ }
+
+ /*
+ ** finally, output the test result -
+ ** if the action code for the result is ABORT, call the user-supplied
+ ** cleanup function and exit
+ */
+ if (tet_tpend(icnum, tpnum, testnum) < 0)
+ tet_docleanup(EXIT_FAILURE);
+}
+
+
+
+static void
+sigabandon(sig)
+int sig;
+{
+ static char mbuf[132];
+
+ if (sig == SIGTERM)
+ sigterm();
+
+# ifdef TET_THREADS
+ if (!TET_THR_EQUAL(TET_THR_SELF(), tet_start_tid))
+ {
+ (void) TET_THR_KILL(tet_start_tid, sig);
+ TET_THR_EXIT((void *)0);
+ }
+# endif /* TET_THREADS */
+
+ (void) sprintf(mbuf,
+ "Abandoning testset: caught unexpected signal %d (%s)",
+ sig, tet_signame(sig));
+ tet_error(0, mbuf);
+
+# ifdef TET_LITE /* -LITE-CUT-LINE- */
+ if (tet_tmpresfile != NULL)
+ (void) UNLINK(tet_tmpresfile);
+# endif /* -LITE-CUT-LINE- */
+
+ /* log off all the servers and exit */
+ tet_exit(EXIT_FAILURE);
+}
+
+static void
+sigterm()
+{
+ /* Cleanup and exit if SIGTERM received */
+
+ char *msg = "Abandoning test case: received signal SIGTERM";
+
+ /* terminate [per-thread] child, if any */
+ if (tet_child > 0)
+ {
+ (void) tet_killw(tet_child, KILLWAIT);
+ tet_child = 0;
+ }
+
+# ifdef TET_THREADS
+ if (!TET_THR_EQUAL(TET_THR_SELF(), tet_start_tid))
+ {
+ (void) TET_THR_KILL(tet_start_tid, SIGTERM);
+ TET_THR_EXIT((void *)0);
+ }
+
+ /* only main thread gets to here */
+ tet_cln_threads(SIGTERM);
+# endif /* TET_THREADS */
+
+ tet_error(0, msg);
+
+# ifdef TET_LITE /* -LITE-CUT-LINE- */
+ if (tet_tmpresfile != NULL)
+ (void) UNLINK(tet_tmpresfile);
+# endif /* TET_LITE */ /* -LITE-CUT-LINE- */
+
+ /* call user-supplied cleanup function */
+ if (tet_cleanup != NULL)
+ {
+ tet_thistest = 0;
+#ifndef TET_THREADS
+ tet_block = 0;
+#else
+ tet_next_block = 0;
+#endif
+ tet_setblock();
+
+ (*tet_cleanup)();
+# ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init(); /* needed by tet_exit() */
+# endif /* TET_THREADS */
+ }
+
+ /* log off all the servers and exit */
+ tet_exit(EXIT_FAILURE);
+}
+
+
+static void
+sigskip(sig)
+int sig;
+{
+ /*
+ * Catch unexpected signals and (in main thread) longjmp() to
+ * skipjmp where the setjmp() return value will be non-zero with
+ * the signal number in signum.
+ */
+
+# ifdef TET_THREADS
+ if (!TET_THR_EQUAL(TET_THR_SELF(), tet_start_tid))
+ {
+ (void) TET_THR_KILL(tet_start_tid, sig);
+ TET_THR_EXIT((void *)0);
+ }
+# endif /* TET_THREADS */
+
+ signum = sig;
+ siglongjmp(skipjmp, 1);
+}
+
+
+static void
+sig_init(var, set)
+char *var;
+sigset_t *set;
+{
+ /* initialise signal set from list in specified variable */
+
+ /* note that this routine uses strtok() which will alter the
+ contents of the list variable */
+
+ char *list, *sname;
+ int snum;
+
+ (void) sigemptyset(set);
+
+ list = tet_getvar(var);
+ if (list == NULL)
+ return;
+
+ for (sname = strtok(list, ", "); sname != NULL;
+ sname = strtok((char *) NULL, ", "))
+ {
+ snum = atoi(sname);
+
+ /* Check it's not a standard signal */
+ if (strncmp(tet_signame(snum), "SIG", (size_t)3) == 0)
+ {
+ (void) sprintf(buf,
+ "warning: illegal entry \"%s\" in %s ignored",
+ sname, var);
+ tet_error(0, buf);
+ }
+ else if (sigaddset(set, snum) == -1)
+ {
+ (void) sprintf(buf,
+ "warning: sigaddset() failed on entry \"%s\" in %s",
+ sname, var);
+ tet_error(0, buf);
+ }
+ }
+}
+
+
+static void
+setsigs(func)
+void (*func)();
+{
+ /*
+ * Sets all signals except SIGKILL, SIGSTOP and SIGCHLD
+ * to be caught by "func", except that signals specified in
+ * TET_SIG_IGN are ignored and signals specified in
+ * TET_SIG_LEAVE are left alone.
+ */
+
+ int i;
+ struct sigaction sig;
+ static sigset_t sig_ign;
+ static sigset_t sig_leave;
+ static int init_done = 0;
+
+ if (!init_done)
+ {
+ sig_init("TET_SIG_IGN", &sig_ign);
+ sig_init("TET_SIG_LEAVE", &sig_leave);
+ init_done = 1;
+ }
+
+ (void) sigemptyset(&tet_blockable_sigs);
+
+ /* NSIG is not provided by POSIX.1: it must be defined via
+ an extra feature-test macro, or on the compiler command line */
+ for (i = 1; i < NSIG; i++)
+ {
+ if (i == SIGKILL || i == SIGSTOP || i == SIGCHLD
+ || sigismember(&sig_leave, i))
+ continue;
+
+ if (sigismember(&sig_ign, i))
+ sig.sa_handler = SIG_IGN;
+ else
+ sig.sa_handler = func;
+ sig.sa_flags = 0;
+ (void) sigemptyset(&sig.sa_mask);
+ if (sigaction(i, &sig, (struct sigaction *)NULL) == 0 &&
+# ifdef SIGBUS
+ i != SIGBUS &&
+# endif
+ i != SIGSEGV && i != SIGILL && i != SIGFPE)
+ (void) sigaddset(&tet_blockable_sigs, i);
+ }
+}
+
+
+
+/*
+** tet_docleanup() - call the user-supplied cleanup function (if any)
+** and exit
+*/
+
+void tet_docleanup(status)
+int status;
+{
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ int nsys;
+
+ /* Do an auto sync -> use ic = tet_iclast + 1, tp = 1 */
+ ASSERT(tet_synreq);
+ nsys = tet_Nsname;
+ if (tet_tcm_async(MK_ASPNO(tet_iclast + 1, 1, S_TPSTART), SV_YES,
+ SV_SYNC_TIMEOUT, tet_synreq, &nsys) < 0) {
+ tet_error(tet_sderrno,
+ "cleanup function Auto Sync failed");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /* analyse the results of an unsuccessful auto sync */
+ if (tet_sderrno != ER_OK) {
+ sync_report(nsys, "cleanup");
+ tet_exit(EXIT_FAILURE);
+ }
+#endif /* -END-LITE-CUT- */
+
+ /* call user-supplied cleanup function */
+ if (tet_cleanup != NULL)
+ {
+ tet_thistest = 0;
+#ifndef TET_THREADS
+ tet_block = 0;
+#else
+ tet_next_block = 0;
+#endif
+ tet_setblock();
+
+ (*tet_cleanup)();
+
+#ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init();
+#endif
+ }
+
+ tet_exit(status);
+}
+
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+/*
+** sync_report() - analyse the results of the startup and cleanup
+** tet_tcm_async() calls
+*/
+
+static void sync_report(nsys, functype)
+register int nsys;
+char *functype;
+{
+ register struct synreq *sp;
+ char errmsg[128];
+
+ for (sp = tet_synreq; sp < tet_synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ break;
+ default:
+ (void) sprintf(errmsg,
+ "%s function Auto Sync error, sysid = %d, state = %s",
+ functype, sp->sy_sysid,
+ tet_systate(sp->sy_state));
+ tet_error(tet_sderrno, errmsg);
+ break;
+ }
+}
+
+#endif /* -END-LITE-CUT- */
+
+/*
+** build_iclist() - build the list of ICs to be executed
+**
+** the IC specifications are taken from TCM command line;
+** each specification can contain one or more comma-separated elements;
+** each element can be an IC number (n), a range of IC numbers (m-n),
+** or the word "all"
+**
+** when an element consists of a range of IC numbers (m-n),
+** a missing m means the lowest numbered IC defined in the test case
+** and a missing n means the highest numbered IC defined in the
+** test case
+**
+** when the word "all" appears and is not the first element, it means
+** all of the ICs beyond the highest IC specified in the previous element
+*/
+
+static void build_iclist(icspec, nicspec)
+char **icspec;
+int nicspec;
+{
+ static char fmt[] = "tet_get%sic() returns %d but tet_isdefic(%d) returns FALSE!";
+ char msg[sizeof fmt + (LNUMSZ * 2)];
+ int icmin, icmax;
+ int err;
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ long spno;
+#endif /* -END-LITE-CUT- */
+
+ /* determin the lowest and highest IC defined in this test case */
+ icmin = tet_getminic();
+ icmax = tet_getmaxic();
+ TRACE3(tet_Ttcm, 8, "build_iclist(): icmin = %s, icmax = %s",
+ tet_i2a(icmin), tet_i2a(icmax));
+
+ /* return now if the iclist is empty */
+ if (icmin <= 0 && icmax == icmin && !tet_isdefic(icmin))
+ return;
+
+ /*
+ ** ensure that tet_isdefic() says that icmin and icmax have been
+ ** defined!
+ */
+ err = 0;
+ if (!tet_isdefic(icmin)) {
+ (void) sprintf(msg, fmt, "min", icmin, icmin);
+ tet_error(0, msg);
+ err = 1;
+ }
+ if (!tet_isdefic(icmax)) {
+ (void) sprintf(msg, fmt, "max", icmax, icmax);
+ tet_error(0, msg);
+ icmax = 1;
+ err = 1;
+ }
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ /* ensure that the largest IC is within bounds */
+ tet_iclast = icmax;
+ spno = MK_ASPNO(tet_iclast + 1, 0, S_ICSTART);
+ if (spno < 0L || EX_ICNO(spno) != tet_iclast + 1) {
+ tet_error(0, "the largest IC number defined in this test case is too big");
+ err = 1;
+ }
+#endif /* -END-LITE-CUT- */
+
+ if (err)
+ tet_exit(EXIT_FAILURE);
+
+ /*
+ ** if we have one or more IC specifications, use them to build the
+ ** IC list; otherwise, build the list from all the ICs defined
+ ** in this test case
+ */
+ if (nicspec > 0)
+ while (nicspec-- > 0)
+ build_icl2(*icspec++, icmin, icmax);
+ else
+ build_icl3("all", icmin, icmax);
+}
+
+/*
+** build_icl2() - extend the build_iclist() processing for
+** a group of elements in a single specification
+*/
+
+static void build_icl2(icspec, icmin, icmax)
+char *icspec;
+int icmin, icmax;
+{
+ char buf[(LNUMSZ * 2) + 2];
+ register char *p;
+
+ TRACE2(tet_Ttcm, 8, "build_icl2(): icspec = \"%s\"", icspec);
+
+ /* process each comma-separated element in turn */
+ while (*icspec) {
+ for (p = icspec; *p; p++)
+ if (*p == ',')
+ break;
+ (void) sprintf(buf, "%.*s",
+ TET_MIN((int) (p - icspec), (int) sizeof buf - 1),
+ icspec);
+ build_icl3(buf, icmin, icmax);
+ icspec = p;
+ if (*icspec)
+ icspec++;
+ }
+}
+
+/*
+** build_icl3() - extend the build_iclist() processing some more
+**
+** process an individual IC number or number range
+*/
+
+static void build_icl3(icspec, icmin, icmax)
+char *icspec;
+int icmin, icmax;
+{
+ static int last_icend = -1;
+ int icstart, icend;
+ struct iclist *icp;
+ char *flds[2];
+ static char fmt[] = "IC %d is not defined for this test case";
+ char msg[sizeof fmt + LNUMSZ];
+
+ TRACE2(tet_Ttcm, 8, "build_icl3(): icspec = \"%s\"", icspec);
+
+ /*
+ ** if the element is "all" and ICs exist beyond the highest IC
+ ** in the last element, add the rest of the ICs to the list
+ ** and return
+ */
+ if (!strcmp(icspec, "all")) {
+ if (last_icend == -1 || last_icend < icmax) {
+ icp = iclalloc();
+ icstart = TET_MAX(icmin, last_icend + 1);
+ icend = icmax;
+ if (last_icend >= 0)
+ while (icstart < icend && !tet_isdefic(icstart))
+ icstart++;
+ icp->ic_start = icstart;
+ icp->ic_end = icend;
+ last_icend = icp->ic_end;
+ }
+ return;
+ }
+
+ /*
+ ** here if the element is a number or a number range
+ **
+ ** split the element into '-' separated fields and extract the
+ ** number from each one
+ */
+ switch (split(icspec, flds, (int) (sizeof flds / sizeof flds[0]), '-')) {
+ case 1:
+ icend = icstart = atoi(flds[0]);
+ break;
+ case 2:
+ icstart = *flds[0] ? atoi(flds[0]) : icmin;
+ icend = *flds[1] ? atoi(flds[1]) : icmax;
+ break;
+ default:
+ return;
+ }
+
+ /*
+ ** find the lowest defined IC that is greater than or equal to
+ ** the specified start IC
+ **
+ ** print a diagnostic if the specified start IC does not exist
+ */
+ if (!tet_isdefic(icstart)) {
+ (void) sprintf(msg, fmt, icstart);
+ tet_error(0, msg);
+ while (++icstart <= icend)
+ if (tet_isdefic(icstart))
+ break;
+ }
+
+ /*
+ ** return now if no ICs within the specified range have been defined
+ ** in the test case
+ */
+ if (icstart > icend)
+ return;
+
+ /*
+ ** here, the IC referenced by the (possibly modified) icstart
+ ** is known to be defined
+ **
+ ** find the highest defined IC that is less than or equal to
+ ** the specified end IC
+ **
+ ** print a diagnostic if the specified end IC does not exist
+ */
+ if (icstart != icend && !tet_isdefic(icend)) {
+ (void) sprintf(msg, fmt, icend);
+ tet_error(0, msg);
+ while (--icend > icstart)
+ if (tet_isdefic(icend))
+ break;
+ }
+
+ /*
+ ** here we have a known good start and end IC
+ ** (which might be the same)
+ **
+ ** add the IC range to the list and return
+ */
+ icp = iclalloc();
+ icp->ic_start = icstart;
+ icp->ic_end = icend;
+ last_icend = icp->ic_end;
+}
+
+/*
+** iclalloc() - allocate an IC list element and return a pointer thereto
+*/
+
+static struct iclist *iclalloc()
+{
+ register struct iclist *icp;
+
+ if (BUFCHK((char **) &iclist, &liclist, (niclist + 1) * sizeof *iclist) < 0)
+ tet_exit(EXIT_FAILURE);
+
+ icp = iclist + niclist++;
+ bzero((char *) icp, sizeof *icp);
+ return(icp);
+}
+
+/*
+** split() - split a string up into at most maxargs fields,
+** discarding excess fields
+**
+** return the number of fields found
+*/
+
+static int split(s, argv, maxargs, delim)
+register char *s, **argv;
+register int maxargs, delim;
+{
+ register char **ap = argv;
+
+ if (!*s || maxargs <= 0)
+ return(0);
+
+ *ap++ = s;
+ while (*s) {
+ if (*s == (char) delim) {
+ *s++ = '\0';
+ if (ap < argv + maxargs)
+ *ap++ = s;
+ else
+ break;
+ }
+ else
+ s++;
+ }
+
+ return(ap - argv);
+}
+
diff --git a/src/tet3/tcm/dynlink.c b/src/tet3/tcm/dynlink.c
new file mode 100644
index 00000000..67ba580b
--- /dev/null
+++ b/src/tet3/tcm/dynlink.c
@@ -0,0 +1,67 @@
+/*
+ * SCCS: @(#)dynlink.c 1.1 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * Copyright (c) 1998 The Open Group
+ * All rights reserved.
+ *
+ * No part of this source code may be reproduced, stored in a retrieval
+ * system, or transmitted, in any form or by any means, electronic,
+ * mechanical, photocopying, recording or otherwise, except as stated
+ * in the end-user licence agreement, without the prior permission of
+ * the copyright owners.
+ * A copy of the end-user licence agreement is contained in the file
+ * Licence which accompanies this distribution.
+ *
+ * Motif, OSF/1, UNIX and the "X" device are registered trademarks and
+ * IT DialTone and The Open Group are trademarks of The Open Group in
+ * the US and other countries.
+ *
+ * X/Open is a trademark of X/Open Company Limited in the UK and other
+ * countries.
+ *
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)dynlink.c 1.1 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)dynlink.c 1.1 98/09/01 TETware release 3.3
+NAME: dynlink.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: July 1998
+
+DESCRIPTION:
+ this is a simple dynamic linker for use when building a test case
+ to use a shared API library on a Win32 system
+
+ the dynamic linker is in two parts:
+
+ tet_w32dynlink() resides in the main program
+ tet_w32dlcheck() resides in the shared API library
+
+ tet_w32dynlink() performs the dynamic linking
+ tet_w32dlcheck() ensures that none of the pointers have been missed
+
+ see the comment in dtmac.h for an overview of how this works
+
+
+ no calls to TETware library functions are allowed from this file
+
+MODIFICATIONS:
+
+************************************************************************/
+
+/* TET_SHLIB_SOURCE implies TET_SHLIB */
+#if defined(TET_SHLIB_SOURCE) && !defined(TET_SHLIB)
+# define TET_SHLIB
+#endif
+
+
+int tet_dynlink_c_not_used;
+
+
diff --git a/src/tet3/tcm/ictp.c b/src/tet3/tcm/ictp.c
new file mode 100644
index 00000000..5b77514c
--- /dev/null
+++ b/src/tet3/tcm/ictp.c
@@ -0,0 +1,888 @@
+/*
+ * SCCS: @(#)ictp.c 1.22 (98/09/22)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1996 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ * A copy of the end-user licence agreement is contained in the file
+ * Licence which accompanies this distribution.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+/*
+ * Copyright 1990 Open Software Foundation (OSF)
+ * Copyright 1990 Unix International (UI)
+ * Copyright 1990 X/Open Company Limited (X/Open)
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of OSF, UI or X/Open not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission. OSF, UI and X/Open make
+ * no representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ *
+ * OSF, UI and X/Open DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL OSF, UI or X/Open BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
+ * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)ictp.c 1.22 (98/09/22) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)ictp.c 1.22 98/09/22 TETware release 3.3
+NAME: ictp.c
+PRODUCT: TETware
+AUTHOR: Geoff Clare, UniSoft Ltd.
+DATE CREATED: 25 July 1990
+DESCRIPTION:
+
+ tet_icstart(), tet_icend(), tet_tpstart() and
+ tet_tpend() are used by the TCM to output TCM start lines, IC
+ start and end lines and test purpose start and result lines to
+ the combined execution results file maintained by XRESD
+
+MODIFICATIONS:
+
+ June 1992
+ DTET development - apilib/dresfile.c is derived from
+ TET release 1.10
+
+ Andrew Dingwall, UniSoft Ltd,. October 1992
+ Some non-API functions specific to parent TCMs moved from
+ apilib/dresfile.c to here.
+
+ All vestages of the local execution results file and temporary
+ execution results file removed - in the DTET, all the processing
+ associated with these files is done by XRESD.
+
+ All these functions completely re-written - auto-syncs are used
+ to pass deletion and Abort information between TCMs as follows:
+
+ if a TP is deleted within a TCM, that TCM votes NO at the
+ TP start sync point
+ if a TCM receives a NO sync vote at TP start, it knows that
+ the TP has been deleted in another TCM
+
+ if a result code action is Abort, XRESD returns ER_ABORT
+ when the MTCM calls tet_xdtpend() from tet_tpend();
+ the MTCM syncs with a NO vote to the end of the last TP
+
+ STCMs will receive this NO vote at the start of any remaining
+ TPs in the current IC, thus causing them to believe that
+ these TPs have been deleted in the MTCM
+
+ when STCMs receive the NO vote at the start of the next IC,
+ they will interpret it as the signal to perform Abort
+ processing
+
+ Andrew Dingwall, UniSoft Ltd., November 1992
+ Increased tpend sync timeout to 10 mins so as to allow for
+ larger inbalance between test part execution times.
+
+ Denis McConalogue, UniSoft Limited, June 1993
+ API enhancements - moved all functions from [ms]tcmdist.c
+ to here. Added tet_ismaster().
+
+ Denis McConalogue, UniSoft Limited, September 1993
+ do not open tet_combined in tet_opencom() if an tet_xrid is
+ already initialised.
+
+ Andrew Dingwall, UniSoft Ltd., November 1994
+ signal IC end from MTCM when result code action is Abort
+
+ Geoff Clare, UniSoft Ltd., August 1996
+ Changes for TETWare.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for use with tetware tcc
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ Changes for TETWare-Lite.
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ changes to support the defined test case interface
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+# include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <errno.h>
+#include <time.h>
+#include "dtmac.h"
+#include "error.h"
+#include "globals.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "ltoa.h"
+#include "synreq.h"
+#include "servlib.h"
+#include "dtetlib.h"
+#include "tcmfuncs.h"
+#include "tet_api.h"
+#include "tet_jrnl.h"
+#include "apilib.h"
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+#define MODE666 (mode_t) (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+ char *tet_tmpresfile;
+ static char *tmpresenv;
+ static char *resenv, *resfile;
+#else /* -START-LITE-CUT- */
+ TET_IMPORT int tet_iclast = ~(~0 << S_ICBITS) - 2;
+ /* used in auto sync before cleanup */
+ TET_IMPORT int tet_sync_del = 0; /* true when a TP is deleted in a
+ test case part on another system */
+ TET_IMPORT struct synreq *tet_synreq = (struct synreq *) 0;
+ /* used when analysing the results
+ of an auto-sync */
+#endif /* -END-LITE-CUT- */
+
+
+/* static function declarations */
+static void icend2 PROTOLIST((int, int));
+static int icstart2 PROTOLIST((int, int));
+static int tpend2 PROTOLIST((int, int, int));
+static void tpstart2 PROTOLIST((int, int, int));
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+ static char *curtime PROTOLIST((void));
+ static void lite_output PROTOLIST((int, char *, char *));
+#else /* -START-LITE-CUT- */
+ static int ismaster PROTOLIST((void));
+ static int mtcm_tpend2 PROTOLIST((void));
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_icstart() - signal IC start
+**
+** return 0 if successful or -1 to abort the test case
+**
+** in Distributed TETware, if the previous result code action was Abort,
+** this function is only executed by STCMs
+*/
+
+TET_IMPORT int tet_icstart(icno, tpcount)
+int icno, tpcount;
+{
+ int rc;
+
+ TRACE3(tet_Ttcm, 7, "tet_icstart(): icno = %s, tpcount = %s",
+ tet_i2a(icno), tet_i2a(tpcount));
+
+ rc = icstart2(icno, tpcount);
+
+ TRACE2(tet_Ttcm, 7, "tet_icstart() RETURN %s", tet_i2a(rc));
+ return(rc);
+}
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+static int icstart2(icno, tpcount)
+int icno, tpcount;
+{
+ char buf[128];
+
+ (void) sprintf(buf, "%d %d %s", icno, tpcount, curtime());
+ lite_output(TET_JNL_IC_START, buf, "IC Start");
+ return(0);
+}
+
+#else /* -START-LITE-CUT- */
+
+static int icstart2(icno, tpcount)
+int icno, tpcount;
+{
+ register struct synreq *sp;
+ int nsys = tet_Nsname;
+ int errflag;
+ char errmsg[128];
+
+ /* the MTCM informs XRESD of IC start */
+ if (
+ ismaster() &&
+ tet_xdicstart(tet_xrid, icno, tet_activity, tpcount) < 0
+ ) {
+ tet_error(tet_xderrno, "can't inform XRESD of IC start");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /*
+ ** then all TCMs sync on IC start -
+ ** if the MTCM votes NO, this means that the previous result
+ ** code action was Abort
+ */
+ ASSERT(tet_synreq);
+ if (tet_tcm_async(MK_ASPNO(icno, 0, S_ICSTART), SV_YES, SV_SYNC_TIMEOUT,
+ tet_synreq, &nsys) < 0) {
+ (void) sprintf(errmsg,
+ "Auto Sync failed at start of IC %d", icno);
+ tet_error(tet_sderrno, errmsg);
+ tet_exit(EXIT_FAILURE);
+ }
+
+ if (tet_sderrno == ER_OK)
+ return(0);
+
+ /*
+ ** here if the auto sync failed in an expected way -
+ ** a NO vote from the MTCM means that the test is to be aborted
+ */
+ errflag = 0;
+ for (sp = tet_synreq; sp < tet_synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ break;
+ case SS_SYNCNO:
+ if (sp->sy_sysid == 0)
+ break;
+ /* else fall through */
+ default:
+ (void) sprintf(errmsg,
+ "Auto sync error at start of IC %d, sysid = %d, state = %s",
+ icno, sp->sy_sysid, tet_systate(sp->sy_state));
+ tet_error(tet_sderrno, errmsg);
+ errflag = 1;
+ break;
+ }
+
+
+ if (errflag)
+ tet_exit(EXIT_FAILURE);
+
+ /* here if MTCM voted NO - return -1 to force a cleanup and exit */
+ return(-1);
+}
+
+#endif /* -END-LITE-CUT- */
+
+/*
+** tet_icend() - signal IC end
+*/
+
+TET_IMPORT void tet_icend(icno, tpcount)
+int icno, tpcount;
+{
+
+ TRACE3(tet_Ttcm, 7, "tet_icend(): icno = %s, tpcount = %s",
+ tet_i2a(icno), tet_i2a(tpcount));
+
+ icend2(icno, tpcount);
+
+ TRACE1(tet_Ttcm, 7, "tet_icend() RETURN");
+}
+
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+static void icend2(icno, tpcount)
+int icno, tpcount;
+{
+ char buf[128];
+
+ (void) sprintf(buf, "%d %d %s", icno, tpcount, curtime());
+ lite_output(TET_JNL_IC_END, buf, "IC End");
+}
+
+#else /* -START-LITE-CUT- */
+
+/* ARGSUSED */
+static void icend2(icno, tpcount)
+{
+ /* the MTCM informs XRESD of IC end */
+ if (ismaster() && tet_xdicend(tet_xrid) < 0) {
+ tet_error(tet_xderrno, "can't inform XRESD of IC end");
+ tet_exit(EXIT_FAILURE);
+ }
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_tpstart() - signal TP start
+*/
+
+TET_IMPORT void tet_tpstart(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+
+ TRACE4(tet_Ttcm, 7, "tet_tpstart(): icno = %s, tpno = %s, testnum = %s",
+ tet_i2a(icno), tet_i2a(tpno), tet_i2a(testnum));
+
+#ifdef TET_THREADS
+ tet_next_block = 1;
+#endif
+ tet_block = 1;
+ tet_sequence = 1;
+
+ tpstart2(icno, tpno, testnum);
+
+ TRACE1(tet_Ttcm, 7, "tet_tpstart() RETURN");
+}
+
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+static void tpstart2(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+ char buf[128];
+
+ (void) sprintf(buf, "%d %s", testnum, curtime());
+ lite_output(TET_JNL_TP_START, buf, "TP Start");
+
+ /* create temporary result file */
+ (void) remove(tet_tmpresfile);
+ if ((tet_tmpresfp = fopen(tet_tmpresfile, "a+b")) == (FILE *) 0)
+ fatal(errno, "cannot create temporary result file:",
+ tet_tmpresfile);
+
+ /* override umask (must be writable by set-uid children) */
+ (void) CHMOD(tet_tmpresfile, MODE666);
+
+ /*
+ ** put pathname in environment to be picked up by tet_result() in
+ ** exec'ed programs
+ */
+ ASSERT(tmpresenv);
+ if (tet_putenv(tmpresenv) != 0)
+ tet_error(0, "tet_putenv() failed setting TET_TMPRESFILE");
+}
+
+#else /* -START-LITE-CUT- */
+
+static void tpstart2(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+ register struct synreq *sp;
+ register int vote;
+ int nsys = tet_Nsname;
+ int errflag;
+ char errmsg[128];
+
+ /* the MTCM informs XRESD of TP start */
+ if (ismaster() && tet_xdtpstart(tet_xrid, testnum) < 0) {
+ tet_error(tet_xderrno, "can't inform XRESD of TP start");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /*
+ ** see if the TP has been deleted in this TCM and set our vote
+ ** accordingly
+ */
+ vote = tet_reason(testnum) ? SV_NO : SV_YES;
+
+ /* then all the TCMs sync on TP start */
+ ASSERT(tet_synreq);
+ if (tet_tcm_async(MK_ASPNO(icno, tpno, S_TPSTART), vote,
+ SV_SYNC_TIMEOUT, tet_synreq, &nsys) < 0) {
+ (void) sprintf(errmsg,
+ "Auto Sync failed at start of TP %d", testnum);
+ tet_error(tet_sderrno, errmsg);
+ tet_exit(EXIT_FAILURE);
+ }
+
+ if (tet_sderrno == ER_OK)
+ return;
+
+ /*
+ ** here if sync failed in an expected way -
+ ** a NO vote means that the TP has been deleted in another TCM
+ */
+ errflag = 0;
+ for (sp = tet_synreq; sp < tet_synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ break;
+ case SS_SYNCNO:
+ tet_sync_del = 1;
+ break;
+ default:
+ (void) sprintf(errmsg,
+ "Auto Sync error at start of TP %d, sysid = %d, state = %s",
+ testnum, sp->sy_sysid,
+ tet_systate(sp->sy_state));
+ tet_error(tet_sderrno, errmsg);
+ errflag = 1;
+ break;
+ }
+
+ if (errflag)
+ tet_exit(EXIT_FAILURE);
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_tpend() - signal TP end
+**
+** return 0 if successful or -1 to abort the test case
+*/
+
+TET_IMPORT int tet_tpend(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+ int rc;
+
+ TRACE4(tet_Ttcm, 7, "tet_tpend(): icno = %s, tpno = %s, testnum = %s",
+ tet_i2a(icno), tet_i2a(tpno), tet_i2a(testnum));
+
+ rc = tpend2(icno, tpno, testnum);
+
+ TRACE2(tet_Ttcm, 7, "tet_tpend(): RETURN %s", tet_i2a(rc));
+ return(rc);
+}
+
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+static int tpend2(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+ char *res;
+ int have_result, nextres, err;
+ int result = TET_NORESULT;
+ int abrt = 0;
+ char buf[128];
+
+ /*
+ * output a "TP Result" line to the execution results file,
+ * based on the result code(s) written to a temporary result
+ * file by tet_result()
+ */
+
+ /* rewind temporary result file */
+ if (fseek(tet_tmpresfp, 0L, SEEK_SET) != 0)
+ {
+ tet_error(errno, "failed to rewind temporary result file");
+
+ /* fall through: no results will be read */
+ }
+
+ /*
+ ** read result code(s) from temporary file - if more than one
+ ** has been written, choose the one with the highest priority
+ */
+
+ have_result = 0;
+ while (fread((void *)&nextres, sizeof(nextres), (size_t) 1, tet_tmpresfp) == 1)
+ {
+ /* if it's the first result, take it (for now) */
+ if (!have_result)
+ {
+ result = nextres;
+ have_result = 1;
+ continue;
+ }
+
+ /* decide if this result supersedes any previous ones */
+
+ result = tet_addresult(result, nextres);
+ }
+ err = errno;
+
+ if (ferror(tet_tmpresfp))
+ {
+ tet_error(err, "read error on temporary results file");
+ have_result = 0;
+ }
+
+ (void) fclose(tet_tmpresfp);
+ (void) UNLINK(tet_tmpresfile);
+ (void) tet_putenv("TET_TMPRESFILE=");
+
+ if (!have_result)
+ {
+ result = TET_NORESULT;
+ res = "NORESULT";
+ }
+ else
+ {
+ res = tet_get_code(result, &abrt);
+ if (res == NULL)
+ {
+ /*
+ ** This should never happen, as the codes have
+ ** already been validated by tet_result().
+ ** It is not a serious problem - the name is only
+ ** there to make the results file more readable
+ */
+ res = "(NO RESULT NAME)";
+ }
+ }
+
+ (void) sprintf(buf, "%d %d %s", testnum, result, curtime());
+ lite_output(TET_JNL_TP_RESULT, buf, res);
+
+ /*
+ ** Abort is done here rather than in tet_result() since the
+ ** latter may have been called in a child.
+ ** Test purposes should not assume that tet_result() will not return
+ ** when called with an abort code.
+ */
+ if (abrt)
+ {
+# ifdef TET_THREADS
+ tet_cln_threads(0);
+ tet_mtx_destroy();
+ tet_mtx_init();
+# endif
+ (void) sprintf(buf, "ABORT on result code %d \"%s\"",
+ result, res);
+ lite_output(TET_JNL_TCM_INFO, "", buf);
+ return(-1);
+ }
+
+ return(0);
+}
+
+#else /* -START-LITE-CUT- */
+
+static int tpend2(icno, tpno, testnum)
+int icno, tpno, testnum;
+{
+ register struct synreq *sp;
+ int err;
+ int nsys = tet_Nsname;
+ char errmsg[128];
+
+ /*
+ ** all the TCMs sync YES on TP end -
+ ** there is an assumption here that the parts of a TP will
+ ** arrive at their ends within 10 minutes of each other;
+ ** if this is not so for a particular test, the test writer
+ ** is expected to use tet_sync() with a longer timeout
+ ** to delay the ends of the quicker test parts
+ */
+ ASSERT(tet_synreq);
+ if (tet_tcm_async(MK_ASPNO(icno, tpno, S_TPEND), SV_YES,
+ SV_SYNC_TIMEOUT * 10, tet_synreq, &nsys) < 0) {
+ (void) sprintf(errmsg,
+ "Auto Sync failed at end of TP %d", testnum);
+ tet_error(tet_sderrno, errmsg);
+ tet_exit(EXIT_FAILURE);
+ }
+ err = tet_sderrno;
+
+ /*
+ ** then the MTCM informs XRESD of TP end -
+ ** if XRESD returns ER_ABORT when tet_xdtpend() is called, this
+ ** function does not return in the MTCM
+ */
+ if (ismaster() && mtcm_tpend2() < 0)
+ return(-1);
+
+ if (err == ER_OK)
+ return(0);
+
+ /* here if a TCM voted NO ("can't happen"), timed out or died */
+ for (sp = tet_synreq; sp < tet_synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ break;
+ default:
+ (void) sprintf(errmsg,
+ "Auto Sync error at end of TP %d, sysid = %d, state = %s",
+ testnum, sp->sy_sysid,
+ tet_systate(sp->sy_state));
+ tet_error(err, errmsg);
+ break;
+ }
+
+ tet_exit(EXIT_FAILURE);
+
+ /* NOTREACHED */
+ return(-1);
+}
+
+/*
+** mtcm_tpend2() - inform XRESD of TP end from MTCM
+**
+** return 0 if successful or -1 if XRESD indicates that the testcase
+** must be aborted
+*/
+
+static int mtcm_tpend2()
+{
+ char errmsg[128];
+ struct synreq *synreq;
+ int nsys, errflag;
+ register struct synreq *sp;
+
+ /* signal TP end to XRESD */
+ (void) tet_xdtpend(tet_xrid);
+ switch (tet_xderrno) {
+ case ER_OK:
+ return(0);
+ case ER_ABORT:
+ /* XRESD prints the "ABORT on result code" message */
+ break;
+ default:
+ tet_error(tet_xderrno, "can't inform XRESD of TP end");
+ tet_exit(EXIT_FAILURE);
+ /* NOTREACHED */
+ }
+
+ /*
+ ** here if previous TP result code action was Abort -
+ ** allocate memory for synreq array; don't worry if it fails
+ */
+ errno = 0;
+ if ((synreq = (struct synreq *) malloc((size_t)(sizeof *synreq * tet_Nsname))) == (struct synreq *) 0) {
+ tet_error(errno, " can't allocate synreq array for Abort sync");
+ nsys = 0;
+ }
+ else
+ nsys = tet_Nsname;
+
+ /* signal IC end to XRESD */
+ if (tet_xdicend(tet_xrid) < 0)
+ tet_error(tet_xderrno, "ABORT: can't inform XRESD of IC end");
+
+ /*
+ ** sync NO to the end of the last IC -
+ ** this communicates the Abort action to other TCMs
+ */
+ if (tet_tcm_async(MK_ASPNO(tet_iclast, ~0, S_ICEND), SV_NO,
+ SV_SYNC_TIMEOUT, synreq, &nsys) < 0) {
+ tet_error(tet_sderrno, "Abort Auto Sync failed");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /* make sure that the other TCMs are still alive */
+ if (synreq) {
+ errflag = 0;
+ for (sp = synreq; sp < synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ case SS_SYNCNO:
+ break;
+ default:
+ (void) sprintf(errmsg,
+ "Abort Auto Sync error, sysid = %d, state = %s",
+ sp->sy_sysid,
+ tet_systate(sp->sy_state));
+ tet_error(tet_sderrno, errmsg);
+ errflag = 1;
+ break;
+ }
+ if (errflag)
+ tet_exit(EXIT_FAILURE);
+ }
+
+ /* here if we should attempt to call (*tet_cleanup)() */
+ return(-1);
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_tcmstart() - send TCM Start journal line to XRESD
+*/
+
+void tet_tcmstart(versn, no_ics)
+char *versn;
+int no_ics;
+{
+ char buf[128];
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+ (void) sprintf(buf, "%s %d", versn, no_ics);
+ lite_output(TET_JNL_TCM_START, buf, "TCM Start");
+
+#else /* -START-LITE-CUT- */
+
+ if (!ismaster())
+ return;
+
+ (void) sprintf(buf, "%d|%ld %s %d|TCM Start",
+ TET_JNL_TCM_START, tet_activity, versn, no_ics);
+
+ if (tet_xdxres(tet_xrid, buf) < 0) {
+ tet_error(tet_xderrno,
+ "can't send \"TCM Start\" journal line to XRESD");
+ tet_exit(EXIT_FAILURE);
+ }
+
+#endif /* -END-LITE-CUT- */
+
+}
+
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+/*
+** tet_init_synreq() - allocate memory for the tet_synreq array
+*/
+
+TET_IMPORT void tet_init_synreq()
+{
+ if (tet_synreq != (struct synreq *) 0)
+ return;
+
+ errno = 0;
+ if ((tet_synreq = (struct synreq *) malloc(sizeof *tet_synreq * tet_Nsname)) == (struct synreq *) 0) {
+ tet_error(errno, "can't allocate memory for tet_synreq array");
+ tet_exit(EXIT_FAILURE);
+ }
+
+ TRACE2(tet_Tbuf, 6, "allocate tet_synreq = %s", tet_i2x(tet_synreq));
+}
+
+/*
+** ismaster() - return true if we are running on the master
+** system.
+*/
+
+static int ismaster()
+{
+ if (tet_myptype == PT_MTCM)
+ return (1);
+ else if (tet_myptype == PT_STCM)
+ return (0);
+ else {
+ tet_error(0, "Can't determine system type");
+ tet_exit(EXIT_FAILURE);
+ /* NOTREACHED */
+ return(0);
+ }
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+
+/*
+** tet_openres() - open the tet_xres file in TETware-Lite
+*/
+
+TET_IMPORT void tet_openres()
+{
+ char cwdbuf[MAXPATH];
+ static char resvar[] = "TET_RESFILE";
+ static char resname[] = "tet_xres";
+ static char tmpvar[] = "TET_TMPRESFILE";
+ static char tmpname[] = "tet_res.tmp";
+
+ /* set full path name of execution results file and temp results
+ file, in a form convenient for placing in the environment */
+
+ if (GETCWD(cwdbuf, (size_t)MAXPATH) == NULL)
+ fatal(errno, "getcwd() failed", (char *) 0);
+
+ resenv = malloc(strlen(cwdbuf)+sizeof(resvar)+sizeof(resname)+4);
+ if (resenv == NULL)
+ fatal(errno, "can't allocate resenv in tet_openres()",
+ (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate resenv = %s", tet_i2x(resenv));
+
+ tmpresenv = malloc(strlen(cwdbuf)+sizeof(tmpvar)+sizeof(tmpname)+4);
+ if (tmpresenv == NULL)
+ fatal(errno, "can't allocate tmpresenv in tet_openres()",
+ (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate tmpresenv = %s",
+ tet_i2x(tmpresenv));
+
+ (void) sprintf(resenv, "%s=%s/%s", resvar, cwdbuf, resname);
+ resfile = resenv + sizeof(resvar);
+
+ (void) sprintf(tmpresenv, "%s=%s/%s", tmpvar, cwdbuf, tmpname);
+ tet_tmpresfile = tmpresenv + sizeof(tmpvar);
+
+ /* create the execution results file and open in append mode */
+
+ (void) remove(resfile);
+ tet_resfp = fopen(resfile, "a");
+ if (tet_resfp == NULL)
+ fatal(errno, "cannot create results file:", resfile);
+
+ /* override umask (must be writable by set-uid children) */
+ (void) CHMOD(resfile, MODE666);
+
+ /* put pathname in environment to be picked up in exec'ed programs */
+ if (tet_putenv(resenv) != 0)
+ tet_error(0, "tet_putenv() failed when setting TET_RESFILE");
+
+ tet_combined_ok = 1;
+}
+
+/*
+** lite_output() - print a line to the tet_xres file in TETware-Lite
+*/
+
+static void lite_output(mtype, fields, data)
+int mtype;
+char *fields;
+char *data;
+{
+ char outbuf[TET_JNL_LEN];
+ char *obp;
+ static char fmt[] = "%d|%ld%s%.64s|";
+ char header[sizeof fmt + (LNUMSZ * 2) + 64];
+
+ if (data == NULL)
+ data = "";
+
+ (void) sprintf(header, fmt, mtype, tet_activity,
+ fields[0] == '\0' ? "" : " ", fields);
+ tet_msgform(header, data, outbuf);
+ obp = outbuf;
+ tet_routput(&obp, 1);
+}
+
+/*
+** curtime() - return string containing current time
+*/
+
+static char *curtime()
+{
+ time_t t;
+ struct tm *tp;
+ static char s[10];
+
+ (void) time(&t);
+ tp = localtime(&t);
+ (void) sprintf(s, "%02d:%02d:%02d", tp->tm_hour,
+ tp->tm_min, tp->tm_sec);
+
+ return s;
+}
+
+#endif /* -END-LITE-CUT- */
+
diff --git a/src/tet3/tcm/inetlib.mk b/src/tet3/tcm/inetlib.mk
new file mode 100644
index 00000000..958fc0c7
--- /dev/null
+++ b/src/tet3/tcm/inetlib.mk
@@ -0,0 +1,50 @@
+#
+# SCCS: @(#)inetlib.mk 1.9 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1993 X/Open Company Limited
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+#
+# ************************************************************************
+#
+# SCCS: @(#)inetlib.mk 1.9 98/09/01 TETware release 3.3
+# NAME: inetlib.mk
+# PRODUCT: TETware
+# AUTHOR: Denis McConalogue, UniSoft Ltd.
+# DATE CREATED: August 1993
+#
+# DESCRIPTION:
+# aux include file for INET-specific tcm files
+#
+# MODIFICATIONS:
+# Andrew Dingwall, UniSoft Ltd., December 1993
+# Moved lists of transport-specific files from makefile and dtet.mk
+# to here.
+#
+# Geoff Clare, UniSoft Ltd., Sept 1996
+# Changes for TETware-Lite.
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+# additional targets when building the TCM in Distributed TETware
+ALL_TS = $(ALL_DIST)
+TARGETS_TS = $(TARGETS_DIST)
+TARGETS_TS_S = $(TARGETS_DIST_S)
+
+# INET-specific tcm object files
+TCM_STATIC_OFILES_TS = tcm_in$O tcm_bs$O
+TCM_SHARED_OFILES_TS =
+
diff --git a/src/tet3/tcm/litelib.mk b/src/tet3/tcm/litelib.mk
new file mode 100644
index 00000000..06dfd822
--- /dev/null
+++ b/src/tet3/tcm/litelib.mk
@@ -0,0 +1,43 @@
+#
+# SCCS: @(#)litelib.mk 1.3 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1993 X/Open Company Limited
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+#
+# ************************************************************************
+#
+# SCCS: @(#)litelib.mk 1.3 98/09/01 TETware release 3.3
+# NAME: litelib.mk
+# PRODUCT: TETware
+# AUTHOR: Geoff Clare, UniSoft Ltd.
+# DATE CREATED: Sept 1996
+#
+# DESCRIPTION:
+# aux include file for TETware-Lite specific tcm files
+#
+# MODIFICATIONS:
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+# there are no additional targets or transport-specific object files
+# in TETware-Lite
+ALL_TS =
+TARGETS_TS =
+TARGETS_TS_S =
+TCM_STATIC_OFILES_TS =
+TCM_SHARED_OFILES_TS =
+
diff --git a/src/tet3/tcm/makefile b/src/tet3/tcm/makefile
new file mode 100644
index 00000000..53ecb2f4
--- /dev/null
+++ b/src/tet3/tcm/makefile
@@ -0,0 +1,143 @@
+#
+# SCCS: @(#)makefile 1.13 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1992 X/Open Company Limited
+# (C) Copyright 1994 UniSoft Ltd.
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+#
+# ************************************************************************
+#
+# SCCS: @(#)makefile 1.13 98/09/01 TETware release 3.3
+# NAME: makefile
+# PRODUCT: TETware
+# AUTHOR: Andrew Dingwall, UniSoft Ltd.
+# DATE CREATED: June 1992
+#
+# DESCRIPTION:
+# tcm makefile
+#
+# MODIFICATIONS:
+# Denis McConalogue, UniSoft Limited, September 1993
+# adapted from the makefile in src/dtet/tcm/makefile.
+#
+# Andrew Dingwall, UniSoft Ltd., December 1993
+# Enhancements for FIFO transport interface.
+# Moved lists of transport-specific files to ts.mk
+#
+# Geoff Clare, UniSoft Ltd., August 1996
+# Changes for TETWare.
+#
+# Geoff Clare, UniSoft Ltd., Sept 1996
+# Changes for TETware-Lite.
+#
+# Geoff Clare, UniSoft Ltd., Oct 1996
+# restructured tcm source to avoid "ld -r"
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+include ../../defines.mk
+include ../ts.mk
+
+LOCAL_TET_CDEFS = $(TET_CDEFS)
+LOCAL_DTET_CDEFS = $(DTET_CDEFS)
+LOCAL_CDEFS =
+LOCAL_COPTS = $(COPTS)
+LOCAL_CC = $(CC)
+
+# TET_CFLAGS and DTET_CFLAGS are set in ../common.mk
+include ../common.mk
+
+
+LIBNAME = $(LIBDAPI)
+
+# generic C build targets
+ALL_GN = tcm$O tcmchild$O
+TARGETS_GN = $(LIB)/tcm$O $(LIB)/tcmchild$O
+
+# additional targets when building the TCM in Distributed TETware
+ALL_DIST = tcmrem$O
+TARGETS_DIST = $(LIB)/tcmrem$O
+
+# this sets ALL_TS, TARGETS_TS and TCM_OFILES_TS
+include ts.mk
+
+# C build targets
+ALL = $(ALL_GN) $(ALL_TS)
+TARGETS = $(TARGETS_GN) $(TARGETS_TS)
+
+# C++ build targets
+# (tcmrem$O isn't supported in the C++ API)
+ALLC = Ctcm$O Ctcmchild$O
+TARGETSC = $(LIB)/Ctcm$O $(LIB)/Ctcmchild$O
+
+all: $(ALL) lib_made
+
+allC: $(ALLC)
+
+install: $(TARGETS) lib_made
+
+installC: $(TARGETSC)
+
+# this sets TCM_OFILES
+TCMSRC =
+APISHLIBSRC =
+include shared.mk
+
+$(LIB)/tcm$O: tcm$O dtcm$O
+ ld -r -o $@ tcm$O dtcm$O
+
+$(LIB)/tcmrem$O: tcmrem$O
+ cp $? $@
+
+$(LIB)/tcmchild$O: tcmchild$O
+ cp $? $@
+
+$(LIB)/Ctcm$O: Ctcm$O dtcm$O
+ ld -r -o $@ Ctcm$O dtcm$O
+
+$(LIB)/Ctcmchild$O: Ctcmchild$O
+ cp $? $@
+
+OFILES = $(TCM_OFILES)
+
+lib_made: $(OFILES)
+ if test -f lib_made; then \
+ $(AR) rv $(LIBNAME) $? ;\
+ else \
+ $(AR) rv $(LIBNAME) `$(LORDER) $(OFILES) | $(TSORT)` ;\
+ fi
+ $(RANLIB) $(LIBNAME)
+ touch lib_made
+
+.PRECIOUS: $(LIBNAME)
+
+
+CLEAN clean:
+ rm -f $(OFILES) $(ALL) $(ALLC) dynlink_gen_made
+
+CLOBBER clobber: clean
+ rm -f $(TARGETS) $(TARGETSC) lib_made
+
+FORCE FRC: clobber all
+
+
+# remove suffix rules from this makefile
+# all .o files are made by explicit rules
+.SUFFIXES:
+
+.SUFFIXES: .none
+
diff --git a/src/tet3/tcm/makefile.orig b/src/tet3/tcm/makefile.orig
new file mode 100644
index 00000000..acd0d313
--- /dev/null
+++ b/src/tet3/tcm/makefile.orig
@@ -0,0 +1,143 @@
+#
+# SCCS: @(#)makefile 1.13 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1992 X/Open Company Limited
+# (C) Copyright 1994 UniSoft Ltd.
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+#
+# ************************************************************************
+#
+# SCCS: @(#)makefile 1.13 98/09/01 TETware release 3.3
+# NAME: makefile
+# PRODUCT: TETware
+# AUTHOR: Andrew Dingwall, UniSoft Ltd.
+# DATE CREATED: June 1992
+#
+# DESCRIPTION:
+# tcm makefile
+#
+# MODIFICATIONS:
+# Denis McConalogue, UniSoft Limited, September 1993
+# adapted from the makefile in src/dtet/tcm/makefile.
+#
+# Andrew Dingwall, UniSoft Ltd., December 1993
+# Enhancements for FIFO transport interface.
+# Moved lists of transport-specific files to ts.mk
+#
+# Geoff Clare, UniSoft Ltd., August 1996
+# Changes for TETWare.
+#
+# Geoff Clare, UniSoft Ltd., Sept 1996
+# Changes for TETware-Lite.
+#
+# Geoff Clare, UniSoft Ltd., Oct 1996
+# restructured tcm source to avoid "ld -r"
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+include ../../defines.mk
+include ../ts.mk
+
+LOCAL_TET_CDEFS = $(TET_CDEFS)
+LOCAL_DTET_CDEFS = $(DTET_CDEFS)
+LOCAL_CDEFS =
+LOCAL_COPTS = $(COPTS)
+LOCAL_CC = $(CC)
+
+# TET_CFLAGS and DTET_CFLAGS are set in ../common.mk
+include ../common.mk
+
+
+LIBNAME = $(LIBDAPI)
+
+# generic C build targets
+ALL_GN = tcm$O tcmchild$O
+TARGETS_GN = $(LIB)/tcm$O $(LIB)/tcmchild$O
+
+# additional targets when building the TCM in Distributed TETware
+ALL_DIST = tcmrem$O
+TARGETS_DIST = $(LIB)/tcmrem$O
+
+# this sets ALL_TS, TARGETS_TS and TCM_OFILES_TS
+include ts.mk
+
+# C build targets
+ALL = $(ALL_GN) $(ALL_TS)
+TARGETS = $(TARGETS_GN) $(TARGETS_TS)
+
+# C++ build targets
+# (tcmrem$O isn't supported in the C++ API)
+ALLC = Ctcm$O Ctcmchild$O
+TARGETSC = $(LIB)/Ctcm$O $(LIB)/Ctcmchild$O
+
+all: $(ALL) lib_made
+
+allC: $(ALLC)
+
+install: $(TARGETS) lib_made
+
+installC: $(TARGETSC)
+
+# this sets TCM_OFILES
+TCMSRC =
+APISHLIBSRC =
+include shared.mk
+
+$(LIB)/tcm$O: tcm$O
+ cp $? $@
+
+$(LIB)/tcmrem$O: tcmrem$O
+ cp $? $@
+
+$(LIB)/tcmchild$O: tcmchild$O
+ cp $? $@
+
+$(LIB)/Ctcm$O: Ctcm$O
+ cp $? $@
+
+$(LIB)/Ctcmchild$O: Ctcmchild$O
+ cp $? $@
+
+OFILES = $(TCM_OFILES)
+
+lib_made: $(OFILES)
+ if test -f lib_made; then \
+ $(AR) rv $(LIBNAME) $? ;\
+ else \
+ $(AR) rv $(LIBNAME) `$(LORDER) $(OFILES) | $(TSORT)` ;\
+ fi
+ $(RANLIB) $(LIBNAME)
+ touch lib_made
+
+.PRECIOUS: $(LIBNAME)
+
+
+CLEAN clean:
+ rm -f $(OFILES) $(ALL) $(ALLC) dynlink_gen_made
+
+CLOBBER clobber: clean
+ rm -f $(TARGETS) $(TARGETSC) lib_made
+
+FORCE FRC: clobber all
+
+
+# remove suffix rules from this makefile
+# all .o files are made by explicit rules
+.SUFFIXES:
+
+.SUFFIXES: .none
+
diff --git a/src/tet3/tcm/shared.mk b/src/tet3/tcm/shared.mk
new file mode 100644
index 00000000..295ab962
--- /dev/null
+++ b/src/tet3/tcm/shared.mk
@@ -0,0 +1,175 @@
+#
+# SCCS: @(#)shared.mk 1.4 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1996 X/Open Company Limited
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+# A copy of the end-user licence agreement is contained in the file
+# Licence which accompanies this distribution.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+# ************************************************************************
+#
+# SCCS: @(#)shared.mk 1.4 98/09/01
+# NAME: shared.mk
+# PRODUCT: TETware
+# AUTHOR: Geoff Clare, UniSoft Ltd.
+# DATE CREATED: October 1996
+#
+# DESCRIPTION:
+# make include file, shared between tcm, tcmthr, tcmshlib and tcmthrshlib
+#
+# MODIFICATIONS:
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+#
+# tcm object files that go in the API library
+#
+
+# list of object files to be included in shared API libraries
+TCM_SHARED_OFILES = ictp$O $(TCM_SHARED_OFILES_TS)
+
+# list of object files to be included in the static part of the shared
+# API libraries
+TCM_STATIC_OFILES = child$O ckversion$O dynlink$O tcmfuncs$O \
+ $(TCM_STATIC_OFILES_TS)
+
+# list of object files to be included in the static API libraries
+TCM_OFILES = $(TCM_SHARED_OFILES) $(TCM_STATIC_OFILES)
+
+# compilations using TET_CFLAGS
+
+child$O: $(TCMSRC)child.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)child.c
+
+ckversion$O: $(TCMSRC)ckversion.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)ckversion.c
+
+dynlink$O: $(TCMSRC)dynlink.c dynlink_gen_made
+ $(LOCAL_CC) -I$(APISHLIBSRC). $(TET_CFLAGS) -c $(TCMSRC)dynlink.c
+
+# note that the dependences in the following rule are incomplete,
+# but it's the best we can do;
+# the higher level makefile makes api*shlib before tcm*shlib, so it doesn't
+# usually matter
+dynlink_gen_made:
+ @set -x; \
+ if test -n "$(APISHLIBSRC)"; \
+ then \
+ cd $(APISHLIBSRC); \
+ $(MAKE) dynlink.gen; \
+ fi
+ touch $@
+
+ictp$O: $(TCMSRC)ictp.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)ictp.c
+
+tcm$O: $(TCMSRC)tcm.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcm.c
+
+tcmchild$O: $(TCMSRC)tcmchild.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmchild.c
+
+tcmfuncs$O: $(TCMSRC)tcmfuncs.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmfuncs.c
+
+tcmrem$O: $(TCMSRC)tcmrem.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmrem.c
+
+tcm_bs$O: $(TCMSRC)tcm_bs.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcm_bs.c
+
+# compilations using DTET_CFLAGS
+
+dtcm$O: $(TCMSRC)dtcm.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)dtcm.c
+
+tcm_in$O: $(TCMSRC)tcm_in.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)tcm_in.c
+
+tcm_xt$O: $(TCMSRC)tcm_xt.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)tcm_xt.c
+
+# C++ compilations
+
+Ctcm$O: $(TCMSRC)tcm.c
+ rm -f Ctcm.$(C_SUFFIX)
+ cp $(TCMSRC)tcm.c Ctcm.$(C_SUFFIX)
+ $(C_PLUS) $(TET_CFLAGS) -I$(TCMSRC). -c Ctcm.$(C_SUFFIX)
+ rm -f Ctcm.$(C_SUFFIX)
+
+Ctcmchild$O: $(TCMSRC)tcmchild.c
+ rm -f Ctcmchild.$(C_SUFFIX)
+ cp $(TCMSRC)tcmchild.c Ctcmchild.$(C_SUFFIX)
+ $(C_PLUS) $(TET_CFLAGS) -I$(TCMSRC). -c Ctcmchild.$(C_SUFFIX)
+ rm -f Ctcmchild.$(C_SUFFIX)
+
+
+# dependencies
+
+Ctcm$O tcm$O: $(INC)/apilib.h $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/sigsafe.h $(INC)/synreq.h $(INC)/tslib.h \
+ $(TCMSRC)tcmfuncs.h
+
+Ctcmchild$O tcmchild$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/servlib.h $(INC)/sigsafe.h $(INC)/synreq.h \
+ $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
+child$O: $(DINC)/tet_api.h $(INC)/alarm.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/sigsafe.h $(INC)/synreq.h $(TCMSRC)tcmfuncs.h
+
+ckversion$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtmac.h \
+ $(INC)/globals.h $(TCMSRC)tcmfuncs.h ../apilib/version.c
+
+dtcm$O: $(DINC)/tet_api.h $(INC)/alarm.h $(INC)/apilib.h $(INC)/bstring.h \
+ $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h \
+ $(INC)/error.h $(INC)/ltoa.h $(INC)/servlib.h $(INC)/sigsafe.h \
+ $(INC)/synreq.h $(TCMSRC)tcmfuncs.h
+
+dynlink$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/server_bs.h $(INC)/server_in.h $(INC)/synreq.h \
+ $(TCMSRC)tcmfuncs.h
+
+ictp$O: $(DINC)/tet_api.h $(DINC)/tet_jrnl.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/ltoa.h $(INC)/servlib.h $(INC)/synreq.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_bs$O: $(INC)/avmsg.h $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/error.h $(INC)/ptab.h $(INC)/server_bs.h $(INC)/valmsg.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_in$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/inetlib_in.h $(INC)/ltoa.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/tptab_in.h $(INC)/tsinfo_in.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_xt$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/ltoa.h $(INC)/ptab.h $(INC)/server.h $(INC)/tptab_xt.h \
+ $(INC)/tsinfo_xt.h $(INC)/xtilib_xt.h $(TCMSRC)tcmfuncs.h
+
+tcmfuncs$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h $(INC)/globals.h \
+ $(INC)/ltoa.h $(INC)/ptab.h $(INC)/server.h $(INC)/servlib.h \
+ $(INC)/synreq.h $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
+tcmrem$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/ptab.h $(INC)/server.h $(INC)/sigsafe.h \
+ $(INC)/synreq.h $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
diff --git a/src/tet3/tcm/shared.mk.orig b/src/tet3/tcm/shared.mk.orig
new file mode 100644
index 00000000..ff19b483
--- /dev/null
+++ b/src/tet3/tcm/shared.mk.orig
@@ -0,0 +1,175 @@
+#
+# SCCS: @(#)shared.mk 1.4 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1996 X/Open Company Limited
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+# A copy of the end-user licence agreement is contained in the file
+# Licence which accompanies this distribution.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+# ************************************************************************
+#
+# SCCS: @(#)shared.mk 1.4 98/09/01
+# NAME: shared.mk
+# PRODUCT: TETware
+# AUTHOR: Geoff Clare, UniSoft Ltd.
+# DATE CREATED: October 1996
+#
+# DESCRIPTION:
+# make include file, shared between tcm, tcmthr, tcmshlib and tcmthrshlib
+#
+# MODIFICATIONS:
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+#
+# tcm object files that go in the API library
+#
+
+# list of object files to be included in shared API libraries
+TCM_SHARED_OFILES = ictp$O $(TCM_SHARED_OFILES_TS)
+
+# list of object files to be included in the static part of the shared
+# API libraries
+TCM_STATIC_OFILES = child$O ckversion$O dtcm$O dynlink$O tcmfuncs$O \
+ $(TCM_STATIC_OFILES_TS)
+
+# list of object files to be included in the static API libraries
+TCM_OFILES = $(TCM_SHARED_OFILES) $(TCM_STATIC_OFILES)
+
+# compilations using TET_CFLAGS
+
+child$O: $(TCMSRC)child.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)child.c
+
+ckversion$O: $(TCMSRC)ckversion.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)ckversion.c
+
+dynlink$O: $(TCMSRC)dynlink.c dynlink_gen_made
+ $(LOCAL_CC) -I$(APISHLIBSRC). $(TET_CFLAGS) -c $(TCMSRC)dynlink.c
+
+# note that the dependences in the following rule are incomplete,
+# but it's the best we can do;
+# the higher level makefile makes api*shlib before tcm*shlib, so it doesn't
+# usually matter
+dynlink_gen_made:
+ @set -x; \
+ if test -n "$(APISHLIBSRC)"; \
+ then \
+ cd $(APISHLIBSRC); \
+ $(MAKE) dynlink.gen; \
+ fi
+ touch $@
+
+ictp$O: $(TCMSRC)ictp.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)ictp.c
+
+tcm$O: $(TCMSRC)tcm.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcm.c
+
+tcmchild$O: $(TCMSRC)tcmchild.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmchild.c
+
+tcmfuncs$O: $(TCMSRC)tcmfuncs.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmfuncs.c
+
+tcmrem$O: $(TCMSRC)tcmrem.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcmrem.c
+
+tcm_bs$O: $(TCMSRC)tcm_bs.c
+ $(LOCAL_CC) $(TET_CFLAGS) -c $(TCMSRC)tcm_bs.c
+
+# compilations using DTET_CFLAGS
+
+dtcm$O: $(TCMSRC)dtcm.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)dtcm.c
+
+tcm_in$O: $(TCMSRC)tcm_in.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)tcm_in.c
+
+tcm_xt$O: $(TCMSRC)tcm_xt.c
+ $(LOCAL_CC) $(DTET_CFLAGS) -c $(TCMSRC)tcm_xt.c
+
+# C++ compilations
+
+Ctcm$O: $(TCMSRC)tcm.c
+ rm -f Ctcm.$(C_SUFFIX)
+ cp $(TCMSRC)tcm.c Ctcm.$(C_SUFFIX)
+ $(C_PLUS) $(TET_CFLAGS) -I$(TCMSRC). -c Ctcm.$(C_SUFFIX)
+ rm -f Ctcm.$(C_SUFFIX)
+
+Ctcmchild$O: $(TCMSRC)tcmchild.c
+ rm -f Ctcmchild.$(C_SUFFIX)
+ cp $(TCMSRC)tcmchild.c Ctcmchild.$(C_SUFFIX)
+ $(C_PLUS) $(TET_CFLAGS) -I$(TCMSRC). -c Ctcmchild.$(C_SUFFIX)
+ rm -f Ctcmchild.$(C_SUFFIX)
+
+
+# dependencies
+
+Ctcm$O tcm$O: $(INC)/apilib.h $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/sigsafe.h $(INC)/synreq.h $(INC)/tslib.h \
+ $(TCMSRC)tcmfuncs.h
+
+Ctcmchild$O tcmchild$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/servlib.h $(INC)/sigsafe.h $(INC)/synreq.h \
+ $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
+child$O: $(DINC)/tet_api.h $(INC)/alarm.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/sigsafe.h $(INC)/synreq.h $(TCMSRC)tcmfuncs.h
+
+ckversion$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtmac.h \
+ $(INC)/globals.h $(TCMSRC)tcmfuncs.h ../apilib/version.c
+
+dtcm$O: $(DINC)/tet_api.h $(INC)/alarm.h $(INC)/apilib.h $(INC)/bstring.h \
+ $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h \
+ $(INC)/error.h $(INC)/ltoa.h $(INC)/servlib.h $(INC)/sigsafe.h \
+ $(INC)/synreq.h $(TCMSRC)tcmfuncs.h
+
+dynlink$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/dtthr.h $(INC)/error.h $(INC)/globals.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/server_bs.h $(INC)/server_in.h $(INC)/synreq.h \
+ $(TCMSRC)tcmfuncs.h
+
+ictp$O: $(DINC)/tet_api.h $(DINC)/tet_jrnl.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/dtthr.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/ltoa.h $(INC)/servlib.h $(INC)/synreq.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_bs$O: $(INC)/avmsg.h $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h \
+ $(INC)/error.h $(INC)/ptab.h $(INC)/server_bs.h $(INC)/valmsg.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_in$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/inetlib_in.h $(INC)/ltoa.h $(INC)/ptab.h \
+ $(INC)/server.h $(INC)/tptab_in.h $(INC)/tsinfo_in.h \
+ $(TCMSRC)tcmfuncs.h
+
+tcm_xt$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/ltoa.h $(INC)/ptab.h $(INC)/server.h $(INC)/tptab_xt.h \
+ $(INC)/tsinfo_xt.h $(INC)/xtilib_xt.h $(TCMSRC)tcmfuncs.h
+
+tcmfuncs$O: $(DINC)/tet_api.h $(INC)/apilib.h $(INC)/dtetlib.h \
+ $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h $(INC)/globals.h \
+ $(INC)/ltoa.h $(INC)/ptab.h $(INC)/server.h $(INC)/servlib.h \
+ $(INC)/synreq.h $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
+tcmrem$O: $(INC)/dtetlib.h $(INC)/dtmac.h $(INC)/dtmsg.h $(INC)/error.h \
+ $(INC)/globals.h $(INC)/ptab.h $(INC)/server.h $(INC)/sigsafe.h \
+ $(INC)/synreq.h $(INC)/tslib.h $(TCMSRC)tcmfuncs.h
+
diff --git a/src/tet3/tcm/tcm.c b/src/tet3/tcm/tcm.c
new file mode 100644
index 00000000..f2627082
--- /dev/null
+++ b/src/tet3/tcm/tcm.c
@@ -0,0 +1,363 @@
+/*
+ * SCCS: @(#)tcm.c 1.17 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcm.c 1.17 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcm.c 1.17 98/09/01 TETware release 3.3
+NAME: tcm.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ tcm main() and client-related functions
+
+MODIFICATIONS:
+ Denis McConalogue, UniSoft Limited, June 1993
+ API enhancements - combined [ms]tcmfuncs.c into this file.
+
+ Denis McConalogue, UniSoft Limited, September 1993
+ changed tet_tcmptype() to set process type PT_MTCM for
+ all non-distributed test cases (executing on master or
+ slave systems).
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for TETware
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ changes for TETware-Lite
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+ (this file was mtcmfuncs.c - moved main() and other things here)
+
+ Andrew Dingwall, UniSoft Ltd., April 1997
+ initialise tet_pname in case it gets used (in tet_dtcmerror())
+ before it can be set up in tet_tcm*_main()
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ initialised tet_tcmlast to the hightest possible value
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+ Andrew Josey, The Open Group, February 2000
+ Add a cast to the call on tet_init_globals to placate the
+ latest g++ compiler.
+************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+# include <signal.h>
+# include <unistd.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "globals.h"
+#include "tcmfuncs.h"
+#ifndef TET_LITE /* -START-LITE-CUT- */
+# include "error.h"
+# include "ptab.h"
+# include "synreq.h"
+# include "server.h"
+# include "tslib.h"
+#endif /* -END-LITE-CUT- */
+#include "dtetlib.h"
+#include "sigsafe.h"
+
+extern int tet_tcm_main PROTOLIST((int, char **));
+extern void tet_dtcmerror PROTOLIST((int, char *, int, char *, char *));
+
+TET_EXPORT char *tet_pname = "<unknown>";
+TET_EXPORT int tet_thistest = 0;
+TET_EXPORT int tet_nosigreset = 0; /* has no effect in WIN32 */
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+TET_EXPORT long tet_snid = -1L; /* sync id */
+TET_EXPORT long tet_xrid = -1L; /* xres id */
+TET_EXPORT int *tet_snames; /* system name list */
+TET_EXPORT int tet_Nsname; /* number of system names */
+TET_EXPORT struct ptab *tet_sdptab, *tet_xdptab;
+ /* ptab elements for syncd and xresd */
+int tet_psysid = -1; /* parent's system id */
+#endif /* -END-LITE-CUT- */
+
+TET_EXPORT sigset_t tet_blockable_sigs;
+
+#ifdef TET_THREADS
+TET_EXPORT tet_thread_t tet_start_tid;
+#endif /* TET_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+** main() is the main program for the Test Case Manager (TCM).
+** It is simply a wrapper for tet_tcm_main().
+*/
+
+#ifdef PROTOTYPES
+int main(int argc, char **argv)
+#else
+int main(argc, argv)
+int argc;
+char **argv;
+#endif
+{
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define MYPTYPE PT_MTCM
+# define MYSYSID 0
+#else /* -START-LITE-CUT- */
+# define MYPTYPE -1
+# define MYSYSID -1
+#endif /* -END-LITE-CUT- */
+
+ /* must be first */
+ tet_init_globals(argc > 0 ? tet_basename(*argv) : (char *) "TCM",
+ MYPTYPE, MYSYSID, tet_dtcmerror, tet_genfatal);
+
+ /*
+ ** make sure that we are linked with the right version of
+ ** the API library
+ */
+ tet_check_apilib_version();
+
+
+ return tet_tcm_main(argc, argv);
+}
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+/*
+** tet_tcm_async() - do an automatic sync from the MTCM
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_tcm_async(long spno, int vote, int timeout,
+ struct synreq *synreq, int *nsys)
+#else
+TET_EXPORT int tet_tcm_async(spno, vote, timeout, synreq, nsys)
+long spno;
+int vote, timeout, *nsys;
+struct synreq *synreq;
+#endif
+{
+ return(tet_sdasync(tet_snid, tet_xrid, spno, vote, timeout, synreq, nsys));
+}
+
+/*
+** tet_tcmptype() - return process type for a TCM
+**
+** In TETware there is almost no difference between "master" and
+** "slave" TCMs and this function is only used to decide which
+** TCMs in a distributed test case should inform XRESD of IC and
+** TP start and end.
+** Someone has to do it so it might as well be the first (or only)
+** system in the system list.
+*/
+
+int tet_tcmptype PROTOLIST((void))
+{
+ int sys1;
+
+ sys1 = tet_snames ? *tet_snames : -1;
+
+ return (tet_mysysid == sys1 ? PT_MTCM : PT_STCM);
+}
+
+/*
+** tet_ss_dead() - server-specific dead process handler
+**
+** should only be called from tet_si_service() when a server dies
+** unexpectedly
+**
+** server logoff routines do not come here
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_dead(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_dead(pp)
+struct ptab *pp;
+#endif
+{
+ /* emit a diagnostic if this is unexpected */
+ if ((pp->pt_flags & PF_LOGGEDOFF) == 0)
+ error(0, "server connection closed", tet_r2a(&pp->pt_rid));
+
+ pp->pt_flags = (pp->pt_flags & ~PF_LOGGEDON) | PF_LOGGEDOFF;
+}
+
+/*
+** tet_ss_connect() - connect to remote process
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_connect(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_connect(pp)
+struct ptab *pp;
+#endif
+{
+ tet_ts_connect(pp);
+}
+
+/*
+** tet_ss_ptalloc(), tet_ss_ptfree() - allocate and free server-specific
+** ptab data area
+**
+** tcm does not make use of server-specific data
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_ptalloc(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_ptalloc(pp)
+struct ptab *pp;
+#endif
+{
+ pp->pt_sdata = (char *) 0;
+ return(0);
+}
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_ptfree(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_ptfree(pp)
+struct ptab *pp;
+#endif
+{
+ /* nothing */
+}
+
+/*
+** tet_ss_serverloop() - server-specific server loop
+**
+** this may be called from tet_si_servwait() if non-blocking message i/o
+** would block
+**
+** tcm does not do non-blocking i/o, so this should never occur
+*/
+
+TET_EXPORT int tet_ss_serverloop PROTOLIST((void))
+{
+ error(0, "internal error - serverloop called!", (char *) 0);
+ return(-1);
+}
+
+/*
+** tet_ss_process() - server-specific request process routine
+**
+** would be called from tet_si_service() when state is PS_PROCESS
+**
+** tcm only uses tet_si_clientloop() which itself returns as soon as a
+** process reaches this state, so tet_ss_process() should never be called
+**/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_process(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_process(pp)
+struct ptab *pp;
+#endif
+{
+ error(0, "internal error - tet_ss_process called!",
+ tet_r2a(&pp->pt_rid));
+}
+
+/*
+ * The following functions are simply wrappers for the real functions
+ * in tcm_bs.c, tcm_in.c and tcm_xt.c. This is done so that tccd, xresd
+ * and syncd cannot resolve these symbols in libapi.a.
+ */
+
+extern int tet_tcm_bs2md PROTOLIST((char *, struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_bs2md(char *from, struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_bs2md(from, pp)
+char *from;
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_bs2md(from, pp);
+}
+
+extern int tet_tcm_md2bs PROTOLIST((struct ptab *, char **, int *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_md2bs(struct ptab *pp, char **bp, int *lp, int offs)
+#else
+TET_EXPORT int tet_ss_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+#endif
+{
+ return tet_tcm_md2bs(pp, bp, lp, offs);
+}
+
+extern int tet_tcm_tsconnect PROTOLIST((struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsconnect(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_tsconnect(pp)
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_tsconnect(pp);
+}
+
+extern int tet_tcm_tsinfo PROTOLIST((struct ptab *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsinfo(struct ptab *pp, int ptype)
+#else
+TET_EXPORT int tet_ss_tsinfo(pp, ptype)
+struct ptab *pp;
+int ptype;
+#endif
+{
+ return tet_tcm_tsinfo(pp, ptype);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* -END-LITE-CUT- */
+
diff --git a/src/tet3/tcm/tcm.c.orig b/src/tet3/tcm/tcm.c.orig
new file mode 100644
index 00000000..32e30cb5
--- /dev/null
+++ b/src/tet3/tcm/tcm.c.orig
@@ -0,0 +1,360 @@
+/*
+ * SCCS: @(#)tcm.c 1.17 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcm.c 1.17 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcm.c 1.17 98/09/01 TETware release 3.3
+NAME: tcm.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ tcm main() and client-related functions
+
+MODIFICATIONS:
+ Denis McConalogue, UniSoft Limited, June 1993
+ API enhancements - combined [ms]tcmfuncs.c into this file.
+
+ Denis McConalogue, UniSoft Limited, September 1993
+ changed tet_tcmptype() to set process type PT_MTCM for
+ all non-distributed test cases (executing on master or
+ slave systems).
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for TETware
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ changes for TETware-Lite
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+ (this file was mtcmfuncs.c - moved main() and other things here)
+
+ Andrew Dingwall, UniSoft Ltd., April 1997
+ initialise tet_pname in case it gets used (in tet_dtcmerror())
+ before it can be set up in tet_tcm*_main()
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ initialised tet_tcmlast to the hightest possible value
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+# include <signal.h>
+# include <unistd.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "globals.h"
+#include "tcmfuncs.h"
+#ifndef TET_LITE /* -START-LITE-CUT- */
+# include "error.h"
+# include "ptab.h"
+# include "synreq.h"
+# include "server.h"
+# include "tslib.h"
+#endif /* -END-LITE-CUT- */
+#include "dtetlib.h"
+#include "sigsafe.h"
+
+extern int tet_tcm_main PROTOLIST((int, char **));
+extern void tet_dtcmerror PROTOLIST((int, char *, int, char *, char *));
+
+TET_EXPORT char *tet_pname = "<unknown>";
+TET_EXPORT int tet_thistest = 0;
+TET_EXPORT int tet_nosigreset = 0; /* has no effect in WIN32 */
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+TET_EXPORT long tet_snid = -1L; /* sync id */
+TET_EXPORT long tet_xrid = -1L; /* xres id */
+TET_EXPORT int *tet_snames; /* system name list */
+TET_EXPORT int tet_Nsname; /* number of system names */
+TET_EXPORT struct ptab *tet_sdptab, *tet_xdptab;
+ /* ptab elements for syncd and xresd */
+int tet_psysid = -1; /* parent's system id */
+#endif /* -END-LITE-CUT- */
+
+TET_EXPORT sigset_t tet_blockable_sigs;
+
+#ifdef TET_THREADS
+TET_EXPORT tet_thread_t tet_start_tid;
+#endif /* TET_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+** main() is the main program for the Test Case Manager (TCM).
+** It is simply a wrapper for tet_tcm_main().
+*/
+
+#ifdef PROTOTYPES
+int main(int argc, char **argv)
+#else
+int main(argc, argv)
+int argc;
+char **argv;
+#endif
+{
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define MYPTYPE PT_MTCM
+# define MYSYSID 0
+#else /* -START-LITE-CUT- */
+# define MYPTYPE -1
+# define MYSYSID -1
+#endif /* -END-LITE-CUT- */
+
+ /* must be first */
+ tet_init_globals(argc > 0 ? tet_basename(*argv) : "TCM",
+ MYPTYPE, MYSYSID, tet_dtcmerror, tet_genfatal);
+
+ /*
+ ** make sure that we are linked with the right version of
+ ** the API library
+ */
+ tet_check_apilib_version();
+
+
+ return tet_tcm_main(argc, argv);
+}
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+/*
+** tet_tcm_async() - do an automatic sync from the MTCM
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_tcm_async(long spno, int vote, int timeout,
+ struct synreq *synreq, int *nsys)
+#else
+TET_EXPORT int tet_tcm_async(spno, vote, timeout, synreq, nsys)
+long spno;
+int vote, timeout, *nsys;
+struct synreq *synreq;
+#endif
+{
+ return(tet_sdasync(tet_snid, tet_xrid, spno, vote, timeout, synreq, nsys));
+}
+
+/*
+** tet_tcmptype() - return process type for a TCM
+**
+** In TETware there is almost no difference between "master" and
+** "slave" TCMs and this function is only used to decide which
+** TCMs in a distributed test case should inform XRESD of IC and
+** TP start and end.
+** Someone has to do it so it might as well be the first (or only)
+** system in the system list.
+*/
+
+int tet_tcmptype PROTOLIST((void))
+{
+ int sys1;
+
+ sys1 = tet_snames ? *tet_snames : -1;
+
+ return (tet_mysysid == sys1 ? PT_MTCM : PT_STCM);
+}
+
+/*
+** tet_ss_dead() - server-specific dead process handler
+**
+** should only be called from tet_si_service() when a server dies
+** unexpectedly
+**
+** server logoff routines do not come here
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_dead(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_dead(pp)
+struct ptab *pp;
+#endif
+{
+ /* emit a diagnostic if this is unexpected */
+ if ((pp->pt_flags & PF_LOGGEDOFF) == 0)
+ error(0, "server connection closed", tet_r2a(&pp->pt_rid));
+
+ pp->pt_flags = (pp->pt_flags & ~PF_LOGGEDON) | PF_LOGGEDOFF;
+}
+
+/*
+** tet_ss_connect() - connect to remote process
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_connect(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_connect(pp)
+struct ptab *pp;
+#endif
+{
+ tet_ts_connect(pp);
+}
+
+/*
+** tet_ss_ptalloc(), tet_ss_ptfree() - allocate and free server-specific
+** ptab data area
+**
+** tcm does not make use of server-specific data
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_ptalloc(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_ptalloc(pp)
+struct ptab *pp;
+#endif
+{
+ pp->pt_sdata = (char *) 0;
+ return(0);
+}
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_ptfree(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_ptfree(pp)
+struct ptab *pp;
+#endif
+{
+ /* nothing */
+}
+
+/*
+** tet_ss_serverloop() - server-specific server loop
+**
+** this may be called from tet_si_servwait() if non-blocking message i/o
+** would block
+**
+** tcm does not do non-blocking i/o, so this should never occur
+*/
+
+TET_EXPORT int tet_ss_serverloop PROTOLIST((void))
+{
+ error(0, "internal error - serverloop called!", (char *) 0);
+ return(-1);
+}
+
+/*
+** tet_ss_process() - server-specific request process routine
+**
+** would be called from tet_si_service() when state is PS_PROCESS
+**
+** tcm only uses tet_si_clientloop() which itself returns as soon as a
+** process reaches this state, so tet_ss_process() should never be called
+**/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_process(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_process(pp)
+struct ptab *pp;
+#endif
+{
+ error(0, "internal error - tet_ss_process called!",
+ tet_r2a(&pp->pt_rid));
+}
+
+/*
+ * The following functions are simply wrappers for the real functions
+ * in tcm_bs.c, tcm_in.c and tcm_xt.c. This is done so that tccd, xresd
+ * and syncd cannot resolve these symbols in libapi.a.
+ */
+
+extern int tet_tcm_bs2md PROTOLIST((char *, struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_bs2md(char *from, struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_bs2md(from, pp)
+char *from;
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_bs2md(from, pp);
+}
+
+extern int tet_tcm_md2bs PROTOLIST((struct ptab *, char **, int *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_md2bs(struct ptab *pp, char **bp, int *lp, int offs)
+#else
+TET_EXPORT int tet_ss_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+#endif
+{
+ return tet_tcm_md2bs(pp, bp, lp, offs);
+}
+
+extern int tet_tcm_tsconnect PROTOLIST((struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsconnect(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_tsconnect(pp)
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_tsconnect(pp);
+}
+
+extern int tet_tcm_tsinfo PROTOLIST((struct ptab *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsinfo(struct ptab *pp, int ptype)
+#else
+TET_EXPORT int tet_ss_tsinfo(pp, ptype)
+struct ptab *pp;
+int ptype;
+#endif
+{
+ return tet_tcm_tsinfo(pp, ptype);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* -END-LITE-CUT- */
+
diff --git a/src/tet3/tcm/tcm_bs.c b/src/tet3/tcm/tcm_bs.c
new file mode 100644
index 00000000..6abe7566
--- /dev/null
+++ b/src/tet3/tcm/tcm_bs.c
@@ -0,0 +1,226 @@
+/*
+ * SCCS: @(#)tcm_bs.c 1.11 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcm_bs.c 1.11 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcm_bs.c 1.11 98/09/01 TETware release 3.3
+NAME: tcm_bs.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ tcm-specific functions to convert DTET interprocess messages between
+ machine-independent and internal format
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ added support for OP_TIME
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ added support for OP_XRSEND
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ added support for OP_PUTENV
+
+
+************************************************************************/
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "ptab.h"
+#include "error.h"
+#include "valmsg.h"
+#include "avmsg.h"
+#include "server_bs.h"
+#include "dtetlib.h"
+#include "tcmfuncs.h"
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+static char reqerr[] = "unknown request code";
+
+/*
+** tet_tcm_bs2md() - convert message data to internal format
+**
+** return length of internal-format message, or -ve error code on error
+*/
+
+int tet_tcm_bs2md(from, pp)
+char *from;
+register struct ptab *pp;
+{
+ register int rc;
+ register int request = pp->pt_savreq;
+
+ switch (request) {
+ case OP_EXEC:
+ case OP_WAIT:
+ case OP_KILL:
+ case OP_XROPEN:
+ case OP_SNGET:
+ case OP_FOPEN:
+ case OP_TIME:
+ rc = tet_bs2valmsg(from, pp->ptm_len,
+ (struct valmsg **) &pp->ptm_data, &pp->pt_mdlen);
+ break;
+ case OP_ASYNC:
+ case OP_USYNC:
+ rc = tet_bs2synmsg(from, pp->ptm_len,
+ (struct valmsg **) &pp->ptm_data, &pp->pt_mdlen);
+ break;
+ case OP_RCFNAME:
+ case OP_GETS:
+ case OP_RCVCONF:
+ case OP_SHARELOCK:
+ rc = tet_bs2avmsg(from, pp->ptm_len,
+ (struct avmsg **) &pp->ptm_data, &pp->pt_mdlen);
+ break;
+ default:
+ error(0, reqerr, tet_ptreqcode(request));
+ return(ER_REQ);
+ }
+
+ return(rc < 0 ? ER_ERR : rc);
+}
+
+/*
+** tet_tcm_md2bs() - convert message data to machine-independent format
+**
+** return length of machine-independent message
+** or -ve error code on error
+*/
+
+int tet_tcm_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+{
+ register char *mp = pp->ptm_data;
+ register int request = pp->ptm_req;
+ register int len, rc;
+
+ /* calculate outgoing data size */
+ switch (request) {
+ case OP_SYSID:
+ case OP_SYSNAME:
+ case OP_SNSYS:
+ case OP_XRSYS:
+ case OP_XRSEND:
+ case OP_ICSTART:
+ case OP_TPSTART:
+ case OP_ICEND:
+ case OP_TPEND:
+ case OP_RESULT:
+ case OP_FCLOSE:
+ case OP_GETS:
+ case OP_WAIT:
+ case OP_KILL:
+ len = VM_VALMSGSZ(((struct valmsg *) mp)->vm_nvalue);
+ break;
+ case OP_ASYNC:
+ case OP_USYNC:
+ len = VM_SYNMSGSZ(((struct valmsg *) mp)->vm_nvalue, VM_MSDLEN((struct valmsg *) mp));
+ break;
+ case OP_TRACE:
+ case OP_EXEC:
+ case OP_XROPEN:
+ case OP_XRES:
+ case OP_FOPEN:
+ case OP_CFNAME:
+ case OP_SNDCONF:
+ case OP_CONFIG:
+ case OP_LOCKFILE:
+ case OP_SHARELOCK:
+ case OP_PUTENV:
+#if TESTING
+ case OP_PRINT:
+#endif
+ len = tet_avmsgbslen((struct avmsg *) mp);
+ break;
+ case OP_TSINFO:
+ len = tet_tcm_ts_tsinfolen();
+ break;
+ default:
+ error(0, reqerr, tet_ptreqcode(request));
+ return(ER_REQ);
+ }
+
+ /* make sure that the receiving area is big enough */
+ if (BUFCHK(bp, lp, len + offs) < 0)
+ return(ER_ERR);
+
+ /* copy the data to (*bp + offs) */
+ switch (request) {
+ case OP_SYSID:
+ case OP_SYSNAME:
+ case OP_SNSYS:
+ case OP_XRSEND:
+ case OP_XRSYS:
+ case OP_ICSTART:
+ case OP_TPSTART:
+ case OP_ICEND:
+ case OP_TPEND:
+ case OP_RESULT:
+ case OP_FCLOSE:
+ case OP_GETS:
+ case OP_WAIT:
+ case OP_KILL:
+ rc = tet_valmsg2bs((struct valmsg *) mp, *bp + offs);
+ break;
+ case OP_ASYNC:
+ case OP_USYNC:
+ rc = tet_synmsg2bs((struct valmsg *) mp, *bp + offs);
+ break;
+ case OP_EXEC:
+ case OP_TRACE:
+ case OP_XROPEN:
+ case OP_XRES:
+ case OP_FOPEN:
+ case OP_CFNAME:
+ case OP_SNDCONF:
+ case OP_CONFIG:
+ case OP_LOCKFILE:
+ case OP_SHARELOCK:
+ case OP_PUTENV:
+#if TESTING
+ case OP_PRINT:
+#endif
+ rc = tet_avmsg2bs((struct avmsg *) mp, *bp + offs);
+ break;
+ case OP_TSINFO:
+ rc = tet_tcm_ts_tsinfo2bs(mp, *bp + offs);
+ break;
+ default:
+ error(0, reqerr, tet_ptreqcode(request));
+ return(ER_REQ);
+ }
+
+ return(rc < 0 ? ER_ERR : rc);
+}
+
diff --git a/src/tet3/tcm/tcm_in.c b/src/tet3/tcm/tcm_in.c
new file mode 100644
index 00000000..7290e9e2
--- /dev/null
+++ b/src/tet3/tcm/tcm_in.c
@@ -0,0 +1,305 @@
+/*
+ * SCCS: @(#)tcm_in.c 1.13 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcm_in.c 1.13 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcm_in.c 1.13 98/09/01 TETware release 3.3
+NAME: tcm_in.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ client-specific functions for tcm INET version
+
+MODIFICATIONS:
+ Denis McConalogue, UniSoft Limited, August 1993
+ Make sure the loopback address is not put in the tsinfo message
+ when the message destination is a different machine.
+
+ Andrew Dingwall, UniSoft Ltd., December 1993
+ added ptm_mtype assignment
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+
+ Andrew Dingwall, UniSoft Ltd., March 1997
+ remove #ifndef __hpux from #include <arpa/inet.h>
+ since current HP-UX implementations now have this file
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+ Changes for conformance with UNIX98.
+
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+# include <netinet/in.h>
+# include <sys/uio.h>
+# include <sys/socket.h>
+# include <arpa/inet.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "ptab.h"
+#include "tptab_in.h"
+#include "tsinfo_in.h"
+#include "error.h"
+#include "globals.h"
+#include "server.h"
+#include "tcmfuncs.h"
+#include "dtetlib.h"
+#include "inetlib_in.h"
+
+#ifndef NOTRACE
+#include "ltoa.h"
+#endif
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+
+/* static function declarations */
+static void storetsinfo PROTOLIST((char *, struct ptab **, int));
+
+
+/*
+** tet_ts_tcminit() - tcm transport-specific environment argument
+** processing
+*/
+
+void tet_ts_tcminit()
+{
+ register char **ap;
+ register char *envstring, *p;
+ char **args;
+ register int nargs;
+ static char envname[] = "TET_TSARGS";
+
+ /* get the dtet ts args out of the environment and count them */
+ if ((envstring = getenv(envname)) == (char *) 0 || !*envstring)
+ fatal(0, envname, "null or not set");
+ nargs = 1;
+ for (p = envstring; *p; p++)
+ if (isspace(*p))
+ nargs++;
+
+ /* allocate some space for argument pointers */
+ errno = 0;
+ if ((args = (char **) malloc(nargs * sizeof *args)) == (char **) 0)
+ fatal(errno, "can't get memory for arg list", (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate ts env args = %s", tet_i2x(args));
+
+ /* split the arg string into fields */
+ nargs = tet_getargs(envstring, args, nargs);
+
+ /* process each argument in turn */
+ for (ap = args; nargs > 0; ap++, nargs--) {
+ if (*(p = *ap) != '-')
+ continue;
+ switch (*++p) {
+ case 'x':
+ storetsinfo(*ap, &tet_xdptab, PT_XRESD);
+ break;
+ case 'y':
+ storetsinfo(*ap, &tet_sdptab, PT_SYNCD);
+ break;
+ default:
+ fatal(0, "bad ts env argument", *ap);
+ /* NOTREACHED */
+ }
+ }
+
+ TRACE2(tet_Tbuf, 6, "free ts env args = %s", tet_i2x(args));
+ free((char *) args);
+}
+
+/*
+** storetsinfo() - store ts info for server process
+**
+** the ts info is stored indirectly through *paddr
+*/
+
+static void storetsinfo(arg, paddr, ptype)
+char *arg;
+struct ptab **paddr;
+int ptype;
+{
+ register struct ptab *pp;
+ register struct tptab *tp;
+ register char *addr, *port;
+
+ /* make addr point to the INET address string
+ and port to the port string */
+ addr = arg + 2;
+ for (port = addr; *port; port++)
+ if (*port == ',') {
+ *port++ = '\0';
+ break;
+ }
+ if (!*addr || !*port)
+ fatal(0, "bad ts env arg format:", arg);
+
+ /* get a ptab structure and fill it in */
+ if ((pp = tet_ptalloc()) == (struct ptab *) 0)
+ exit(1);
+ pp->ptr_sysid = 0;
+ pp->ptr_ptype = ptype;
+ pp->pt_flags = PF_SERVER;
+ tp = (struct tptab *) pp->pt_tdata;
+
+ /* fill in the INET address structure */
+ tp->tp_sin.sin_family = AF_INET;
+ if ((tp->tp_sin.sin_addr.s_addr = inet_addr(addr)) == -1) {
+ *(port - 1) = ',';
+ fatal(0, "bad format INET address:", arg);
+ }
+ if ((tp->tp_sin.sin_port = htons((unsigned short) atoi(port))) == 0) {
+ *(port - 1) = ',';
+ fatal(0, "bad port number:", arg);
+ }
+
+ *paddr = pp;
+}
+
+/*
+** tet_tcm_tsconnect() - server-specific connect processing
+**
+** return 0 if successful or -1 on error
+*/
+
+int tet_tcm_tsconnect(pp)
+struct ptab *pp;
+{
+ switch (pp->ptr_ptype) {
+ case PT_SYNCD:
+ if (tet_sdptab)
+ return(0);
+ break;
+ case PT_XRESD:
+ if (tet_xdptab)
+ return(0);
+ break;
+ case PT_STCC:
+ return(tet_gettccdaddr(pp));
+ }
+
+ error(0, "don't know how to connect to", tet_ptptype(pp->ptr_ptype));
+ return(-1);
+}
+
+/*
+** tet_tcm_tsinfo() - construct a tsinfo message relating to a server
+** process
+**
+** return 0 if successful or -1 on error
+*/
+
+int tet_tcm_tsinfo(pp, ptype)
+struct ptab *pp;
+register int ptype;
+{
+ register struct tptab *tp;
+ register struct tsinfo *mp;
+
+ struct in_addr *ap;
+ char hostname[SNAMELEN];
+
+ if ((mp = (struct tsinfo *) tet_ti_msgbuf(pp, sizeof *mp)) == (struct tsinfo *) 0)
+ return(-1);
+
+ /* make tp point to the tptab for the server -
+ tet_sdptab and tet_xdptab were set up if the corresponding
+ arguments were in the TET_TSARGS environment variable */
+ tp = (struct tptab *) 0;
+ switch (ptype) {
+ case PT_SYNCD:
+ if (tet_sdptab)
+ tp = (struct tptab *) tet_sdptab->pt_tdata;
+ break;
+ case PT_XRESD:
+ if (tet_xdptab)
+ tp = (struct tptab *) tet_xdptab->pt_tdata;
+ break;
+ }
+
+ if (!tp) {
+ error(0, "no tsinfo for", tet_ptptype(ptype));
+ return(-1);
+ }
+
+ /* all ok so copy over the data and return */
+ mp->ts_ptype = ptype;
+ mp->ts_port = ntohs(tp->tp_sin.sin_port);
+
+ /*
+ ** on system 0 we talk to syncd and xresd using the loopback address,
+ ** so that is what is stored in the tptab structure;
+ ** if the message destination is also localhost, simply copy the
+ ** stored (localhost) address -
+ ** otherwise, the destination is on another machine so find our
+ ** (external) Internet address and use that
+ */
+ if (
+ tet_mysysid == 0 &&
+ ((struct tptab *) pp->pt_tdata)->tp_sin.sin_addr.s_addr !=
+ tp->tp_sin.sin_addr.s_addr
+ ) {
+ if (gethostname(hostname, sizeof hostname) < 0) {
+ error(SOCKET_ERRNO, "gethostname() failed", (char *) 0);
+ return(-1);
+ }
+ if ((ap = tet_gethostaddr(hostname)) == (struct in_addr *) 0)
+ return(-1);
+ mp->ts_addr = ntohl(ap->s_addr);
+ }
+ else
+ mp->ts_addr = ntohl(tp->tp_sin.sin_addr.s_addr);
+
+ pp->ptm_mtype = MT_TSINFO_IN;
+ pp->ptm_len = sizeof *mp;
+ return(0);
+}
+
+/*
+** tet_tcm_ts_tsinfolen() - return length of a machine-independent
+** tsinfo structure
+*/
+
+int tet_tcm_ts_tsinfolen()
+{
+ return(TS_TSINFOSZ);
+}
+
+/*
+** tet_tcm_ts_tsinfo2bs() - call tet_tsinfo2bs()
+*/
+
+int tet_tcm_ts_tsinfo2bs(from, to)
+char *from, *to;
+{
+ return(tet_tsinfo2bs((struct tsinfo *) from, to));
+}
+
diff --git a/src/tet3/tcm/tcm_xt.c b/src/tet3/tcm/tcm_xt.c
new file mode 100644
index 00000000..c36a8f21
--- /dev/null
+++ b/src/tet3/tcm/tcm_xt.c
@@ -0,0 +1,322 @@
+/*
+ * SCCS: @(#)tcm_xt.c 1.8 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1993 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcm_xt.c 1.8 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcm_xt.c 1.8 98/09/01 TETware release 3.3
+NAME: tcm_xt.c
+PRODUCT: TETware
+AUTHOR: Denis McConalogue, UniSoft Ltd.
+DATE CREATED: April 1993
+
+DESCRIPTION:
+ client-specific functions for tcm XTI version
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd., December 1993
+ added malloc tracing
+ added ptm_mtype assignment
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <xti.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "ptab.h"
+#include "tptab_xt.h"
+#include "error.h"
+#include "ltoa.h"
+#include "server.h"
+#include "tcmfuncs.h"
+#include "dtetlib.h"
+#include "xtilib_xt.h"
+#include "tsinfo_xt.h"
+
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+
+/* global variables */
+TET_EXPORT int tet_tpi_mode = -1; /* transport provider mode */
+TET_EXPORT char *tet_tpname = (char *) 0;
+ /* transport provider name */
+
+
+/* static function declarations */
+static void storetsinfo PROTOLIST((char *, struct ptab **, int));
+
+
+/*
+** tet_ts_tcminit() - tcm transport-specific environment argument
+** processing
+*/
+
+void tet_ts_tcminit()
+{
+ register char **ap;
+ register char *envstring, *p;
+ char **args;
+ register int nargs;
+ static char envname[] = "TET_TSARGS";
+
+ /* get the dtet ts args out of the environment and count them */
+ if ((envstring = getenv(envname)) == (char *) 0 || !*envstring)
+ fatal(0, envname, "null or not set");
+ nargs = 1;
+ for (p = envstring; *p; p++)
+ if (isspace(*p))
+ nargs++;
+
+ /* allocate some space for argument pointers */
+ errno = 0;
+ if ((args = (char **) malloc(nargs * sizeof *args)) == (char **) 0)
+ fatal(errno, "can't get memory for arg list", (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate ts env args = %s", tet_i2x(args));
+
+ /* split the arg string into fields */
+ nargs = tet_getargs(envstring, args, nargs);
+
+ /* process each argument in turn */
+ for (ap = args; nargs > 0; ap++, nargs--) {
+ if (*(p = *ap) != '-')
+ continue;
+ switch (*++p) {
+ case 'x':
+ storetsinfo(*ap, &tet_xdptab, PT_XRESD);
+ break;
+ case 'y':
+ storetsinfo(*ap, &tet_sdptab, PT_SYNCD);
+ break;
+ case 'M':
+ tet_tpi_mode = atoi(*ap+2);
+ break;
+ case 'P':
+ tet_tpname = tet_strstore(*ap+2);
+ break;
+ default:
+ fatal(0, "bad ts env argument", *ap);
+ /* NOTREACHED */
+ }
+ }
+
+ TRACE2(tet_Tbuf, 6, "free ts env args = %s", tet_i2x(args));
+ free((char *) args);
+}
+
+/*
+** storetsinfo() - store ts info for server process
+**
+** the ts info is stored indirectly through *paddr
+*/
+
+static void storetsinfo(arg, paddr, ptype)
+char *arg;
+struct ptab **paddr;
+int ptype;
+{
+ register struct ptab *pp;
+ register struct tptab *tp;
+ register char *addr;
+ register struct netbuf *np;
+
+ /* make addr point to the XTI address string */
+ addr = arg + 2;
+ if (!*addr)
+ fatal(0, "bad ts env arg format", arg);
+
+ /* get a ptab structure and fill it in */
+ if ((pp = tet_ptalloc()) == (struct ptab *) 0)
+ exit(1);
+
+ pp->ptr_sysid = 0;
+ pp->ptr_ptype = ptype;
+ pp->pt_flags = PF_SERVER;
+ tp = (struct tptab *) pp->pt_tdata;
+
+ /* fill in the XTI address structure */
+ if ((np = tet_lname2addr(addr)) == (struct netbuf *)0)
+ fatal(0, "bad format XTI address", arg);
+
+ errno = 0;
+ if ((tp->tp_call.buf = (char *) malloc(np->maxlen)) == (char *) 0)
+ fatal(errno, "can't allocate address buffer", (char *) 0);
+
+ TRACE2(tet_Tbuf, 6, "allocate tp_call.buf = %s",
+ tet_i2x(tp->tp_call.buf));
+
+ tp->tp_call.maxlen = np->maxlen;
+ tp->tp_call.len = np->len;
+ (void) memcpy(tp->tp_call.buf, np->buf, np->len);
+
+ *paddr = pp;
+}
+
+/*
+** tet_tcm_tsconnect() - server-specific connect processing
+**
+** return 0 if successful or -1 on error
+*/
+
+int tet_tcm_tsconnect(pp)
+struct ptab *pp;
+{
+ switch (pp->ptr_ptype) {
+ case PT_SYNCD:
+ if (tet_sdptab)
+ return(0);
+ break;
+ case PT_XRESD:
+ if (tet_xdptab)
+ return(0);
+ break;
+ case PT_STCC:
+ return(tet_gettccdaddr(pp));
+ }
+
+ error(0, "don't know how to connect to", tet_ptptype(pp->ptr_ptype));
+ return(-1);
+}
+
+/*
+** tet_tcm_tsinfo() - construct a tsinfo message relating to a server
+** process
+**
+** return 0 if successful or -1 on error
+*/
+
+int tet_tcm_tsinfo(pp, ptype)
+struct ptab *pp;
+register int ptype;
+{
+ register struct tptab *tp;
+ register struct tsinfo *mp;
+ extern int tet_tpi_mode;
+
+ if ((mp = (struct tsinfo *) tet_ti_msgbuf(pp, sizeof *mp)) == (struct tsinfo *) 0)
+ return(-1);
+
+ /* make tp point to the tptab for the server -
+ tet_sdptab and tet_xdptab were set up if the corresponding
+ arguments were in the TET_TSARGS environment variable */
+ tp = (struct tptab *) 0;
+ switch (ptype) {
+ case PT_SYNCD:
+ if (tet_sdptab)
+ tp = (struct tptab *) tet_sdptab->pt_tdata;
+ break;
+ case PT_XRESD:
+ if (tet_xdptab)
+ tp = (struct tptab *) tet_xdptab->pt_tdata;
+ break;
+ }
+
+ if (!tp) {
+ error(0, "no tsinfo for", tet_ptptype(ptype));
+ return(-1);
+ }
+
+ mp->ts_ptype = ptype;
+
+ /* all ok so copy over the data and return */
+ switch (tet_tpi_mode) {
+#ifdef TCPTPI
+ case TPI_TCP:
+
+ mp->ts.inet.ts_addr =
+ ntohl(((struct sockaddr_in *)tp->tp_call.buf)->sin_addr.s_addr);
+ mp->ts.inet.ts_port =
+ ntohs(((struct sockaddr_in *)tp->tp_call.buf)->sin_port);
+
+ break;
+
+#endif
+#ifdef OSITPI
+ case TPI_OSICO:
+
+ if (tp->tp_call.len > sizeof (mp->ts.osico.ts_nsap)) {
+ error(0, "address too big for tsinfo buffer", (char *)0);
+ return (-1);
+ }
+ mp->ts.osico.ts_len = tp->tp_call.len;
+ (void) memcpy(mp->ts.osico.ts_nsap, tp->tp_call.buf, tp->tp_call.len);
+
+ break;
+#endif
+ default:
+ fatal(0,"invalid tet_tpi_mode or not supported", tet_i2a(tet_tpi_mode));
+ /* NOTREACHED */
+ }
+
+ pp->ptm_mtype = MT_TSINFO_XT;
+ pp->ptm_len = sizeof *mp;
+ return(0);
+}
+
+/*
+** tet_tcm_ts_tsinfolen() - return length of a machine-independent tsinfo
+** structure
+*/
+
+int tet_tcm_ts_tsinfolen()
+{
+ switch (tet_tpi_mode) {
+#ifdef TCPTPI
+ case TPI_TCP:
+
+ return(TS_INET_TSINFOSZ);
+ break;
+#endif
+#ifdef OSITPI
+ case TPI_OSICO:
+
+ return(TS_OSICO_TSINFOSZ);
+ break;
+#endif
+ default:
+ fatal(0,"invalid tet_tpi_mode, or not supported", (char *)0);
+ /* NOTREACHED */
+ }
+}
+
+/*
+** tet_tcm_ts_tsinfo2bs() - call tet_tsinfo2bs()
+*/
+
+int tet_tcm_ts_tsinfo2bs(from, to)
+char *from, *to;
+{
+ return(tet_tsinfo2bs((struct tsinfo *) from, to));
+}
+
diff --git a/src/tet3/tcm/tcmchild.c b/src/tet3/tcm/tcmchild.c
new file mode 100644
index 00000000..8d601af0
--- /dev/null
+++ b/src/tet3/tcm/tcmchild.c
@@ -0,0 +1,376 @@
+/*
+ * SCCS: @(#)tcmchild.c 1.13 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcmchild.c 1.13 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcmchild.c 1.13 98/09/01 TETware release 3.3
+NAME: tcmchild.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: October 1992
+
+DESCRIPTION:
+ tcm main() and client-related functions for processes
+ started by tet_exec() and tet_spawn()
+
+MODIFICATIONS:
+ Denis McConalogue, UniSoft Limited, September 1993
+ changed tet_tcmptype() to set process type PT_MTCM for
+ non-distributed test cases executing on remote or
+ local systems.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for TETware
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ changes for TETware-Lite
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+ (this file was ctcmfuncs.c - moved main() and other things here)
+
+ Andrew Dingwall, UniSoft Ltd., April 1997
+ initialise tet_pname in case it gets used (in tet_dtcmerror())
+ before it can be set up in tet_tcm*_main()
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+ Note that this includes a change to the calling convention for
+ child processes.
+
+************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+# include <signal.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "globals.h"
+#include "tcmfuncs.h"
+#include "error.h"
+#ifndef TET_LITE /* -START-LITE-CUT- */
+# include "ptab.h"
+# include "synreq.h"
+# include "server.h"
+# include "tslib.h"
+# include "servlib.h"
+#endif /* -END-LITE-CUT- */
+#include "dtetlib.h"
+#include "sigsafe.h"
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__;
+#endif
+
+extern int tet_tcmc_main PROTOLIST((int, char **));
+extern void tet_dtcmerror PROTOLIST((int, char *, int, char *, char *));
+
+TET_EXPORT char *tet_pname = "<unknown>";
+TET_EXPORT int tet_thistest = -1;
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+int tet_psysid = -1; /* parent's system id */
+TET_EXPORT long tet_snid = -1L; /* sync id */
+TET_EXPORT long tet_xrid = -1L; /* xres id */
+TET_EXPORT int *tet_snames; /* system name list */
+TET_EXPORT int tet_Nsname; /* number of system names */
+TET_EXPORT struct ptab *tet_sdptab, *tet_xdptab;
+ /* ptab elements for syncd and xresd */
+#endif /* -END-LITE-CUT- */
+
+TET_EXPORT sigset_t tet_blockable_sigs;
+
+#ifdef TET_THREADS
+TET_EXPORT tet_thread_t tet_start_tid;
+#endif /* TET_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+** main() is the main program for processes started by tet_exec().
+** It is simply a wrapper for tet_tcmc_main().
+*/
+
+#ifdef PROTOTYPES
+int main(int argc, char **argv)
+#else
+int main(argc, argv)
+int argc;
+char **argv;
+#endif
+{
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define MYPTYPE PT_MTCM
+# define MYSYSID 0
+#else /* -START-LITE-CUT- */
+# define MYPTYPE -1
+# define MYSYSID -1
+#endif /* -END-LITE-CUT- */
+
+ /* must be first */
+ tet_init_globals(argc > 0 ? tet_basename(*argv) : (char *) "child process controller",
+ MYPTYPE, MYSYSID, tet_dtcmerror, tet_genfatal);
+
+ /*
+ ** make sure that we are linked with the right version of
+ ** the API library
+ */
+ tet_check_apilib_version();
+
+
+ return tet_tcmc_main(argc, argv);
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+/*
+** tet_tcm_async() - dummy auto-sync function for child TCMs
+**
+** child TCMs do not do auto-syncs, so this function should only be
+** called with spno == SV_EXEC_SPNO from tet_tcminit()
+*/
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT int tet_tcm_async(long spno, int vote, int timeout,
+ struct synreq *synreq, int *nsys)
+#else
+TET_EXPORT int tet_tcm_async(spno, vote, timeout, synreq, nsys)
+long spno;
+int vote, timeout, *nsys;
+struct synreq *synreq;
+#endif
+{
+ ASSERT(spno == SV_EXEC_SPNO);
+
+ tet_sderrno = ER_OK;
+ return(0);
+}
+
+/*
+** tet_tcmptype() - return process type for a TCM
+**
+** In TETware there is almost no difference between "master" and
+** "slave" TCMs and this function is only used to decide which
+** TCMs in a distributed test case should inform XRESD of IC and
+** TP start and end.
+** Someone has to do it so it might as well be the first (or only)
+** system in the system list.
+*/
+
+int tet_tcmptype PROTOLIST((void))
+{
+ int sys1;
+
+ sys1 = tet_snames ? *tet_snames : -1;
+
+ return (tet_mysysid == sys1 ? PT_MTCM : PT_STCM);
+}
+
+/*
+** tet_ss_dead() - server-specific dead process handler
+**
+** should only be called from tet_si_service() when a server dies
+** unexpectedly
+**
+** server logoff routines do not come here
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_dead(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_dead(pp)
+struct ptab *pp;
+#endif
+{
+ /* emit a diagnostic if this is unexpected */
+ if ((pp->pt_flags & PF_LOGGEDOFF) == 0)
+ error(0, "server connection closed", tet_r2a(&pp->pt_rid));
+
+ pp->pt_flags = (pp->pt_flags & ~PF_LOGGEDON) | PF_LOGGEDOFF;
+}
+
+/*
+** tet_ss_connect() - connect to remote process
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_connect(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_connect(pp)
+struct ptab *pp;
+#endif
+{
+ tet_ts_connect(pp);
+}
+
+/*
+** tet_ss_ptalloc(), tet_ss_ptfree() - allocate and free server-specific
+** ptab data area
+**
+** tcm does not make use of server-specific data
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_ptalloc(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_ptalloc(pp)
+struct ptab *pp;
+#endif
+{
+ pp->pt_sdata = (char *) 0;
+ return(0);
+}
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_ptfree(struct ptab *pp)
+#else
+void tet_ss_ptfree(pp)
+struct ptab *pp;
+#endif
+{
+ /* nothing */
+}
+
+/*
+** tet_ss_serverloop() - server-specific server loop
+**
+** this may be called from tet_si_servwait() if non-blocking message i/o
+** would block
+**
+** tcm does not do non-blocking i/o, so this should never occur
+*/
+
+TET_EXPORT int tet_ss_serverloop PROTOLIST((void))
+{
+ error(0, "internal error - serverloop called!", (char *) 0);
+ return(-1);
+}
+
+/*
+** tet_ss_process() - server-specific request process routine
+**
+** would be called from tet_si_service() when state is PS_PROCESS
+**
+** tcm only uses tet_si_clientloop() which itself returns as soon as a
+** process reaches this state, so tet_ss_process() should never be called
+**/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_process(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_process(pp)
+struct ptab *pp;
+#endif
+{
+ error(0, "internal error - tet_ss_process called!",
+ tet_r2a(&pp->pt_rid));
+}
+
+/*
+ * The following functions are simply wrappers for the real functions
+ * in tcm_bs.c, tcm_in.c and tcm_xt.c. This is done so that tccd, xresd
+ * and syncd cannot resolve these symbols in libapi.a.
+ */
+
+extern int tet_tcm_bs2md PROTOLIST((char *, struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_bs2md(char *from, struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_bs2md(from, pp)
+char *from;
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_bs2md(from, pp);
+}
+
+extern int tet_tcm_md2bs PROTOLIST((struct ptab *pp, char **bp, int *lp,
+ int offs));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_md2bs(struct ptab *pp, char **bp, int *lp, int offs)
+#else
+TET_EXPORT int tet_ss_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+#endif
+{
+ return tet_tcm_md2bs(pp, bp, lp, offs);
+}
+
+extern int tet_tcm_tsconnect PROTOLIST((struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsconnect(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_tsconnect(pp)
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_tsconnect(pp);
+}
+
+extern int tet_tcm_tsinfo PROTOLIST((struct ptab *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsinfo(struct ptab *pp, int ptype)
+#else
+TET_EXPORT int tet_ss_tsinfo(pp, ptype)
+struct ptab *pp;
+int ptype;
+#endif
+{
+ return tet_tcm_tsinfo(pp, ptype);
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_callfuncname() - return name of tcmchild's calling function
+** for use in error messages
+*/
+
+char *tet_callfuncname PROTOLIST((void))
+{
+ return("tet_exec() or tet_spawn()");
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/tet3/tcm/tcmchild.c.orig b/src/tet3/tcm/tcmchild.c.orig
new file mode 100644
index 00000000..87c1a905
--- /dev/null
+++ b/src/tet3/tcm/tcmchild.c.orig
@@ -0,0 +1,376 @@
+/*
+ * SCCS: @(#)tcmchild.c 1.13 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcmchild.c 1.13 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcmchild.c 1.13 98/09/01 TETware release 3.3
+NAME: tcmchild.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: October 1992
+
+DESCRIPTION:
+ tcm main() and client-related functions for processes
+ started by tet_exec() and tet_spawn()
+
+MODIFICATIONS:
+ Denis McConalogue, UniSoft Limited, September 1993
+ changed tet_tcmptype() to set process type PT_MTCM for
+ non-distributed test cases executing on remote or
+ local systems.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for TETware
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ changes for TETware-Lite
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+ (this file was ctcmfuncs.c - moved main() and other things here)
+
+ Andrew Dingwall, UniSoft Ltd., April 1997
+ initialise tet_pname in case it gets used (in tet_dtcmerror())
+ before it can be set up in tet_tcm*_main()
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+ Note that this includes a change to the calling convention for
+ child processes.
+
+************************************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+# include <signal.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "dtthr.h"
+#include "globals.h"
+#include "tcmfuncs.h"
+#include "error.h"
+#ifndef TET_LITE /* -START-LITE-CUT- */
+# include "ptab.h"
+# include "synreq.h"
+# include "server.h"
+# include "tslib.h"
+# include "servlib.h"
+#endif /* -END-LITE-CUT- */
+#include "dtetlib.h"
+#include "sigsafe.h"
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__;
+#endif
+
+extern int tet_tcmc_main PROTOLIST((int, char **));
+extern void tet_dtcmerror PROTOLIST((int, char *, int, char *, char *));
+
+TET_EXPORT char *tet_pname = "<unknown>";
+TET_EXPORT int tet_thistest = -1;
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+int tet_psysid = -1; /* parent's system id */
+TET_EXPORT long tet_snid = -1L; /* sync id */
+TET_EXPORT long tet_xrid = -1L; /* xres id */
+TET_EXPORT int *tet_snames; /* system name list */
+TET_EXPORT int tet_Nsname; /* number of system names */
+TET_EXPORT struct ptab *tet_sdptab, *tet_xdptab;
+ /* ptab elements for syncd and xresd */
+#endif /* -END-LITE-CUT- */
+
+TET_EXPORT sigset_t tet_blockable_sigs;
+
+#ifdef TET_THREADS
+TET_EXPORT tet_thread_t tet_start_tid;
+#endif /* TET_THREADS */
+
+#ifdef __cplusplus
+}
+#endif
+
+/*
+** main() is the main program for processes started by tet_exec().
+** It is simply a wrapper for tet_tcmc_main().
+*/
+
+#ifdef PROTOTYPES
+int main(int argc, char **argv)
+#else
+int main(argc, argv)
+int argc;
+char **argv;
+#endif
+{
+
+#ifdef TET_LITE /* -LITE-CUT-LINE- */
+# define MYPTYPE PT_MTCM
+# define MYSYSID 0
+#else /* -START-LITE-CUT- */
+# define MYPTYPE -1
+# define MYSYSID -1
+#endif /* -END-LITE-CUT- */
+
+ /* must be first */
+ tet_init_globals(argc > 0 ? tet_basename(*argv) : "child process controller",
+ MYPTYPE, MYSYSID, tet_dtcmerror, tet_genfatal);
+
+ /*
+ ** make sure that we are linked with the right version of
+ ** the API library
+ */
+ tet_check_apilib_version();
+
+
+ return tet_tcmc_main(argc, argv);
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+/*
+** tet_tcm_async() - dummy auto-sync function for child TCMs
+**
+** child TCMs do not do auto-syncs, so this function should only be
+** called with spno == SV_EXEC_SPNO from tet_tcminit()
+*/
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT int tet_tcm_async(long spno, int vote, int timeout,
+ struct synreq *synreq, int *nsys)
+#else
+TET_EXPORT int tet_tcm_async(spno, vote, timeout, synreq, nsys)
+long spno;
+int vote, timeout, *nsys;
+struct synreq *synreq;
+#endif
+{
+ ASSERT(spno == SV_EXEC_SPNO);
+
+ tet_sderrno = ER_OK;
+ return(0);
+}
+
+/*
+** tet_tcmptype() - return process type for a TCM
+**
+** In TETware there is almost no difference between "master" and
+** "slave" TCMs and this function is only used to decide which
+** TCMs in a distributed test case should inform XRESD of IC and
+** TP start and end.
+** Someone has to do it so it might as well be the first (or only)
+** system in the system list.
+*/
+
+int tet_tcmptype PROTOLIST((void))
+{
+ int sys1;
+
+ sys1 = tet_snames ? *tet_snames : -1;
+
+ return (tet_mysysid == sys1 ? PT_MTCM : PT_STCM);
+}
+
+/*
+** tet_ss_dead() - server-specific dead process handler
+**
+** should only be called from tet_si_service() when a server dies
+** unexpectedly
+**
+** server logoff routines do not come here
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_dead(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_dead(pp)
+struct ptab *pp;
+#endif
+{
+ /* emit a diagnostic if this is unexpected */
+ if ((pp->pt_flags & PF_LOGGEDOFF) == 0)
+ error(0, "server connection closed", tet_r2a(&pp->pt_rid));
+
+ pp->pt_flags = (pp->pt_flags & ~PF_LOGGEDON) | PF_LOGGEDOFF;
+}
+
+/*
+** tet_ss_connect() - connect to remote process
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_connect(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_connect(pp)
+struct ptab *pp;
+#endif
+{
+ tet_ts_connect(pp);
+}
+
+/*
+** tet_ss_ptalloc(), tet_ss_ptfree() - allocate and free server-specific
+** ptab data area
+**
+** tcm does not make use of server-specific data
+*/
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_ptalloc(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_ptalloc(pp)
+struct ptab *pp;
+#endif
+{
+ pp->pt_sdata = (char *) 0;
+ return(0);
+}
+
+/* ARGSUSED */
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_ptfree(struct ptab *pp)
+#else
+void tet_ss_ptfree(pp)
+struct ptab *pp;
+#endif
+{
+ /* nothing */
+}
+
+/*
+** tet_ss_serverloop() - server-specific server loop
+**
+** this may be called from tet_si_servwait() if non-blocking message i/o
+** would block
+**
+** tcm does not do non-blocking i/o, so this should never occur
+*/
+
+TET_EXPORT int tet_ss_serverloop PROTOLIST((void))
+{
+ error(0, "internal error - serverloop called!", (char *) 0);
+ return(-1);
+}
+
+/*
+** tet_ss_process() - server-specific request process routine
+**
+** would be called from tet_si_service() when state is PS_PROCESS
+**
+** tcm only uses tet_si_clientloop() which itself returns as soon as a
+** process reaches this state, so tet_ss_process() should never be called
+**/
+
+#ifdef PROTOTYPES
+TET_EXPORT void tet_ss_process(struct ptab *pp)
+#else
+TET_EXPORT void tet_ss_process(pp)
+struct ptab *pp;
+#endif
+{
+ error(0, "internal error - tet_ss_process called!",
+ tet_r2a(&pp->pt_rid));
+}
+
+/*
+ * The following functions are simply wrappers for the real functions
+ * in tcm_bs.c, tcm_in.c and tcm_xt.c. This is done so that tccd, xresd
+ * and syncd cannot resolve these symbols in libapi.a.
+ */
+
+extern int tet_tcm_bs2md PROTOLIST((char *, struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_bs2md(char *from, struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_bs2md(from, pp)
+char *from;
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_bs2md(from, pp);
+}
+
+extern int tet_tcm_md2bs PROTOLIST((struct ptab *pp, char **bp, int *lp,
+ int offs));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_md2bs(struct ptab *pp, char **bp, int *lp, int offs)
+#else
+TET_EXPORT int tet_ss_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+#endif
+{
+ return tet_tcm_md2bs(pp, bp, lp, offs);
+}
+
+extern int tet_tcm_tsconnect PROTOLIST((struct ptab *));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsconnect(struct ptab *pp)
+#else
+TET_EXPORT int tet_ss_tsconnect(pp)
+struct ptab *pp;
+#endif
+{
+ return tet_tcm_tsconnect(pp);
+}
+
+extern int tet_tcm_tsinfo PROTOLIST((struct ptab *, int));
+
+#ifdef PROTOTYPES
+TET_EXPORT int tet_ss_tsinfo(struct ptab *pp, int ptype)
+#else
+TET_EXPORT int tet_ss_tsinfo(pp, ptype)
+struct ptab *pp;
+int ptype;
+#endif
+{
+ return tet_tcm_tsinfo(pp, ptype);
+}
+
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_callfuncname() - return name of tcmchild's calling function
+** for use in error messages
+*/
+
+char *tet_callfuncname PROTOLIST((void))
+{
+ return("tet_exec() or tet_spawn()");
+}
+
+#ifdef __cplusplus
+}
+#endif
+
diff --git a/src/tet3/tcm/tcmfuncs.c b/src/tet3/tcm/tcmfuncs.c
new file mode 100644
index 00000000..b676ae08
--- /dev/null
+++ b/src/tet3/tcm/tcmfuncs.c
@@ -0,0 +1,408 @@
+/*
+ * SCCS: @(#)tcmfuncs.c 1.25 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcmfuncs.c 1.25 (98/09/01) TET3 release 3.3";
+static char *copyright[] = {
+ "(C) Copyright 1996 X/Open Company Limited",
+ "All rights reserved"
+};
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcmfuncs.c 1.25 98/09/01 TETware release 3.3
+NAME: tcmfuncs.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ generic tcm client-related functions
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd., October 1992
+ Set tet_progname to basename(argv[0]) so as to avoid long path names
+ in error messages.
+ Moved tet_tcmptype() call to after TET_TIARGS parsing so that tcmchild
+ processes can determine which system they are on.
+ Moved tet_root[] from dtcm.c to here so that it is available
+ to tcmchild processes as well.
+
+ Denis McConalogue, UniSoft Limited, September 1993
+ added ss_disconnect() function
+
+ Andrew Dingwall, UniSoft Ltd., December 1993
+ Removed disconnect stuff.
+ Changed dapi.h to dtet2/tet_api.h
+ Corrected error message when TET_ROOT is not set.
+
+ Andrew Dingwall, UniSoft Ltd., February 1994
+ replaced generror() with dtcmerror() as the error handler -
+ this sends TETware errors to tet_error() so they will probably
+ appear in the journal rather than just being sent to stderr
+ straight off
+
+ Andrew Dingwall, UniSoft Ltd., December 1994
+ Handle recursive calls to dtcmerror() sensibly.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for tetware tcc
+
+ Geoff Clare, UniSoft Ltd., August 1996
+ Missing <unistd.h>.
+
+ Geoff Clare, UniSoft Ltd., Sept 1996
+ Changes for TETware-Lite.
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ Enable tracing in TETware-Lite.
+ Restructured tcm source to avoid "ld -r".
+
+ Andrew Dingwall, UniSoft Ltd., June 1997
+ changes to enable parallel remote and distributed test cases
+ to work correctly;
+ improved process type determination when processing trace args
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/types.h>
+# include <unistd.h>
+#include "dtmac.h"
+#include "tet_api.h"
+#include "dtmsg.h"
+#include "ptab.h"
+#include "error.h"
+#include "globals.h"
+#include "synreq.h"
+#include "server.h"
+#include "servlib.h"
+#include "dtetlib.h"
+#include "apilib.h"
+#include "tslib.h"
+#include "tcmfuncs.h"
+
+#ifndef NOTRACE
+#include "ltoa.h"
+#endif
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+extern int tet_psysid; /* parent's system id */
+#endif /* -END-LITE-CUT- */
+
+
+/*
+** tet_tcminit() - initialisation for both master and slave TCMs
+*/
+
+/* ARGSUSED */
+void tet_tcminit(argc, argv)
+int argc;
+char **argv;
+{
+ register char *envstring, *p;
+ char **args;
+ int nargs;
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ char errmsg[128];
+ register char **ap;
+ register int *ip;
+ struct synreq *synreq, *sp;
+ int count;
+ int nsys;
+#endif /* -END-LITE-CUT- */
+ static char tiargs_name[] = "TET_TIARGS";
+ static char tetroot_name[] = "TET_ROOT";
+ static char envmsg[] = "null or not set";
+#ifdef NOTRACE
+ int twarn = 0;
+#else
+# ifndef TET_LITE /* -START-LITE-CUT- */
+ int ptsave;
+# endif /* -END-LITE-CUT- */
+#endif
+
+ /* get TET_ROOT out of the environment */
+ if ((envstring = getenv(tetroot_name)) == (char *) 0 || !*envstring)
+ fatal(0, tetroot_name, envmsg);
+ (void) sprintf(tet_root, "%.*s", (int) sizeof tet_root - 1, envstring);
+
+ /* get the dtet ti args out of the environment and count them */
+ if ((envstring = getenv(tiargs_name)) == (char *) 0 || !*envstring) {
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ fatal(0, tiargs_name, envmsg);
+ /* NOTREACHED */
+ return;
+#else /* -END-LITE-CUT- */
+ args = NULL;
+ nargs = 0;
+#endif /* -LITE-CUT-LINE- */
+ }
+ else {
+ nargs = 1;
+ for (p = envstring; *p; p++)
+ if (isspace(*p))
+ nargs++;
+
+ /* allocate some space for argument pointers */
+ errno = 0;
+ if ((args = (char **) malloc(nargs * sizeof *args)) == (char **) 0)
+ fatal(errno, "can't get memory for arg list",
+ (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate ti env args = %s", tet_i2x(args));
+
+ /* split the arg string into fields */
+ nargs = tet_getargs(envstring, args, nargs);
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+ /* process each argument in turn */
+# ifndef NOTRACE
+ /* assume MTCM if we're not sure */
+ if ((ptsave = tet_myptype) < 0 || ptsave == PT_NOPROC)
+ tet_myptype = PT_MTCM;
+ tet_traceinit(nargs + 1, args - 1);
+ tet_myptype = ptsave;
+# endif
+ for (ap = args; ap < &args[nargs]; ap++) {
+ if (*(p = *ap) != '-')
+ continue;
+ TRACE2(tet_Ttcm, 6, "TI arg = \"%s\"", p);
+ switch (*++p) {
+ case 'T':
+# ifdef NOTRACE
+ if (!twarn) {
+ error(0, "tracing not configured",
+ (char *) 0);
+ twarn = 1;
+ }
+# endif
+ break;
+ case 'l':
+ count = isdigit(*++p) ? 1 : 0;
+ do {
+ if (*p == ',')
+ count++;
+ else if (!isdigit(*p))
+ fatal(0, "bad sysname string",
+ *ap);
+ } while (*++p);
+ errno = 0;
+ if ((tet_snames = (int *) malloc(count * sizeof *tet_snames)) == (int *) 0)
+ fatal(errno, "can't get memory for sname list",
+ (char *) 0);
+ TRACE2(tet_Tbuf, 6, "allocate tet_snames = %s",
+ tet_i2x(tet_snames));
+ p = *ap + 2;
+ ip = tet_snames;
+ tet_Nsname = count;
+ while (--count >= 0) {
+ *ip = atoi(p);
+ ip++;
+ while (*p)
+ if (*p++ == ',')
+ break;
+ }
+ break;
+ case 'n':
+ if ((tet_snid = atol(p + 1)) <= 0)
+ fatal(0, "bad sync id", *ap);
+ break;
+ case 'p':
+ if ((tet_psysid = atoi(p + 1)) < 0)
+ fatal(0, "bad parent system id", *ap);
+ break;
+ case 'r':
+ if ((tet_xrid = atol(p + 1)) <= 0)
+ fatal(0, "bad xres id", *ap);
+ break;
+ case 's':
+ if ((tet_mysysid = atoi(p + 1)) < 0)
+ fatal(0, "bad system id", *ap);
+ break;
+ default:
+ fatal(0, "bad ti env argument", *ap);
+ /* NOTREACHED */
+ }
+ }
+#endif /* -END-LITE-CUT- */
+
+ } /* end of tiargs processing */
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+ if (tet_mysysid < 0)
+ fatal(0, "sysid not assigned", (char *) 0);
+
+ if (tet_snid < 0L)
+ fatal(0, "snid not assigned", (char *) 0);
+
+ if (tet_xrid < 0L)
+ fatal(0, "xrid not assigned", (char *) 0);
+
+ if (tet_Nsname <= 0)
+ fatal(0, "system name list not assigned", (char *) 0);
+
+ /* assign my process type */
+ switch (tet_myptype = tet_tcmptype()) {
+ case PT_MTCM:
+ case PT_STCM:
+ break;
+ default:
+ fatal(0, "ptype assignment error:", tet_ptptype(tet_myptype));
+ }
+
+#endif /* -END-LITE-CUT- */
+
+#ifndef NOTRACE
+ /* initialise tracing for known process type */
+ if (args != NULL) {
+ tet_tfclear();
+ tet_traceinit(nargs + 1, args - 1);
+ }
+#endif
+
+ if (args != NULL) {
+ TRACE2(tet_Tbuf, 6, "free ti env args = %s", tet_i2x(args));
+ free((char *) args);
+ }
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+ /* perform transport-specific initialisation */
+ tet_ts_startup();
+ tet_ts_tcminit();
+
+ /* log on to syncd and xresd */
+ if (tet_sdlogon() < 0 ||
+ tet_xdlogon() < 0 ||
+ tet_xdxrsend(tet_xrid) < 0)
+ exit(1);
+
+ /* now we are logged on to xresd, we can use the combined file
+ if we received an xrid in TET_TIARGS */
+ if (tet_xrid > 0L)
+ tet_combined_ok = 1;
+
+#endif /* -END-LITE-CUT- */
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+
+ /* get some memory for the autosync results */
+ if ((synreq = (struct synreq *) malloc(tet_Nsname * sizeof *synreq)) == (struct synreq *) 0) {
+ tet_error(errno, "can't get memory for synreq array");
+ tet_exit(1);
+ }
+ TRACE2(tet_Tbuf, 6, "allocate synreq = %s", tet_i2x(synreq));
+
+ /* here, TCMs sync with each other, or a TCMrem process syncs
+ with its parent */
+ nsys = tet_Nsname;
+ if (tet_tcm_async(SV_EXEC_SPNO, SV_YES, SV_EXEC_TIMEOUT, synreq, &nsys) < 0) {
+ tet_error(tet_sderrno, "initial sync failed");
+ tet_exit(1);
+ }
+
+ /* if we didn't get an xrid from TET_TIARGS, we might have received
+ one in the last async reply */
+ if (!tet_combined_ok && tet_xrid > 0L)
+ tet_combined_ok = 1;
+
+ /* report a sync that failed in an "expected" way */
+ if (tet_sderrno != ER_OK) {
+ for (sp = synreq; sp < synreq + nsys; sp++)
+ switch (sp->sy_state) {
+ case SS_SYNCYES:
+ break;
+ default:
+ (void) sprintf(errmsg,
+ "initial sync error, sysid = %d, state = %s",
+ sp->sy_sysid,
+ tet_systate(sp->sy_state));
+ tet_error(tet_sderrno, errmsg);
+ }
+ tet_exit(1);
+ }
+
+ TRACE2(tet_Tbuf, 6, "free synreq = %s", tet_i2x(synreq));
+ free((char *) synreq);
+
+#endif /* -END-LITE-CUT- */
+}
+
+/*
+** tet_dtcmerror() - TETware TCM error printing routine
+**
+** messages printed by the error() macro come here
+** note that this function might be called recursively
+*/
+
+void tet_dtcmerror(errnum, file, line, s1, s2)
+int errnum, line;
+char *file;
+register char *s1, *s2;
+{
+ char msg[MAXPATH + 128];
+ register char *p = msg;
+ static int inprogress = 0;
+ int combined_save = 0;
+
+ /* start the buffer with filename and line number */
+ (void) sprintf(p, "(%s, %d): ", tet_basename(file), line);
+ p += strlen(p);
+
+ /* append the first message string */
+ while (*s1 && p < &msg[sizeof msg - 1])
+ *p++ = *s1++;
+
+ /* append the second message string if there is one */
+ if (s2 && *s2 && p < &msg[sizeof msg - 1]) {
+ *p++ = ' ';
+ while (*s2 && p < &msg[sizeof msg - 1])
+ *p++ = *s2++;
+ }
+
+ /*
+ ** terminate the message and punt it to tet_error() for output -
+ ** if we are called recursively, there is probably
+ ** something wrong with the connection to xresd, so clear
+ ** the tet_combined_ok flag to force output to stderr instead
+ */
+ *p = '\0';
+ if (inprogress++) {
+ combined_save = tet_combined_ok;
+ tet_combined_ok = 0;
+ }
+ tet_error(errnum, msg);
+ if (--inprogress)
+ tet_combined_ok = combined_save;
+
+ errno = 0;
+}
+
diff --git a/src/tet3/tcm/tcmfuncs.h b/src/tet3/tcm/tcmfuncs.h
new file mode 100644
index 00000000..2eac7525
--- /dev/null
+++ b/src/tet3/tcm/tcmfuncs.h
@@ -0,0 +1,56 @@
+/*
+ * SCCS: @(#)tcmfuncs.h 1.11 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+/************************************************************************
+
+SCCS: @(#)tcmfuncs.h 1.11 98/09/01 TETware release 3.3
+NAME: tcmfuncs.h
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: April 1992
+
+DESCRIPTION:
+ declarations of extern tcm-specific functions not declared in
+ other header files
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd, October 1992
+ added tet_callfuncname() declaration
+
+ Added declarations of ictp.c and [ms]tcmdist.c functions.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for tetware tcc
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+
+************************************************************************/
+
+
+extern void tet_tcminit PROTOLIST((int, char **));
+extern char *tet_callfuncname PROTOLIST((void));
+extern void tet_check_apilib_version PROTOLIST((void));
+
+#ifndef TET_LITE /* -START-LITE-CUT- */
+ extern int tet_tcmptype PROTOLIST((void));
+ extern int tet_tcm_ts_tsinfo2bs PROTOLIST((char *, char *));
+ extern int tet_tcm_ts_tsinfolen PROTOLIST((void));
+ extern void tet_ts_tcminit PROTOLIST((void));
+#endif /* -END-LITE-CUT- */
+
+
diff --git a/src/tet3/tcm/tcmrem.c b/src/tet3/tcm/tcmrem.c
new file mode 100644
index 00000000..61626221
--- /dev/null
+++ b/src/tet3/tcm/tcmrem.c
@@ -0,0 +1,270 @@
+/*
+ * SCCS: @(#)tcmrem.c 1.13 (98/09/01)
+ *
+ * UniSoft Ltd., London, England
+ *
+ * (C) Copyright 1992 X/Open Company Limited
+ *
+ * All rights reserved. No part of this source code may be reproduced,
+ * stored in a retrieval system, or transmitted, in any form or by any
+ * means, electronic, mechanical, photocopying, recording or otherwise,
+ * except as stated in the end-user licence agreement, without the prior
+ * permission of the copyright owners.
+ *
+ * X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+ * the UK and other countries.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)tcmrem.c 1.13 (98/09/01) TET3 release 3.3";
+#endif
+
+/************************************************************************
+
+SCCS: @(#)tcmrem.c 1.13 98/09/01 TETware release 3.3
+NAME: tcmrem.c
+PRODUCT: TETware
+AUTHOR: Andrew Dingwall, UniSoft Ltd.
+DATE CREATED: May 1992
+
+DESCRIPTION:
+ tcm main() and client-related functions for processes
+ started by tet_remexec()
+
+MODIFICATIONS:
+ Andrew Dingwall, UniSoft Ltd., October 1992
+ Most of the code that was in this file is now in child.c and is
+ built into tcmchild.o as well as tcmrem.o.
+ This file now only contains code specific to tcmrem.o.
+
+ Andrew Dingwall, UniSoft Ltd., August 1996
+ changes for tetware-style syncs
+
+ Geoff Clare, UniSoft Ltd., Oct 1996
+ restructured tcm source to avoid "ld -r"
+ (this file was rtcmfuncs.c - moved main() and other things here)
+
+ Andrew Dingwall, UniSoft Ltd., April 1997
+ initialise tet_pname in case it gets used (in tet_dtcmerror())
+ before it can be set up in tet_tcm*_main()
+
+ Andrew Dingwall, UniSoft Ltd., July 1998
+ Added support for shared API libraries.
+ Note that this includes a change to the calling convention for
+ child processes.
+
+************************************************************************/
+
+#include <stdio.h>
+# include <signal.h>
+#include "dtmac.h"
+#include "dtmsg.h"
+#include "ptab.h"
+#include "error.h"
+#include "globals.h"
+#include "synreq.h"
+#include "tcmfuncs.h"
+#include "server.h"
+#include "tslib.h"
+#include "dtetlib.h"
+#include "sigsafe.h"
+
+extern int tet_tcmc_main PROTOLIST((int, char **));
+extern void tet_dtcmerror PROTOLIST((int, char *, int, char *, char *));
+
+TET_EXPORT char *tet_pname = "<unknown>";
+TET_EXPORT int tet_thistest = -1;
+
+int tet_psysid = -1; /* parent's system id */
+TET_EXPORT long tet_snid = -1L; /* sync id */
+TET_EXPORT long tet_xrid = -1L; /* xres id */
+TET_EXPORT int *tet_snames; /* system name list */
+TET_EXPORT int tet_Nsname; /* number of system names */
+TET_EXPORT struct ptab *tet_sdptab, *tet_xdptab;
+ /* ptab elements for syncd and xresd */
+
+TET_EXPORT sigset_t tet_blockable_sigs;
+
+#ifdef NEEDsrcFile
+static char srcFile[] = __FILE__; /* file name for error reporting */
+#endif
+
+/*
+** main() is the main program for processes started by tet_remexec().
+** It is simply a wrapper for tet_tcmc_main().
+*/
+
+int main(argc, argv)
+int argc;
+char **argv;
+{
+ /* must be first */
+ tet_init_globals(argc > 0 ? tet_basename(*argv) : "remote process controller",
+ -1, -1, tet_dtcmerror, tet_genfatal);
+
+ /*
+ ** make sure that we are linked with the right version of
+ ** the API library
+ */
+ tet_check_apilib_version();
+
+
+ return tet_tcmc_main(argc, argv);
+}
+
+/*
+** tet_callfuncname() - return name of tcmrem's calling function
+** for use in error messages
+*/
+
+char *tet_callfuncname()
+{
+ return("tet_remexec()");
+}
+
+/*
+** tet_tcmptype() - return process type for slave TCM
+*/
+
+int tet_tcmptype()
+{
+ return(PT_STCM);
+}
+
+/*
+** tet_tcm_async() - do an automatic sync from a tcmrem STCM
+*/
+
+TET_EXPORT int tet_tcm_async(spno, vote, timeout, synreq, nsys)
+long spno;
+int vote, timeout, *nsys;
+struct synreq *synreq;
+{
+ return(tet_sdasync(tet_snid, tet_xrid, spno, vote, timeout, synreq, nsys));
+}
+
+/*
+** tet_ss_dead() - server-specific dead process handler
+**
+** should only be called from tet_si_service() when a server dies
+** unexpectedly
+**
+** server logoff routines do not come here
+*/
+
+TET_EXPORT void tet_ss_dead(pp)
+struct ptab *pp;
+{
+ /* emit a diagnostic if this is unexpected */
+ if ((pp->pt_flags & PF_LOGGEDOFF) == 0)
+ error(0, "server connection closed", tet_r2a(&pp->pt_rid));
+
+ pp->pt_flags = (pp->pt_flags & ~PF_LOGGEDON) | PF_LOGGEDOFF;
+}
+
+/*
+** tet_ss_connect() - connect to remote process
+*/
+
+TET_EXPORT void tet_ss_connect(pp)
+struct ptab *pp;
+{
+ tet_ts_connect(pp);
+}
+
+/*
+** tet_ss_ptalloc(), tet_ss_ptfree() - allocate and free server-specific
+** ptab data area
+**
+** tcm does not make use of server-specific data
+*/
+
+TET_EXPORT int tet_ss_ptalloc(pp)
+struct ptab *pp;
+{
+ pp->pt_sdata = (char *) 0;
+ return(0);
+}
+
+/* ARGSUSED */
+TET_EXPORT void tet_ss_ptfree(pp)
+struct ptab *pp;
+{
+ /* nothing */
+}
+
+
+/*
+** tet_ss_serverloop() - server-specific server loop
+**
+** this may be called from tet_si_servwait() if non-blocking message i/o
+** would block
+**
+** tcm does not do non-blocking i/o, so this should never occur
+*/
+
+TET_EXPORT int tet_ss_serverloop()
+{
+ error(0, "internal error - serverloop called!", (char *) 0);
+ return(-1);
+}
+
+/*
+** tet_ss_process() - server-specific request process routine
+**
+** would be called from tet_si_service() when state is PS_PROCESS
+**
+** tcm only uses tet_si_clientloop() which itself returns as soon as a
+** process reaches this state, so tet_ss_process() should never be called
+**/
+
+TET_EXPORT void tet_ss_process(pp)
+struct ptab *pp;
+{
+ error(0, "internal error - tet_ss_process called!",
+ tet_r2a(&pp->pt_rid));
+}
+
+/*
+ * The following functions are simply wrappers for the real functions
+ * in tcm_bs.c, tcm_in.c and tcm_xt.c. This is done so that tccd, xresd
+ * and syncd cannot resolve these symbols in libapi.a.
+ */
+
+extern int tet_tcm_bs2md PROTOLIST((char *, struct ptab *));
+
+TET_EXPORT int tet_ss_bs2md(from, pp)
+char *from;
+struct ptab *pp;
+{
+ return tet_tcm_bs2md(from, pp);
+}
+
+extern int tet_tcm_md2bs PROTOLIST((struct ptab *pp, char **bp, int *lp,
+ int offs));
+
+TET_EXPORT int tet_ss_md2bs(pp, bp, lp, offs)
+struct ptab *pp;
+char **bp;
+int *lp, offs;
+{
+ return tet_tcm_md2bs(pp, bp, lp, offs);
+}
+
+extern int tet_tcm_tsconnect PROTOLIST((struct ptab *));
+
+TET_EXPORT int tet_ss_tsconnect(pp)
+struct ptab *pp;
+{
+ return tet_tcm_tsconnect(pp);
+}
+
+extern int tet_tcm_tsinfo PROTOLIST((struct ptab *, int));
+
+TET_EXPORT int tet_ss_tsinfo(pp, ptype)
+struct ptab *pp;
+int ptype;
+{
+ return tet_tcm_tsinfo(pp, ptype);
+}
+
diff --git a/src/tet3/tcm/xtilib.mk b/src/tet3/tcm/xtilib.mk
new file mode 100644
index 00000000..d2509c37
--- /dev/null
+++ b/src/tet3/tcm/xtilib.mk
@@ -0,0 +1,50 @@
+#
+# SCCS: @(#)xtilib.mk 1.9 (98/09/01)
+#
+# UniSoft Ltd., London, England
+#
+# (C) Copyright 1993 X/Open Company Limited
+#
+# All rights reserved. No part of this source code may be reproduced,
+# stored in a retrieval system, or transmitted, in any form or by any
+# means, electronic, mechanical, photocopying, recording or otherwise,
+# except as stated in the end-user licence agreement, without the prior
+# permission of the copyright owners.
+#
+# X/Open and the 'X' symbol are trademarks of X/Open Company Limited in
+# the UK and other countries.
+#
+#
+# ************************************************************************
+#
+# SCCS: @(#)xtilib.mk 1.9 98/09/01 TETware release 3.3
+# NAME: xtilib.mk
+# PRODUCT: TETware
+# AUTHOR: Denis McConalogue, UniSoft Ltd.
+# DATE CREATED: August 1993
+#
+# DESCRIPTION:
+# aux include file for XTI-specific tcm files
+#
+# MODIFICATIONS:
+# Andrew Dingwall, UniSoft Ltd., December 1993
+# Moved lists of transport-specific files from makefile and dtet.mk
+# to here.
+#
+# Geoff Clare, UniSoft Ltd., Sept 1996
+# Changes for TETware-Lite.
+#
+# Andrew Dingwall, UniSoft Ltd., August 1998
+# Added support for shared libraries.
+#
+# ************************************************************************
+
+# additional targets when building the TCM in Distributed TETware
+ALL_TS = $(ALL_DIST)
+TARGETS_TS = $(TARGETS_DIST)
+TARGETS_TS_S = $(TARGETS_DIST_S)
+
+# XTI-specific tcm object files
+TCM_STATIC_OFILES_TS = tcm_xt$O tcm_bs$O
+TCM_SHARED_OFILES_TS =
+