home *** CD-ROM | disk | FTP | other *** search
- /*
- * C O P Y R I G H T N O T I C E :
- * Copyright 1986 Eric Jul. May not be used for any
- * purpose without written permission from the author.
- *
- * File: /usr/Em/Kernel/KmdOps/kmdCode.c Origin: Eric Jul, 1986-05-01
- * Note: Rewritten for TCP/IP, May 1986.
- *
- * This file contain the bulk of the procedures to handle the kmd stuff
- * Log: 84/07/13 fixed bug in KMDShip re. the type of fArgs. Eric Jul
- *
- * Note: 84/11/29 19:04:23 schwartz
- * Changed all calls to malloc so they don't call HoldSigs and ReleaseSigs
- * before and after, since this is now done in (Almeses version of) malloc.
- *
- * 85/02/27 eric
- * Added GetBlocks and fixed trace sockets on socket death.
- * NOTE: The data structure rooted in THeads and nextHead must
- * be updated with signals held.
- * Added stuff so that KMD may be stuffed into Ejects too.
- *
- * 86/05/02 eric
- * Most Eden considerations removed.
- *
- * 88/07/05 cjeffery
- * BSD support moved under xkernel simulator
- */
-
- #undef integer
- #include "Kernel/h/system.h"
- #include "Kernel/h/expandArray.h"
- #include <nlist.h>
- extern errno; /* IPC status if call returns -1; NB: not set upon success!*/
-
- extern int
- DisplayEdenMsg(),
- GetEdenMsg(),
- PutEdenMsg();
-
- extern char progArg0Name[];
-
- #ifdef xkernel
- #include "userupi.h"
- #include "userprocess.h"
- #include "debug.h"
- #include "ip.h"
- #include "tcp.h"
- static IPaddr myipaddr;
- #endif
-
- #include "Kernel/h/mmTypes.h"
- #include "Kernel/h/mmCodes.h"
- #include "Kernel/h/unixCodes.h"
- #include "Kernel/h/mmBufTypes.h"
- #include "Kernel/h/mmFifoTypes.h"
- #include "Kernel/h/mmMsgDefs.h"
- #include "Kernel/h/mmMsgTypes.h"
- #include "Kernel/h/kEvents.h"
- #include "Kernel/h/kmdDefs.h"
- #include "Kernel/h/kmdTypes.h"
- #include "Kernel/h/timerTypes.h"
- #include "Kernel/h/sigio.h"
- #include "Kernel/h/map.h"
-
- /* this is defined in emTypes.h which includes <a.out.h> which defines a struct nlist,
- * which is incompatible with the one defined above in <nlist.h>.
- */
- #include "Kernel/h/emstream.h"
-
- #ifndef xkernel
- #include <errno.h>
- #include <sys/file.h>
- #include <sys/ioctl.h>
- #endif
- #ifdef xkernel
- extern Map tcp2emsessn;
- #endif
- extern int DebugLevel, MMTrace, emTracing;
-
- /* forward */
- HResult KMDMsgHandler();
- void KMDStartTrace();
- void KMDShip();
- int KMDRequestSignal(); /* fwrd. decl. of signal handler */
- void KMDCleanSock();
-
-
- /* Tables: */
-
- /* Table sizes */
- #define MAXSNAPS 64
- #define MAXTRACES 64
- #define MAXVARS 512
- #define MAXREQSOCKS 10 /* Each uses a file descriptor */
-
- typedef char *charPtr;
-
- typedef struct SnapElement
- {
- char *name;
- HandlerPtr handler;
- } SnapElement, *SnapElemPtr;
-
- #ifdef xkernel
- extern struct DebugInfo *debugStart();
- #endif xkernel
-
- typedef struct TraceElem
- {
- struct TraceElem *next; /* Ptr to next trace destination */
- int tracesock; /* Destination sock */
- struct DebugInfo *debugger;
- int level; /* Output level indicator */
- } TraceElem, *TraceElemPtr;
-
- typedef struct TraceHead
- {
- char *name;
- TraceElemPtr first;
- } TraceHead, TraceHeadPtr;
-
- typedef struct VarElem
- {
- char *name;
- int *addr;
- } VarElem, VarElemPtr;
-
-
- typedef struct PreparedElem {
- char *name;
- int level;
- } PreparedElem, *PreparedElemPtr;
-
-
-
- /*** table stuff ***/
- SnapElement Snaps[MAXSNAPS];
- TraceHead THeads[MAXTRACES];
- VarElem Vars[MAXVARS];
-
- #ifndef xkernel
- int ReqSocks[MAXREQSOCKS];
- #endif
-
- PreparedElem *PreparedTraces;
-
- /* ... and the next free element for them.
- * (Linear search is fine with me.)
- */
- int nextSnap = 0;
- int nextHead = 0;
- int nextVar = 0;
- int nextReq = 0;
- int nextPrepared = 0;
-
- /*** End of Table stuff ***/
-
-
-
-
-
- int KMDTraceAct = 0; /* Number of active traces */
- int anyKMDTrace = 1; /* True if any KMD tracing */
- int anyKMD = 1; /* True if any tracing is possible:
- False means no tracing at all */
- #ifdef xkernel
- PROTL KMDProtl;
- #else
- int KMDRequestSock; /* Socket for rec. requests */
- #endif
- int KMDSnapSock; /* Current Snapshot socket */
- int reqSrcLength;
- #ifdef BSD
- struct sockaddr_in reqSrc; /* Source address of request */
- struct sockaddr_in
- mySocket = {AF_INET}; /* KMD Socket for requests */
- #endif
-
- int interruptScheduled = 0;
-
- #define KMDTICKSIZE 300 /* milliseconds */
- int vKMDTickSize = KMDTICKSIZE; /* milliseconds */
-
- #define NULLSOCK 0
- #define KMDSIG SIGURG
- #define KMDSIGPIPE SIGPIPE
-
- /*** End of var decl. ***/
-
- #define endcase break
-
- #define DoArgs(stx, fFmt, fArgs) \
- { \
- struct _iobuf _strbuf; \
- char fullfmt[2000]; \
- \
- _strbuf._flag = _IOWRT+_IOSTRG; \
- _strbuf._ptr = stx; \
- _strbuf._cnt = 32767; \
- sprintf(fullfmt, "Em%02x: ",GetLNN()); \
- (void) strcat(fullfmt, fFmt); \
- _doprnt(fullfmt, fArgs, &_strbuf); \
- putc('\0',&_strbuf); \
- if (KMDTest) printf(" ... DidArgs: %s\n", stx); \
- }
-
- #ifdef xkernel
- /*
- * XKERNEL HANDLERS
- *
- * see note in .../FileLoad/loadCode.c for an explanation of xkernel handlers
- * implementing tcp connections. It appears the behavior of Kmd connections
- * may warrant a somewhat simpler approach than for loadCode.
- */
- KMDdemux_handler(s,msg,len)
- SESSN s;
- register char *msg;
- int len;
- {
- register EMSTREAM *ems;
-
- xkhandlerstart();
- if (KMDTest)
- printf("In KMDdemux_handler, session 0x%x, msg %s, len %d\n", s, msg, len);
- ems = (EMSTREAM *)Map_Lookup(tcp2emsessn, (int)s);
- if(ems==(EMSTREAM *)0x80000000) {/*include some file for IsNIL definition*/
- if (KMDTest) printf("no EMSTREAM found in KMDdemux_handler!\n");
- xkhandlerend();
- return;
- }
- ems->eof = !len;
- INSERTMSGQUEUE(ems->buffers,msg,len);
- if (xsemcount(ems->sem) >= 0) {
- if (KMDTest) printf("No one waiting for data on %#x\n", s);
- }
- xkv(ems->sem);
-
- if (!ems->usedForDebugging) {
- HoldSigs();
- QueueTask((HandlerPtr)KMDMsgHandler, (char *)ems);
- ReleaseSigs();
- }
- xkhandlerend();
- }
-
- KMDopendone_handler(s)
- SESSN s;
- {
- register EMSTREAM *ems;
-
- xkhandlerstart();
- if (KMDTest) printf("In KMDopendone_handler, session 0x%x\n", s);
- /* create emstream things */
- if(!(ems=(EMSTREAM *)malloc(sizeof(EMSTREAM)))) {
- if (KMDTest) printf("malloc #1 fails in FLopendone_handler!\n");
- xkhandlerend();
- return -1;
- }
- ems->sessn = s;
- ems->sem = xcreatesemaphore(0);
- ems->eof = 0;
- ems->usedForDebugging = 0;
- if((ems->buffers = (msgqueue *)malloc(sizeof(msgqueue)))==NULL){}
- ems->buffers->next = ems->buffers->prev = ems->buffers;
-
- /* one ring to rule them all, and in the darkness bind them. */
- Map_Insert(tcp2emsessn, (int)s, (int)ems);
-
- /* Tell the new socket that it has been connected */
- if (KMDTest )
- printf("In KMDopendone_handler, shipping reply from ems 0x%x\n", ems);
-
- KMDShip((int)ems, "KMDConnected to host %d\n", GetLNN());
- xkhandlerend();
- return 0;
- }
-
- KMDclosedone_handler(s)
- SESSN s;
- {
- register EMSTREAM *ems;
-
- xkhandlerstart();
- ems = (EMSTREAM *)Map_Lookup(tcp2emsessn, (int)s);
- KMDTrace("UserIO", 3, "'Socket' (tcp 0x%x) (ems 0x%x) died.\n", s, ems);
- xkhandlerend();
- }
-
- #endif
-
-
-
- /* Set the KMD flags. Used for dynamically changing the values of
- * trace flags
- *
- * Problem: In the MM there are statements of the form:
- * if (MMTrace > 7) ... which circumvent calling MMTraceMsg thus
- * resulting in less output than desired.
- * There are also statements like: if (MMTrace) MMTraceMsg ...
- * (see MMTraceMxg macro in some .h file), but the hack below solved that
- */
- void KMDSetFlags()
- {
- anyKMDTrace = KMDTraceAct != 0;
- if (anyKMDTrace && (! MMTrace)) MMTrace = -1; /* Hack */
- if (! anyKMDTrace && (MMTrace < 0 )) MMTrace = 0;/* Hack */
- anyKMD = DebugLevel || MMTrace || KMDTraceAct;
- if (KMDTest)
- printf(" ... any=%d, TraceAct=%d, anyKMDTrace=%d, -x%d, -t%d\n",
- anyKMD, KMDTraceAct, anyKMDTrace, DebugLevel, MMTrace);
- }
-
-
- /* Just a front end for malloc to handle:
- 1) Disable-enable of signals.
- 2) Errors.
- */
- charPtr kmdalloc(memsize)
- int memsize;
- {
- charPtr i;
-
- if ( ! (i = (charPtr) malloc((unsigned)memsize) ) ) {
- printf("\n*** KMD fatal error malloc returned NULL - dumping core\n");
- abort();
- }
- return(i);
- }
-
- /* Must be very careful: This code segment must be protected
- * from signals, but signals may or may not already be held.
- * The problem is that deallocation may be required DURING trace output
- * for signal handlers.
- * EXTREME CAUTION necessary.
- * 85/02/27: Lastest fix avoids kmdfree during trace output if sigs are held.
- * by employing KMDDeadPipe and KMDCleanSock.
- * This basically make the above caution unnecessary.
- */
- void kmdfree(fPtr)
- TraceElemPtr fPtr;
- {
- if (KMDTest) printf(" ... kmdfree, %s\n", SigsHeld ? "SigsHeld!!!":
- "Sigs fortunately not held");
- if (SigsHeld) return; /* Lose it!*/
- free((char *)fPtr);
- }
-
- /************************************************************************/
-
-
- #ifdef BSD
-
- /*ARGSUSED*/
- int SIGIOOccurred(fKind, fSock)
- int fSock;
- {
- QueueTask(KMDMsgHandler, (char *) fSock);
- return 0; /* procedure ought to be void */
- }
-
- #endif
-
- /************************************************************************/
-
-
- /* Encodes a KMD msg according to the fFmt and the fArgs and Sends it
- * to the specified socket.
- */
- /* VARARGS2 */
- void KMDShip(fSock, fFmt, fArgs)
- int fSock; /* Sock to ship to */
- char *fFmt; /* Format pointer for printf */
- char *fArgs; /* Argument pointer for printf */
- {
- struct _iobuf _strbuf;
- char str[2000];
- char fullfmt[132];
- KKStatus status;
-
- if(fSock == NULLSOCK) return;
- _strbuf._flag = _IOWRT+_IOSTRG;
- #ifdef vax
- _strbuf._ptr = str;
- #else
- _strbuf._ptr = (unsigned char *)str;
- #endif
-
- _strbuf._cnt = 32767;
- sprintf(fullfmt, "Em%02x: ",GetLNN());
- (void) strcat(fullfmt,fFmt);
- _doprnt(fullfmt, &fArgs, &_strbuf);
- putc('\0',&_strbuf);
- if (KMDTest)
- printf(" ... shipping to %d: %s\n", fSock, str);
- #ifndef xkernel
- if (KMDSTDOUTSOCK == fSock) {
- printf("%s", str);
- (void) fflush(stdout);
- return;
- }
- #endif
- status = KMDSend(fSock, KMDCDATA, 0, str);
- if (!mSUCCESS(status)) {
- if (KMDTest) perror("KMDSend");
- #ifdef BSD
- (void) close(fSock);
- #else
- #ifdef xkernel
- ems_close((EMSTREAM *)fSock);
- #endif
- #endif
- }
- return;
- }
-
-
- /* Sends a snapshot line to the current snapshot socket */
- /*VARARGS1*/
- void KMDPrint(fFmt, fArgs)
- char *fFmt, *fArgs; /* Args as for DebugMsg */
- {
- struct _iobuf _strbuf;
- char str[2000];
- KKStatus status;
-
- if (KMDTest) printf("KMDPrint called Snapsocket = %d\n", KMDSnapSock);
- if (KMDSnapSock == NULLSOCK) return;
- _strbuf._flag = _IOWRT+_IOSTRG;
- #ifdef vax
- _strbuf._ptr = str;
- #else
- _strbuf._ptr = (unsigned char *)str;
- #endif
- _strbuf._cnt = 32767;
-
- _doprnt(fFmt, &fArgs, &_strbuf);
- putc('\0',&_strbuf);
- if (KMDTest) printf(" ... snap shipping to %d:%s\n", KMDSnapSock, str);
- #ifndef xkernel
- if (KMDSTDOUTSOCK == KMDSnapSock) {
- printf("%s", str);
- (void) fflush(stdout);
- return;
- }
- #endif
- status = KMDSend(KMDSnapSock, KMDCDATA, 0, str);
- if (!mSUCCESS(status)) {
- perror("KMDSend");
- #ifdef BSD
- (void) close(KMDSnapSock);
- #else
- #ifdef xkernel
- ems_close((EMSTREAM *)KMDSnapSock);
- #endif
- #endif
- KMDSnapSock = NULLSOCK;
- }
- return;
- }
-
- /************************************************************************/
-
- void KMDSetSnap1(fName, fHandler)
- char *fName; /* The Name of the snapshot */
- HandlerPtr fHandler; /* The snapshot handler. */
- {
- register int i;
- if (KMDTest) printf("KMDSetSnap1 for %s\n", fName);
- for (i=0; i < nextSnap ? strcmp(fName, Snaps[i].name) : 0; i++);
- if (KMDTest) printf(" ... i=%d, nextSnap = %d\n", i, nextSnap);
- if (i == nextSnap) { /* A new one */
- nextSnap++;
- if (Snaps[i].name = kmdalloc(strlen(fName) +1))
- (void) strcpy(Snaps[i].name, fName);
- } else {
- /* An existing one */
- }
- Snaps[i].handler = fHandler;
- }
-
-
- void KMDSetTrace1(fName)
- char *fName; /* The name of the trace */
- {
- register int i;
-
- if (KMDTest) printf("KMDSetTrace1 for %s\n", fName);
- for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
- if (i < nextHead) {
- /* An existing one */
- if (KMDTest)
- printf("KMDSetTrace: Duplicate Trace definition ignored , name: %s\n",
- fName);
- return;
- }
-
- /* A new one */
- if (THeads[i].name = kmdalloc(strlen(fName) +1) ) {
- (void) strcpy(THeads[i].name, fName);
- } else {
- printf("Malloc returned 0\n");
- }
- THeads[i].first = NULL;
- nextHead++;
-
- /* Check to see if a trace request was made earlier for this trace */
- for (i=0; i<nextPrepared ? strcmp(fName, PreparedTraces[i].name): 0; i++);
- if (i < nextPrepared) {
- /* A trace request was done earlier, so start it now that the
- trace has been defined */
- KMDStartTrace(fName, PreparedTraces[i].level, KMDSTDOUTSOCK, TRUE);
- }
- }
-
-
- /* Lookup the named variable first in the table and if not found then
- * try nlist(). If found there then cache in table.
- * If not found at all then return -1
- */
- int *NlistValueOf(fName)
- char *fName;
- {
- register int i;
- static struct nlist nl[] = {
- { 0 },
- { 0 }
- };
- char vName[132];
- int *ptr;
- VarElem tempVarElem;
-
- if ( KMDTest ) printf(" ... VarLookup of %s\n", fName);
- for (i=0; i < nextVar ? strcmp(fName, Vars[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextVar = %d\n", i, nextVar);
- if (i < nextVar) {
- /* An existing one */
- /* For performance: reorganize list, use move-to-front */
- tempVarElem = Vars[i];
- Vars[i] = Vars[0];
- Vars[0] = tempVarElem;
- return((int*) Vars[0].addr );
- }
-
- /* Try looking it up using nlist */
-
- if ( KMDTest ) printf(" ... trying nlist of file %s\n", progArg0Name);
- (void) strcpy(&vName[0], fName);
- nl[0].n_name = vName;
- #ifdef BSD /* make this xsimul if you must */
- nlist(progArg0Name, nl); /* progArg0Name set in main.c */
- #else
- nl[0].n_type = 0; /* no unix->no nlist: force a failure */
- #endif
- if ( nl[0].n_type == 0 ) { /* Not there or nlist failed */
- if ( KMDTest )
- printf(">> Warning: nlist failed for %s, file %s.\n",fName,progArg0Name);
- ptr = (int *) -1;
- } else {
- ptr = (int *) nl[0].n_value;
- if (KMDTest)
- printf(" ... nlist returned addr 0x%08x value %d (0%x)\n",
- ptr, *ptr, *ptr);
- }
-
- /* Cache it in table */
- if ( nextVar >= MAXVARS ) { /* Table full */
- if (nextVar++ == MAXVARS)
- /* Print warning once only */
- printf(">> Warning: KMD Vars table size of %d too small.\n", MAXVARS);
- return((int *) ptr);
- }
-
- i = nextVar++;
- if ( (Vars[i].name = kmdalloc(strlen(fName) +1)) )
- (void) strcpy(Vars[i].name, fName);
- Vars[i].addr = ptr;
- if (KMDTest) printf(" ... name %s, addr 0x%08x, value %d\n",
- Vars[i].name, ptr, (ptr == ((int *) -1) ? -1 : *ptr) );
- return((int*) ptr);
- }
-
- /* Looks up the C-language variable named as given in fName.
- * Note, a leading _ is added since cc does this too
- */
- int *VarLookup(fName)
- char *fName;
- {
- char buf[200];
- (void) strcpy(buf, "_");
- (void) strcat(&buf[1], fName);
- return((int *) NlistValueOf(buf));
- }
-
-
- void KMDSetVar1(fName, fAddr)
- char *fName; /* The Name of the Variable */
- int *fAddr; /* The address of the Variable */
- {
- register int i;
- char buf[200];
- (void) strcpy(buf, "_");
- (void) strcat(&buf[1], fName);
- if (KMDTest) printf("KMDSetVar1 for %s, addr = 0x%0x8\n", buf, fAddr);
- for (i=0; i < nextVar ? strcmp(buf, Vars[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextVar = %d\n", i, nextVar);
- if (i == nextVar) { /* A new one */
- nextVar++;
- } else {
- /* An existing one */
- if ((Vars[i].addr) == fAddr) return;
- printf("KMDSetVar: Duplicate Var name: %s - second call ignored.\n", buf);
- return;
- }
- if ((Vars[i].name = kmdalloc(strlen(buf) +1)) )
- (void) strcpy(Vars[i].name, buf);
- Vars[i].addr = fAddr;
- if (KMDTest) printf(" ... name %s, addr 0x%08x, value %d\n",
- Vars[i].name, Vars[i].addr, *(Vars[i].addr) );
- }
-
-
-
- /* Due to parameters to _doprnt KMDTracex1 should not be called directly
- * unless you know what you are doing.
- * KMDTrace1 may be called directly with variable args.
- * KMDTracex1 must be called "indirectly" with 4 args.
- * Both should be called using the macros KMDTrace and KMDTracex resp.
- */
-
- /*VARARGS3*/
- void KMDTrace1(fName, fLevel, fFmt, fArgs)
- char *fName; /* Trace name */
- int fLevel; /* The level at which output is to be done.*/
- char *fFmt, *fArgs; /* For _doprnt */
- {
- KMDTracex1(fName, fLevel, fFmt, &fArgs);
- }
-
- /*VARARGS3*/
- void KMDTracex1(fName, fLevel, fFmt, fArgs)
- char *fName; /* Trace name */
- int fLevel; /* The level at which output is to be done.*/
- char *fFmt, *fArgs; /* For _doprnt */
- {
- register int i;
- register TraceElemPtr p, q;
- char str[2000];
- int notEncoded;
-
- if (KMDTest)
- printf(" KMDTrace1: fName = %s, fLevel = %d\n", fName, fLevel);
- KMDSetFlags();
- if (!anyKMDTrace) return;
- for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
-
- if (i == nextHead) {
- if (KMDTest) printf(" ... not found - ignored.\n");
- return;
- }
-
- notEncoded = 1; /* True, until the string to print has been encoded */
- for (p = THeads[i].first, q = NULL; p != NULL; ) {
- if (KMDTest)
- printf(" ... q = 0x%08x, p = 0x%08x, sock = %d, level = %d\n",
- q, p, p->tracesock, p->level);
- if ((fLevel > p->level) || (p->tracesock==NULLSOCK)) {
- /* Skip it */
- q = p; p = p-> next;
- } else { /* send trace data to this listner */
- if (KMDTest) printf(" ... found a trace listner ..\n");
- if (notEncoded) {
- notEncoded = 0;
- #ifdef vax
- DoArgs(str, fFmt, fArgs); /* Encode them args! */
- #else
- DoArgs((unsigned char *)str, fFmt, fArgs); /* Encode them args! */
- #endif
-
- }
- #ifdef xkernel
- if (p->debugger) {
- runDebugger(p, str);
- q=p; p = p->next;
- } else {
- #else
- {
- #endif xkernel
- if ( mSUCCESS(KMDSend(p->tracesock, KMDCDATA, 0, str)) ) {
- /* Send ok, advance pointer */
- q=p; p = p->next;
- } else {
- /* Unsuccessful send: There is a problem here.
- * We would like to remove the entry from the list,
- * but we may be in the middle of an interrupt, or
- * get one.
- * Therefore, we will just null the
- * socket and the trace entry will eventually
- * be cleaned when its file descriptor is reused
- */
- if ( KMDTest )
- printf(" ... Bum Sock = %d\n", p->tracesock);
- p->tracesock = NULLSOCK;
- q=p; p = p->next;
- }
- }
- }
- }
- }
-
-
- /********************************************************************/
- /* KMD defined snapshots: */
- /* Snapshots Print the possible snapshots. */
- /* Traces Print the possible traces. */
- /* Variables Print the currently accessible vars. */
- /* Flush Flushes stderr and stdout. */
- /* Menu Print a menu. */
- /* NOP A NOP */
- /********************************************************************/
-
- /* Snapshot */
- /* VARARGS */
- static void Snapshots()
- /* Print the snapshots available */
- {
- register int i;
-
- KMDPrint("The following %d snapshots are available:\n", nextSnap);
-
- for (i=0; i < nextSnap; i += 4)
- KMDPrint(" %-18.18s %-18.18s %-18.18s %.18s\n", Snaps[i].name,
- (i+1 < nextSnap) ? Snaps[i+1].name : " ",
- (i+2 < nextSnap) ? Snaps[i+2].name : " ",
- (i+3 < nextSnap) ? Snaps[i+3].name : " ");
- }
-
-
- /* Snapshot */
- /*VARARGS*/
- static void Traces()
- /* Print the traces available */
- {
- register int i;
-
- KMDPrint("The following %d traces are available:\n", nextHead);
-
- for (i=0; i < nextHead; i+=4)
- KMDPrint(" %s%-18.18s %s%-18s %s%-18s %s%-18s\n",
- THeads[i].first ? "*" : " ", THeads[i].name,
- ((i+1) < nextHead) ? THeads[i+1].first ? "*" : " " : " ",
- ((i+1) < nextHead) ? THeads[i+1].name : " ",
- ((i+2) < nextHead) ? THeads[i+2].first ? "*" : " " : " ",
- ((i+2) < nextHead) ? THeads[i+2].name : " ",
- ((i+3) < nextHead) ? THeads[i+3].first ? "*" : " " : " ",
- ((i+3) < nextHead) ? THeads[i+3].name : " ");
- }
-
-
- /* Snapshot */
- static void Variables()
- /* Print the vars available in list - besides the nlist stuff */
- {
- register int i;
-
- KMDPrint("Variable addr. Value Name\n");
- for (i=0; i < nextVar; i++)
- KMDPrint(" 0x%08x %10d (0x%08x) %s\n", Vars[i].addr,
- *(Vars[i].addr), *(Vars[i].addr), Vars[i].name);
- }
-
-
- /* Snapshot */
- static void Flush()
- /* Flushes standard error and standard output files */
- {
- #ifndef xkernel
- KMDPrint("Flushing kernel stderr and stdout\n");
- (void) fflush(stderr);
- (void) fflush(stdout);
- #endif
- }
-
-
- /*Snapshot*/
- static void Menu()
- /* Print snaps and traces */
- {
- Snapshots(); Traces();
- KMDPrint("To print variables, try the Variables snapshot\n");
- }
-
- /* Snapshot */
- static void Help()
- /* Prints out a help message */
- {
- KMDPrint("KMD facilities: try Menu for the list of snapshots.\n");
- KMDPrint("snapshot -n Traces -- gives the avaliable traces\n");
- KMDPrint("snapshot -n Snapshots -- gives the available snapshots\n");
- }
-
- /* Snapshot */
- static void NOP()
- {
- KMDPrint("NOP -- or Yes, I am alive\n");
- }
-
- /************************************************/
- /* E N D O F K M D Defined snapshots.*/
- /************************************************/
-
- void KMDStartTrace(fName, fLevel, fSrcSock, fUseStdout)
- char *fName;
- int fLevel, fSrcSock;
- int fUseStdout;
- {
- register int i;
- int sock;
- char buf[200];
- int useDebugger = 0;
-
- if ( KMDTest )
- printf("Start %s tracing level %d to sock = %d\n", fName, fLevel,
- fSrcSock);
- if (!strcmp(fName, "*LineNumber")) {
- useDebugger = TRUE;
- fName++;
- }
-
- if (fUseStdout) {
- /* trace to std out */
- sock = KMDSTDOUTSOCK;
- } else sock = fSrcSock;
-
- for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
- if (i == nextHead) {
- /* Not found, return error */
- sprintf(buf, "Trace %s unknown\n", fName);
- (void) KMDSend( fSrcSock, KMDCERRMSG, 0, buf);
- return;
- } else {
- TraceElemPtr newElem;
- /* Found it; Insert into linked list */
- newElem = (TraceElemPtr) kmdalloc(sizeof(TraceElem));
- HoldSigs();
- newElem->next = THeads[i].first;
- THeads[i].first = newElem;
- newElem->tracesock = sock;
- #ifdef xkernel
- newElem->debugger = useDebugger ? debugStart(newElem) : NULL;
- #else
- newElem->debugger = NULL;
- #endif xkernel
- newElem->level = fLevel;
- ReleaseSigs();
- if (KMDTest)
- printf(" ... added: 0x%08x, sock = %d, level = %d\n", newElem,
- newElem->tracesock, newElem->level);
- KMDTraceAct++;
- KMDSetFlags();
- if (!strcmp(fName,"LineNumber")) {
- emTracing = THeads[i].first != NULL;
- }
- sprintf(buf, "Started trace %s level %d%s\n", fName,
- newElem->level,
- (newElem->tracesock == KMDSTDOUTSOCK) ? " to stdout":"");
- if (sock != KMDSTDOUTSOCK) {
- (void) KMDSend(fSrcSock, KMDCDATA, 0, buf);
- } else printf("%s", buf);
- }
- }
-
- void KMDStopTrace(fName, fSrcSock, fUseStdout)
- char *fName;
- int fSrcSock;
- int fUseStdout;
- {
- register int i;
- int sock;
- char buf[200];
- if ( KMDTest )
- printf("Stop %s tracing to sock = %d\n", fName, fSrcSock);
- if (fUseStdout) {
- /* trace to std out */
- sock = KMDSTDOUTSOCK;
- } else sock = fSrcSock;
- for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextHead = %d\n", i, nextHead);
- if (i == nextHead) {
- /* Not found, return error */
- sprintf(buf, "Trace %s unknown\n", fName);
- (void) KMDSend( fSrcSock, KMDCERRMSG, 0, buf);
- return;
- } else {
- /* Found it; Remove it from linked list */
- register TraceElemPtr p, q, theEntry;
-
- if ( KMDTest )
- printf(" ... looking for entry = %d\n", sock);
-
- for (p = THeads[i].first, q = NULL; p != NULL; ) {
- if (KMDTest)
- printf(" ... checking p = 0x%08x, q = 0x%08x, sock = %d\n",
- p, q, p->tracesock);
- if (p->tracesock != sock ) {
- q = p; p = p->next;
- continue;
- };
- if (KMDTest)
- printf("Removing theEntry, sock = %d\n", p->tracesock);
- theEntry = p;
- HoldSigs();
- if (q == NULL) { /* First entry */
- p = p->next;
- THeads[i].first = p;
- } else { /* Down the line entry */
- p = q->next = p->next;
- };
- ReleaseSigs();
- if (KMDTest) printf(" ... stop tracing to sock %d\n",
- theEntry->tracesock);
- if (theEntry->tracesock != NULLSOCK) {
- sprintf(buf, "Stopped trace %s level %d%s\n", fName,
- theEntry->level,
- (theEntry->tracesock == KMDSTDOUTSOCK) ? " to stdout":"");
- if (sock != KMDSTDOUTSOCK) {
- (void) KMDSend(fSrcSock, KMDCDATA, 0, buf);
- } else printf("%s", buf);
- };
- kmdfree(theEntry);
- KMDTraceAct--;
- KMDSetFlags();
- };
- if (!strcmp(fName,"LineNumber")) {
- emTracing = THeads[i].first != NULL;
- }
- }
- }
-
-
- void KMDPrepareTrace(fName, fLevel)
- char *fName;
- int fLevel;
- {
- register int i;
-
- for (i=0; i < nextHead ? strcmp(fName, THeads[i].name) : 0; i++);
- if (i == nextHead) {
- /* Did not find it, so retain it for later (see KMDSetTrace) */
- if (nextPrepared == 0) {
- CreateArray((int **)&PreparedTraces, sizeof(TraceElem));
- }
- EnsureArray((int **)&PreparedTraces,
- (nextPrepared+1) * sizeof(PreparedElem),
- (nextPrepared + 2) * sizeof(PreparedElem));
-
- PreparedTraces[nextPrepared].level = fLevel;
- if(PreparedTraces[nextPrepared].name = kmdalloc(strlen(fName)+1))
- (void) strcpy(PreparedTraces[nextPrepared].name, fName);
- nextPrepared++;
- return;
- }
- /* Found it, so start it right away */
- KMDStartTrace(fName, fLevel, KMDSTDOUTSOCK, TRUE);
- }
-
- /* KMDMsgHandler
- *
- * Invoked from task queue when there is data to read on the socket.
- * Accepts requests for new KMD connections and reads specific
- * requests off of old ones.
- */
-
- HResult KMDMsgHandler(fSock)
- int fSock;
- {
- int MType, MInt;
- int SrcSock;
- register int i;
- int *ptr;
- char MString[MAXMESSAGESIZE];
- char snapName[MAXMESSAGESIZE];
- char *snapString;
- KKStatus status;
- SnapElement tempSnapElement;
- #ifdef xkernel
- EMSTREAM *ems = (EMSTREAM *)fSock;
- #else
- int nreadablebytes, newReqSock, s, sockIndex;
- int somethingHappened = 1;
- #endif
-
- #ifndef xkernel
- while(somethingHappened) {
- somethingHappened = 0;
- if (KMDTest) (void) fflush(stdout);
- if (KMDTest) printf("KMDMsgHandler top of loop\n");
-
- if (fSock == KMDRequestSock) {
- reqSrcLength = sizeof(reqSrc);
- newReqSock = accept(KMDRequestSock, (struct sockaddr *) &reqSrc,
- &reqSrcLength);
- if (newReqSock < 0) {
- if (KMDTest) printf("No new request\n");
- } else {
- somethingHappened = 1;
- /* Accept and set up a new request */
- if (KMDTest) printf("New request fd %d\n", newReqSock);
- /* First, clean out the socket */
- KMDCleanSock(newReqSock);
-
- /* Second, tell the new socket that it has been connected */
- KMDShip(newReqSock, "KMD Connected to host %d\n", GetLNN());
-
- /* Third, make the request line use SIGIO */
- if (fcntl(newReqSock, F_SETFL, FASYNC) < 0 ) {
- perror("newReqSock: fcntl");
- return;
- };
-
- if (fcntl(newReqSock, F_SETOWN, getpid()) < 0 ) {
- perror("newReqSock: fcntl");
- return;
- };
-
- SISetSockHandler(newReqSock, SIREAD, (SIHandlerPtr)SIGIOOccurred);
- SISetSockHandler(newReqSock, SIEXCEPT,(SIHandlerPtr) KMDCleanSock);
- /* Ensure that a new SIGIO occurs soon (there might already be
- input on the socket) */
- SIEnsureSIGIO();
-
- /* Put into request list and sooner or later something will
- arrive (or the connection will die).
- */
-
- if (nextReq >= MAXREQSOCKS) {
- (void) KMDSend(newReqSock, KMDCERRMSG, 0,
- "Out of KMD sockets.\n");
- (void) shutdown(newReqSock, 2);
- (void) close(newReqSock);
- return;
- };
- ReqSocks[nextReq++] = newReqSock;
- };
- continue;
- }
-
- /* Now try to see if a message has arrived on any of the
- Request sockets.
- */
-
- for (sockIndex = 0; sockIndex < nextReq ; sockIndex++) {
- if ( (s = ReqSocks[sockIndex]) <= NULLSOCK ) continue;
- if (s != fSock) continue;
- #ifdef ORIGINAL
- if (fcntl(s, F_SETFL, FASYNC | FNDELAY) < 0 ) {
- perror("KMDRead: fcntl");
- continue;
- };
- status = KMDReceive(s, &MType, &MInt, MString);
- if (fcntl(s, F_SETFL, FASYNC) < 0 ) {
- perror("KMDMsgHandler: fcntl");
- continue;
- };
- if (!mSUCCESS(status)) {
- if (errno == EWOULDBLOCK) continue;
- /* Bad error */
- perror("KMD: socket recv error");
- KMDCleanSock(s);
- continue;
- };
- #else
- if (ioctl(s, FIONREAD, &nreadablebytes) < 0) {
- perror("KMDRead: iocntl");
- continue;
- }
- if (nreadablebytes <= 0) continue;
- status = KMDReceive(s, &MType, &MInt, MString);
- if (!mSUCCESS(status)) {
- /* Bad error */
- perror("KMD: socket recv error");
- KMDCleanSock(s);
- continue;
- };
- #endif
- #else xkernel
- status = KMDReceive((int)ems, &MType, &MInt, MString);
- if (!mSUCCESS(status)) { /* Bad error. who cares */
- if (KMDTest) printf("KMDReceive failed in kmdmsghandler!\n");
- KMDCleanSock((int)ems);
- return;
- }
- if (KMDTest) printf("In KMDMsgHandler, KMDreceived message type %d\n",MType);
- #endif xkernel
-
-
- /* Now start decoding the request: */
- #ifndef xkernel
- somethingHappened = 1;
- #endif
- if (KMDTest) {
- printf("KMDMsgHandler: Type = %d, Int = %d, string = %d\n",
- MType, MInt, MString);
- }
-
- #ifdef xkernel
- SrcSock = (int)ems;
- #else
- SrcSock = s;
- #endif
- switch ( MType ) {
-
- case KMDCTRACE: /* Start trace message */
- KMDStartTrace(MString, MInt, SrcSock, FALSE);
- endcase;
-
- case KMDCUNTRACE: /* Untrace message */
- KMDStopTrace(MString, SrcSock, FALSE);
- endcase;
-
- case KMDCTRACESTDOUT: /* Start trace message */
- KMDStartTrace(MString, MInt, SrcSock, TRUE);
- endcase;
-
- case KMDCUNTRACESTDOUT: /* Untrace message */
- KMDStopTrace(MString, SrcSock, TRUE);
- endcase;
-
- case KMDCSNAPSHOT: /* Do a snapshot */
- if (KMDTest) printf("Starting snapshot.\n");
- if(sscanf(MString, "%s", snapName) != 1) {
- (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "bad snapshot name\n");
- #ifdef xkernel
- return;
- #else
- continue;
- #endif
- };
- for (i=0; MString[i] != ' '; i++);
- snapString = &MString[i+1];
- for (i=0; i < nextSnap ? strcmp(snapName, Snaps[i].name) : 0; i++);
- if (KMDTest) printf(" ... i = %d, nextSnap = %d\n", i, nextSnap);
- if (i == nextSnap) {
- /* Not found: Return error */
- (void) KMDSend(SrcSock, KMDCERRMSG, 0, "Unknown snapshot.\n");
- #ifdef xkernel
- return;
- #else
- continue;
- #endif
- }
- /* Improve performance by using move-to-front for linear list */
- tempSnapElement = Snaps[0];
- Snaps[0] = Snaps[i];
- Snaps[i] = tempSnapElement;
- if (KMDTest) printf(" ... Snapshot sock = %d \n", SrcSock);
- KMDSnapSock = SrcSock;
-
- (*Snaps[0].handler) (MInt, snapString);
-
- (void) KMDSend(KMDSnapSock, KMDCLASTMSG, 0,
- "*** End of Snapshot ***\n");
- KMDSnapSock = NULLSOCK;
- KMDSetFlags();
- endcase;
-
- case KMDCPRINTVAR: /* Print Variable */
- if ( KMDTest ) printf("Printing variable\n");
- ptr = VarLookup(MString);
- if (ptr == (int *) -1) {
- /* Not found, return error */
- (void) KMDSend(SrcSock, KMDCERRMSG, 0,
- "Variable name not found.\n");
- #ifdef xkernel
- return;
- #else
- continue;
- #endif
- };
- KMDShip(SrcSock, "%s = %d (0x%08x)\n", MString, *ptr, *ptr);
- (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "** Done **\n");
- endcase;
-
- case KMDCCHANGEVAR: /* Change value of integer variable */
- if ( KMDTest ) printf("Change variable.\n");
- ptr = VarLookup(MString);
- if (ptr == (int *) -1) {
- /* Not found, return error */
- (void) KMDSend(SrcSock, KMDCERRMSG, 0,
- "Variable name not found.\n");
- #ifdef xkernel
- return;
- #else
- continue;
- #endif
- };
- *ptr = MInt;
- KMDShip(SrcSock, "%s @ 0x%08x changed to %d (0x%08x)\n",
- MString, ptr, *ptr, *ptr);
- (void) KMDSend(SrcSock, KMDCLASTMSG, 0, "** Done **\n");
- KMDSetFlags();
- endcase;
-
- case KMDCLASTMSG: /* Last message */
- KMDCleanSock(SrcSock);
- #ifdef BSD
- (void) shutdown(SrcSock, 2); /* Close down connection */
- (void) close(SrcSock);
- #else
- #ifdef xkernel
- {
- int x;
- x = spl7();
- if(!ems->eof) {
- ems_close(ems);
- }
- splx(x);
- }
- #endif
- #endif
- /* Deallocate request */
- if (KMDTest) printf("Closing connection to %d\n", SrcSock);
- #ifdef CLOSEITSOMEHOW
- #ifndef xkernel
- if (KMDTest) printf("Closing connection to %d\n", SrcSock);
- (void) shutdown(SrcSock, 2); /* Close down connection */
- (void) close(SrcSock);
- /* Deallocate request */
- if (i < --nextReq) {
- ReqSocks[i] = ReqSocks[nextReq];
- };
- #else xkernel
- if (KMDTest) printf("Closing connection to %d\n", SrcSock);
- xclose(((EMSTREAM *)SrcSock)->sessn);
- (EMSTREAM *)SrcSock->sessn = 0;
- #endif
- #endif CLOSEITSOMEHOW
- endcase;
-
- #ifdef NOTIMPLEMENTED
- case KMDCGETBYTES: /* Send back a sequence of bytes */
- MBytes = (long *) MString;
- bufptr = bytebuf;
- if (KMDTest)
- printf("GetBytes: count = %d, data: (0x%08x %d) (0x%08x %d)\n",
- MBytes[0], MBytes[1], MBytes[2], MBytes[3], MBytes[4]);
- for (i=0; i < MBytes[0] ; i++) {
- /* Get a contigous set of bytes */
- from = (char *) (MBytes[2*i+1]);
- size = MBytes[2*i+2];
- bcopy(from, bufptr, size);
- bufptr = bufptr+size;
- };
- size = bufptr - bytebuf;
- (void) KMDSendBlock(NULLSOCK, SrcSock, KMDCBYTES, size, bytebuf,
- NORMALMSG);
- endcase;
- #endif NOTIMPLEMENTED
-
- default:
- if (KMDTest)
- printf("**** KMD: Bad type in incoming KMD msg: %d, int=%d\n",
- MType, MInt);
- (void) KMDSend(SrcSock, KMDCERRMSG, 0,
- "**** Bad KMD msg type ****\n");
- };
- #ifndef xkernel
- if (KMDTest) (void) fflush(stdout);
- #endif
- #ifndef xkernel
- }
- }
- #endif
- }
-
- /*
- *
- * KMDCleanSock
- *
- * Cleans a KMD sock, i.e., removes any traces being sent
- * to the sock.
- */
- void KMDCleanSock( fSock )
- int fSock;
- {
- register int i;
- register TraceElemPtr p, q;
-
- if (KMDTest) printf("KMDCleanSock %d\n", fSock);
- #ifndef xkernel
- /* Traverse the list of traces and remove any that point to the dead sock.*/
- for (i = 0; i < nextReq ; i++) {
- /* Clean out the request socket data structure */
- if ((fSock == ReqSocks[i]) || (ReqSocks[i] == NULLSOCK)) {
- /* Remove from request list */
- SIRemoveSockHandler(fSock, SIREAD);
- SIRemoveSockHandler(fSock, SIWRITE);
- SIRemoveSockHandler(fSock, SIEXCEPT);
- if (i < --nextReq) {
- if (KMDTest) printf("Removing ReqSock[%d] == %d \n", i, ReqSocks[i]);
- ReqSocks[i] = ReqSocks[nextReq];
- /* Now decrement i since the structure has been compacted */
- i--;
- };
- }
- }
- #endif
- /* Clean up the trace data structure */
- for (i=0; i < nextHead ; i++) {
- if (KMDTest) printf(" ... i = %d, name = %s, nextHead = %d\n", i,
- THeads[i].name, nextHead);
- for (p = THeads[i].first, q = NULL; p != NULL; ) {
- if (KMDTest)
- printf(" ... q = 0x%08x, p = 0x%08x, sock = %d, level = %d\n",
- q, p, p->tracesock, p->level);
-
- if ((p->tracesock != fSock) && (p->tracesock != NULLSOCK) ){
- /* Sock ok, advance pointer */
- q=p; p = p->next;
- } else {
- /* The sock has died: remove the trace entry */
- TraceElemPtr BumEntry = p;
- if ( KMDTest )
- printf(" .. Dead Sock cleaning = %d\n", p->tracesock);
- HoldSigs();
- if (q == NULL) { /* First entry */
- p = p->next;
- THeads[i].first = p;
- } else { /* Down the line entry */
- p = q->next = p->next;
- };
- ReleaseSigs();
- if (!strcmp(THeads[i].name, "LineNumber")) {
- emTracing = THeads[i].first != NULL;
- }
- #ifdef xkernel
- if (BumEntry->debugger) debugEnd(BumEntry);
- #endif xkernel
- if (BumEntry->tracesock != NULLSOCK){
- #ifdef BSD
- (void) close(BumEntry->tracesock); /* ignore result */
- #else
- #ifdef xkernel
- ems_close((EMSTREAM *)BumEntry->tracesock); /* ignore result */
- #endif xkernel
- #endif
- }
- kmdfree(BumEntry);
- KMDTraceAct--;
- KMDSetFlags();
- }
- }
- }
- }
-
-
-
- /*
- *
- * PrintVar
- *
- * Print out a given variable
- *
- */
- /* Snapshot */
- /*ARGSUSED*/
- void PrintVar(fInt, fString)
- int fInt;
- char *fString;
- {
- int *ptr;
-
- if ( KMDTest ) printf("Printing variable\n");
- ptr = VarLookup(fString);
- if (ptr == (int *) -1) {
- /* Not found, return error */
- KMDPrint("Variable name %s not found.\n", fString);
- return;
- }
- KMDPrint("%s = %d (0x%08x)\n", fString, *ptr, *ptr);
- }
-
- /*
- *
- * ChangeVar
- *
- * Snapshot to give an integer variable a new value
- *
- */
- /* Snapshot */
- void ChangeVar(fInt, fString)
- int fInt;
- char *fString;
- {
- int *ptr;
-
- if ( KMDTest ) printf("Change variable %s to %d .\n", fString, fInt);
- ptr = VarLookup(fString);
- if (ptr == (int *) -1) {
- /* Not found, return error */
- KMDPrint("Variable name %s not found.\n", fString);
- return;
- }
- *ptr = fInt;
- KMDPrint("%s @ 0x%08x changed to %d (0x%08x)\n", fString, ptr, *ptr, *ptr);
- KMDSetFlags();
- }
-
-
- /*
- *
- * KMDInit
- *
- * KMDInit initializes the KMD part of the Eden kernel
- * resident part.
- *
- */
- void KMDInit(fKMDSockNumber)
- unsigned short fKMDSockNumber; /* in network byte order */
- {
- DebugMsg(5, "KMDInit, KMD port = %d\n", ntohs(fKMDSockNumber));
-
- #ifdef BSD
- KMDRequestSock = socket(AF_INET, SOCK_STREAM, 0);
- if (KMDRequestSock < 0) {
- perror("KMDInit: socket");
- return;
- }
- mySocket.sin_port = fKMDSockNumber;
- if (bind(KMDRequestSock, &mySocket, sizeof(mySocket)) < 0) {
- perror("KMDInit: bind(KMDRequestSock)");
- /* Fatal error so cause a fatal fault */
- * ((int *) 0) = 0;
- }
-
- if (fcntl(KMDRequestSock, F_SETFL, FASYNC | FNDELAY ) < 0) {
- perror("KMDInit: first fcntl");
- }
- if (fcntl(KMDRequestSock, F_SETOWN, getpid()) < 0) {
- perror("KMDInit: second fcntl");
- }
-
- check(listen(KMDRequestSock, 5));
-
- SISetSockHandler(KMDRequestSock, SIREAD, (SIHandlerPtr) SIGIOOccurred);
- SISetSockHandler(KMDRequestSock, SIEXCEPT, (SIHandlerPtr) KMDCleanSock);
- #else BSD
- #ifdef xkernel
- xcontrolprotl(IP,0,(char *)&myipaddr,IPADLEN);
- if((KMDProtl = xcreateprotl(KMDdemux_handler, KMDopendone_handler,
- KMDclosedone_handler)) == -1){
- printf("Can't create KMDProtl in kmdCode.c!\n");
- abort();
- }
- {
- PART part[2];
- TCPaddr me;
-
- me.port = fKMDSockNumber; me.host = myipaddr;
- part[0].address = (char *)&me; part[0].length = TCPADLEN;
- part[1].address = NULL; part[1].length = 0;
- if(xopenenable(KMDProtl, TCP, part) == -1){
- printf("Can't openenable TCP in kmdCode.c!\n");
- abort();
- }
- }
- #endif xkernel
- #endif BSD
-
- /* Define standard traces */
- #undef DebugMsg
- KMDSetTrace(DebugMsg);
- KMDSetTrace(MMTraceMsg);
-
- /* Define KMD snapshots available in this source file */
- KMDSetSnap(Menu);
- KMDSetSnap(Snapshots);
- KMDSetSnap(Traces);
- KMDSetSnap(Variables);
- KMDSetSnap(Flush);
- KMDSetSnap(Help);
- KMDSetSnap(NOP);
- KMDSetSnap(PrintVar);
- KMDSetSnap(ChangeVar);
-
- /* Define a few vars for testing */
- KMDSetVar(DebugLevel);
- KMDSetVar(MMTrace);
-
- /* Local vars in this file */
- KMDSetVar(KMDTraceAct);
- KMDSetVar(KMDTest);
- }
-