home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 418.lha / woodward / woodward.c < prev    next >
C/C++ Source or Header  |  1990-08-06  |  6KB  |  231 lines

  1. /*
  2.  *   This simple little program monitors the files that the `child'
  3.  *   process opens; it can be used for user-level debugging and bug
  4.  *   reporting.  (What files does it *really* try to open?)
  5.  *
  6.  *   The procedure we follow is relatively simple.  We first spawn a
  7.  *   full-fledged process to record the output, since we want to use
  8.  *   the current CLI process to execute our monitored program.  This
  9.  *   process opens either a window or a file, depending on the flags,
  10.  *   to send the output to.
  11.  *
  12.  *   Next, we plug in the WaitPkt ptr of our task with a pointer to a
  13.  *   routine that will actually send a message to our spawned process
  14.  *   that there is information, and then wait for a reply.
  15.  * 
  16.  *   Next, we execute the program we want to monitor.  This is
  17.  *   synchronous, so we wait for it to return.
  18.  *
  19.  *   As soon as this process returns, we can safely restore the old
  20.  *   WaitPkt value, and notify the monitoring process that it can quit.
  21.  *   (The monitoring process will wait for a carriage return from the
  22.  *   window opened before exiting, if and only if no output file was
  23.  *   specified.)
  24.  *
  25.  *   And then we exit.
  26.  *
  27.  *   Acknowledgement to Leo Schwab (for CreateProc hints) and Phillip
  28.  *   Lindsay (for MonProc hints); sections of code lifted freely from
  29.  *   both, but comments removed for brevity.
  30.  *
  31.  *   Compile with Aztec C.
  32.  */
  33. #include <exec/types.h>
  34. #include <libraries/dosextens.h>
  35. #include <functions.h>
  36. struct PhonySegList {
  37.    BPTR psl_NextSeg;
  38.    UWORD psl_JMP;
  39.    LONG (*psl_EntryPoint)();
  40. };
  41. struct PhonySegList template = {0,0x4EF9,0};
  42. char *filename ;
  43. struct MsgPort *mainport, *replyport ;
  44. struct MsgPort *monport ;
  45. struct Lock *currdir ;
  46. #define START (1)
  47. #define DONE (2)
  48. #define FILENAME (3)
  49. struct mymsg {
  50.    struct Message msg ;
  51.    int type ;
  52. } msg ;
  53. #define ACTION_FIND_INPUT (1005)
  54. #define ACTION_FIND_OUTPUT (1006)
  55. struct FileHandle *doswin ;
  56. struct DosPacket *pkt ;
  57. long delayval ;
  58. LONG coprocess()
  59. {
  60.    register struct mymsg *m ;
  61.    register long foo ;
  62.    struct Lock *olddir ;
  63. #ifdef AZTEC_C
  64.    geta4();
  65. #endif
  66.    olddir = CurrentDir(currdir) ;
  67.    mainport = &(((struct Process *)FindTask(0L))->pr_MsgPort) ;
  68.    while (1) {
  69.       while ((m = (struct mymsg *)GetMsg(mainport))==0)
  70.          WaitPort(mainport) ;
  71.       switch(m->type) {
  72. case START:
  73.          m->type = -1 ;
  74.          if ((mainport = CreatePort(0L, 0L)))
  75.             if ((doswin =
  76.      Open((filename?filename:"CON:0/0/320/100/MonFiles"),MODE_NEWFILE))==0)
  77.                 DeletePort(mainport) ;
  78.             else
  79.                 m->type = 0 ;
  80.          break ;
  81. case FILENAME:
  82.          Write(doswin, "`", 1L) ;
  83.          foo = ((long)(pkt->dp_Arg3)) << 2 ;
  84.          Write(doswin, ((char *)foo)+1, (long)*((unsigned char *)foo)) ;
  85.          Write(doswin, pkt->dp_Type==ACTION_FIND_INPUT?"' (r)":"' (w)", 5L) ;
  86.          if (pkt->dp_Res1)
  87.             Write(doswin, " succeeded\n", 11L) ;
  88.          else
  89.             Write(doswin, " failed\n", 8L) ;
  90.          m->type = 0 ;
  91.          if (delayval > 3)
  92.             Delay(delayval) ;
  93.          break ;
  94. case DONE:
  95. default:
  96.          m->type = -1 ;
  97.       }
  98.       if (m->type) {
  99.          if (filename == 0)
  100.             Delay(100L) ;
  101.          if (doswin) {
  102.             Close(doswin);
  103.             doswin = 0 ;
  104.          }
  105.          if (mainport) {
  106.             DeletePort(mainport) ;
  107.             mainport = 0 ;
  108.          }
  109.          CurrentDir(olddir) ;
  110.          Forbid() ;
  111.          ReplyMsg(m) ;
  112.          return(0) ;
  113.       } else {
  114.          ReplyMsg(m) ;
  115.       }
  116.    }
  117. }
  118. #ifdef AZTEC_C
  119. long PWait() ;
  120. #else
  121. #define PWait PacketWait
  122. #endif
  123. /*
  124.  *   This is the task that actually replaces PacketWait.
  125.  */
  126. #define DOS_MASK (1L << 8)
  127. struct Message *PacketWait() {
  128.    register struct Message *dmsg ;
  129. #ifdef AZTEC_C
  130.    geta4() ;
  131. #endif
  132.    SetSignal(-1L, DOS_MASK) ;
  133.    while ((dmsg = GetMsg(monport))==0)
  134.       Wait(DOS_MASK) ;
  135.    pkt = (struct DosPacket *)(dmsg->mn_Node.ln_Name) ;
  136.    if (pkt->dp_Type == ACTION_FIND_INPUT ||
  137.        pkt->dp_Type == ACTION_FIND_OUTPUT)
  138.       putmsg(FILENAME) ;
  139.    return dmsg ;
  140. }
  141. int putmsg(what)
  142. int what ;
  143. {
  144.    msg.type = what ;
  145.    msg.msg.mn_Node.ln_Type = NT_MESSAGE;
  146.    msg.msg.mn_Node.ln_Pri = 0;
  147.    msg.msg.mn_ReplyPort = replyport;
  148.    PutMsg(mainport, &msg);
  149.    WaitPort(replyport) ;
  150.    GetMsg(replyport) ;
  151.    return msg.type ;
  152. }
  153. main(argc, argv)
  154. int argc ;
  155. char *argv[] ;
  156. {
  157.    struct PhonySegList *fakelist = 0 ;
  158.    struct Process *me ;
  159.    LONG priority;
  160.    APTR opktwait ;
  161.    register char *p ;
  162.    register int option ;
  163.  
  164.    if (argc > 1 && argv[1][0] == '-') {
  165.       argv++ ;
  166.       argc-- ;
  167.       option = argv[0][1] ;
  168.       p = argv[0] + 2 ;
  169.       if (*p == 0 && argc > 1) {
  170.          argv++ ;
  171.          argc-- ;
  172.          p = *argv ;
  173.       }
  174.       switch (option) {
  175. case 'o': case 'O':
  176.          filename = p ;
  177.          break ;
  178. case 'd': case 'D':
  179.          delayval = atol(p) ;
  180.          break ;
  181. default:
  182.          Write(Output(), "No such option\n", 15L) ;
  183.       }
  184.    }
  185.    if (((replyport = CreatePort(0L, 0L))==0) ||
  186.        ((fakelist = AllocMem((LONG)sizeof(*fakelist), 0L))==0))
  187.       goto xit;
  188.    CopyMem(&template, fakelist,(LONG)sizeof(template));
  189.    fakelist->psl_EntryPoint = coprocess;
  190.    me = (struct Process *)FindTask(0L);
  191.    monport = &(me->pr_MsgPort) ;
  192.    priority = me->pr_Task.tc_Node.ln_Pri;
  193.    currdir = Lock("", SHARED_LOCK) ;
  194.    if ((struct MsgPort *)
  195.           CreateProc("MonFiles2", priority, ((LONG)fakelist) >> 2, 4096L)==0)
  196.       goto xit;
  197.    if (putmsg(START))
  198.       goto xit ;
  199.    Forbid() ;
  200.    opktwait = me->pr_PktWait ;
  201.    me->pr_PktWait = (APTR)PWait ;
  202.    Permit() ;
  203. #ifdef AZTEC_C
  204.    fexecv(argv[1], argv+1) ;
  205. #else
  206.    I don't know how to do this in Lattice yet
  207.    The spawned process has to execute in the *same CLI*
  208. #endif
  209.    Forbid() ;
  210.    me->pr_PktWait = opktwait ;
  211.    Permit() ;
  212.    putmsg(DONE) ;
  213.    if (currdir)
  214.       UnLock(currdir) ;
  215. xit:
  216.    if (fakelist) FreeMem(fakelist,(LONG)sizeof(*fakelist));
  217.    if (replyport) DeletePort(replyport);
  218. }
  219. #ifdef AZTEC_C
  220. _wb_parse() {}
  221. #asm
  222.     XREF    _PacketWait
  223.     XDEF    _PWait
  224. _PWait:
  225.     movem.l    a2/a3/a4,-(sp)
  226.     jsr    _PacketWait
  227.     movem.l    (sp)+,a2/a3/a4
  228.     rts
  229. #endasm
  230. #endif
  231.