diff options
author | jamey <jamey> | 2005-10-31 23:09:06 +0000 |
---|---|---|
committer | jamey <jamey> | 2005-10-31 23:09:06 +0000 |
commit | 429ed4219a23e356fbbf0066a4330353e4e764a2 (patch) | |
tree | d928257f9b7715dad66711e065a9765252bfbaae /src/tet3/tcm | |
parent | 41fe38e5829b9ef59b67fae5d08ee0ca5ea6b803 (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.c | 190 | ||||
-rw-r--r-- | src/tet3/tcm/ckversion.c | 142 | ||||
-rw-r--r-- | src/tet3/tcm/dtcm.c | 1081 | ||||
-rw-r--r-- | src/tet3/tcm/dynlink.c | 67 | ||||
-rw-r--r-- | src/tet3/tcm/ictp.c | 888 | ||||
-rw-r--r-- | src/tet3/tcm/inetlib.mk | 50 | ||||
-rw-r--r-- | src/tet3/tcm/litelib.mk | 43 | ||||
-rw-r--r-- | src/tet3/tcm/makefile | 143 | ||||
-rw-r--r-- | src/tet3/tcm/makefile.orig | 143 | ||||
-rw-r--r-- | src/tet3/tcm/shared.mk | 175 | ||||
-rw-r--r-- | src/tet3/tcm/shared.mk.orig | 175 | ||||
-rw-r--r-- | src/tet3/tcm/tcm.c | 363 | ||||
-rw-r--r-- | src/tet3/tcm/tcm.c.orig | 360 | ||||
-rw-r--r-- | src/tet3/tcm/tcm_bs.c | 226 | ||||
-rw-r--r-- | src/tet3/tcm/tcm_in.c | 305 | ||||
-rw-r--r-- | src/tet3/tcm/tcm_xt.c | 322 | ||||
-rw-r--r-- | src/tet3/tcm/tcmchild.c | 376 | ||||
-rw-r--r-- | src/tet3/tcm/tcmchild.c.orig | 376 | ||||
-rw-r--r-- | src/tet3/tcm/tcmfuncs.c | 408 | ||||
-rw-r--r-- | src/tet3/tcm/tcmfuncs.h | 56 | ||||
-rw-r--r-- | src/tet3/tcm/tcmrem.c | 270 | ||||
-rw-r--r-- | src/tet3/tcm/xtilib.mk | 50 |
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 = + |