home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
418.lha
/
woodward
/
woodward.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-08-06
|
6KB
|
231 lines
/*
* This simple little program monitors the files that the `child'
* process opens; it can be used for user-level debugging and bug
* reporting. (What files does it *really* try to open?)
*
* The procedure we follow is relatively simple. We first spawn a
* full-fledged process to record the output, since we want to use
* the current CLI process to execute our monitored program. This
* process opens either a window or a file, depending on the flags,
* to send the output to.
*
* Next, we plug in the WaitPkt ptr of our task with a pointer to a
* routine that will actually send a message to our spawned process
* that there is information, and then wait for a reply.
*
* Next, we execute the program we want to monitor. This is
* synchronous, so we wait for it to return.
*
* As soon as this process returns, we can safely restore the old
* WaitPkt value, and notify the monitoring process that it can quit.
* (The monitoring process will wait for a carriage return from the
* window opened before exiting, if and only if no output file was
* specified.)
*
* And then we exit.
*
* Acknowledgement to Leo Schwab (for CreateProc hints) and Phillip
* Lindsay (for MonProc hints); sections of code lifted freely from
* both, but comments removed for brevity.
*
* Compile with Aztec C.
*/
#include <exec/types.h>
#include <libraries/dosextens.h>
#include <functions.h>
struct PhonySegList {
BPTR psl_NextSeg;
UWORD psl_JMP;
LONG (*psl_EntryPoint)();
};
struct PhonySegList template = {0,0x4EF9,0};
char *filename ;
struct MsgPort *mainport, *replyport ;
struct MsgPort *monport ;
struct Lock *currdir ;
#define START (1)
#define DONE (2)
#define FILENAME (3)
struct mymsg {
struct Message msg ;
int type ;
} msg ;
#define ACTION_FIND_INPUT (1005)
#define ACTION_FIND_OUTPUT (1006)
struct FileHandle *doswin ;
struct DosPacket *pkt ;
long delayval ;
LONG coprocess()
{
register struct mymsg *m ;
register long foo ;
struct Lock *olddir ;
#ifdef AZTEC_C
geta4();
#endif
olddir = CurrentDir(currdir) ;
mainport = &(((struct Process *)FindTask(0L))->pr_MsgPort) ;
while (1) {
while ((m = (struct mymsg *)GetMsg(mainport))==0)
WaitPort(mainport) ;
switch(m->type) {
case START:
m->type = -1 ;
if ((mainport = CreatePort(0L, 0L)))
if ((doswin =
Open((filename?filename:"CON:0/0/320/100/MonFiles"),MODE_NEWFILE))==0)
DeletePort(mainport) ;
else
m->type = 0 ;
break ;
case FILENAME:
Write(doswin, "`", 1L) ;
foo = ((long)(pkt->dp_Arg3)) << 2 ;
Write(doswin, ((char *)foo)+1, (long)*((unsigned char *)foo)) ;
Write(doswin, pkt->dp_Type==ACTION_FIND_INPUT?"' (r)":"' (w)", 5L) ;
if (pkt->dp_Res1)
Write(doswin, " succeeded\n", 11L) ;
else
Write(doswin, " failed\n", 8L) ;
m->type = 0 ;
if (delayval > 3)
Delay(delayval) ;
break ;
case DONE:
default:
m->type = -1 ;
}
if (m->type) {
if (filename == 0)
Delay(100L) ;
if (doswin) {
Close(doswin);
doswin = 0 ;
}
if (mainport) {
DeletePort(mainport) ;
mainport = 0 ;
}
CurrentDir(olddir) ;
Forbid() ;
ReplyMsg(m) ;
return(0) ;
} else {
ReplyMsg(m) ;
}
}
}
#ifdef AZTEC_C
long PWait() ;
#else
#define PWait PacketWait
#endif
/*
* This is the task that actually replaces PacketWait.
*/
#define DOS_MASK (1L << 8)
struct Message *PacketWait() {
register struct Message *dmsg ;
#ifdef AZTEC_C
geta4() ;
#endif
SetSignal(-1L, DOS_MASK) ;
while ((dmsg = GetMsg(monport))==0)
Wait(DOS_MASK) ;
pkt = (struct DosPacket *)(dmsg->mn_Node.ln_Name) ;
if (pkt->dp_Type == ACTION_FIND_INPUT ||
pkt->dp_Type == ACTION_FIND_OUTPUT)
putmsg(FILENAME) ;
return dmsg ;
}
int putmsg(what)
int what ;
{
msg.type = what ;
msg.msg.mn_Node.ln_Type = NT_MESSAGE;
msg.msg.mn_Node.ln_Pri = 0;
msg.msg.mn_ReplyPort = replyport;
PutMsg(mainport, &msg);
WaitPort(replyport) ;
GetMsg(replyport) ;
return msg.type ;
}
main(argc, argv)
int argc ;
char *argv[] ;
{
struct PhonySegList *fakelist = 0 ;
struct Process *me ;
LONG priority;
APTR opktwait ;
register char *p ;
register int option ;
if (argc > 1 && argv[1][0] == '-') {
argv++ ;
argc-- ;
option = argv[0][1] ;
p = argv[0] + 2 ;
if (*p == 0 && argc > 1) {
argv++ ;
argc-- ;
p = *argv ;
}
switch (option) {
case 'o': case 'O':
filename = p ;
break ;
case 'd': case 'D':
delayval = atol(p) ;
break ;
default:
Write(Output(), "No such option\n", 15L) ;
}
}
if (((replyport = CreatePort(0L, 0L))==0) ||
((fakelist = AllocMem((LONG)sizeof(*fakelist), 0L))==0))
goto xit;
CopyMem(&template, fakelist,(LONG)sizeof(template));
fakelist->psl_EntryPoint = coprocess;
me = (struct Process *)FindTask(0L);
monport = &(me->pr_MsgPort) ;
priority = me->pr_Task.tc_Node.ln_Pri;
currdir = Lock("", SHARED_LOCK) ;
if ((struct MsgPort *)
CreateProc("MonFiles2", priority, ((LONG)fakelist) >> 2, 4096L)==0)
goto xit;
if (putmsg(START))
goto xit ;
Forbid() ;
opktwait = me->pr_PktWait ;
me->pr_PktWait = (APTR)PWait ;
Permit() ;
#ifdef AZTEC_C
fexecv(argv[1], argv+1) ;
#else
I don't know how to do this in Lattice yet
The spawned process has to execute in the *same CLI*
#endif
Forbid() ;
me->pr_PktWait = opktwait ;
Permit() ;
putmsg(DONE) ;
if (currdir)
UnLock(currdir) ;
xit:
if (fakelist) FreeMem(fakelist,(LONG)sizeof(*fakelist));
if (replyport) DeletePort(replyport);
}
#ifdef AZTEC_C
_wb_parse() {}
#asm
XREF _PacketWait
XDEF _PWait
_PWait:
movem.l a2/a3/a4,-(sp)
jsr _PacketWait
movem.l (sp)+,a2/a3/a4
rts
#endasm
#endif