/* getprocs.c - Grab all available processes and return them to you in a
 * 		simple exec list. The list is made up of  nodes--the "name"
 *	 	fields pointing to the process structure. 
 *
 * 	 Phillip Lindsay (c) 1987 Commodore-Amiga Inc. 
 * You may use this source as long as the copyright notice is left intact.
 */

#include <exec/types.h>
#include <exec/nodes.h>
#include <exec/lists.h>
#include <exec/memory.h>
#include <exec/tasks.h>
#include <exec/execbase.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/filehandler.h>

#ifdef MANX
#include <functions.h>
#include <stdio.h>
#else
#include <lattice/stdio.h>
#endif

/* getnode() will allocate a node structure for you. And initialize the node
 * structure with the given values.
 */   	
struct Node *getnode(name,type,pri)
char *name;
UBYTE type,pri;
{
 register struct Node *mynode;

 mynode = (struct Node *) 
  AllocMem((ULONG)sizeof(*mynode),MEMF_PUBLIC | MEMF_CLEAR); 

 if(!mynode) return((struct Node *)NULL);
 
 mynode->ln_Name = name;
 mynode->ln_Type = type;
 mynode->ln_Pri  = pri;

 return(mynode);
}

/* freenode() frees a given Exec node. 
 * Make sure you remove node from any list. 
 */
void freenode(mynode)
struct Node *mynode;
{
 FreeMem(mynode,(ULONG)sizeof(*mynode));
}


/* getprocs() will grab all processes in the system task's list and
 *  append an exec node to a given list. The node name field filled
 *  with a pointer to the process strcuture. 
 * WARNING: This isn't a casual subroutine. The returned list is valid as
 * long as a process is not ended or added after this subroutine is
 * called. To be real safe you should probably check to see if the
 * process is still around before trying to look at the data structure.  
 */
void getprocs(plist)
struct List *plist;	/* passed a pointer to a initialized exec list */ 
{
 extern   struct ExecBase 	  *SysBase;
 register struct ExecBase	  *execbase=SysBase;
 register struct List		  *proclist;
 register struct Node 		  *aproc,*bproc;
 register USHORT		  count=0;

/* I haven't clocked this code, but you shouldn't as a rule stay disabled for
 * no more than 250ms. I'm have no doubt I'm illegal, but you can't be
 * too safe when dealing with something that changes with a blink of a
 * interrupt.
 */

 Disable();

/* first we deal with ourselves... */
 if(execbase->ThisTask->tc_Node.ln_Type == NT_PROCESS)
  {
   if((bproc=getnode(execbase->ThisTask,0,0)))
    {
     AddTail(plist,bproc);
    }
  }

/* hopefully the added braces make the flow clear */
 for(;count <= 1;count++)
  {
   if(!count) 
    proclist = &execbase->TaskReady;
   else
    proclist = &execbase->TaskWait;

   if(proclist->lh_TailPred != proclist)
    {
     for(aproc = proclist->lh_Head;aproc->ln_Succ;aproc=aproc->ln_Succ)
      { 
       if(aproc->ln_Type == NT_PROCESS)
        { 
         if((bproc=getnode(aproc,0,0)))
          {
           AddTail(plist,bproc);
          }
        }
      }
    }    
  }

 Enable();

} /* end of getprocs() */


/* freeprocs() will free all nodes in a given list. Function assumes nodes where
 *    initialized with getnode().
 */
void freeprocs(plist)
struct List *plist;
{
 register struct Node *proc;

 while((proc=RemTail(plist)))
  freenode(proc);
}

/*
main()
 {
  struct List    procs;
  struct Node    *proc;
 
  NewList(&procs);	** Initialize list header **
  getprocs(&procs);	** Fill list **

 ** print any processess in list.... if any **
   if(procs.lh_TailPred != &procs)
    for(proc = procs.lh_Head;proc->ln_Succ;proc=proc->ln_Succ)
     puts( ((struct Process *)proc->ln_Name)->pr_Task.tc_Node.ln_Name );
     
   freeprocs(&procs);
 }
 
*/

