/*************************************************

DML_child.h

introduces the DML_child and DML_master classes. 
Provides functions for handling child processes.

resources used:  This makes use of the SIGCHLD signal:
				 DO NOT attempt to use this signal yourself. 

other notes:
	1.) IF a particular process happens to be an intermediate master, i.e.
		it is created by a master process and has children of its own, in order
		to properly handle the death of children, it should declare its DML_child
		objects BEFORE declaring its DML_master object.
		
	2.) if you are passing (argv) as a list of arguments to a child to be created,
		be sure that your prototype for main() is as follows:
		void main( int argc, char *argv[])
		or
		void main( int argc, const char *argv[])		
		
		if your prototype looks like this: void main( void )
		then you can pass the arguments EVEN THOUGH you didn't declare them, as follows:
		extern char *_argv[];
		and pass this one. (QNX global data...)
				
Author: Ryan Findley


History:
who	when		what
--------------------------------
ryan	5/10/99		started
ryan	5/12/99		lots of changes: added child death handlers, alternate constructors etc.
ryan	7/29/99		changed to be a derivative of DML_process class.
					changed some nomenclature, tested for stability
ryan	8/4/99		added support for passing arguments.
ryan	8/25/99		changed array-of-children to linked-list-of-children
					found problem with flags: built it in to open (now the only way to open is P_NOWAIT).
***************************************************/

#ifndef CHILD_HPP
#define CHILD_HPP


#include <sys/proxy.h>
#include "DML_process.h"


//------------------- definitions --------------------
#define QUIET 1
#define LOUD  0
#define MAX_CHILD_NAME_LENGTH 48
#define WAIT_RESPONSE 1
#define DONT_WAIT 0

//------------------- typedefs -----------------------


//structure used to pass info back and forth to the child.
typedef struct 
{
    pid_t proxy;
    int priority;
    int verbosity;
    
} childInfoStruct;

//------------------- public prototypes --------------



//------------------- class definitions --------------

//Now remember, the Master process creates an instance of the child class to talk to the child,
//and the child process creates an instance of the master class.   :-)
class DML_child : public DML_process
{
  public:
    pid_t proxy;						//a proxy attached to the child
    char name[MAX_CHILD_NAME_LENGTH+1];	//the file from which the child came
	        
    DML_child();						//creates a blank child instance
	DML_child(const char * theName);	//creates child, no args, QUIET, and DONT_WAIT.
	DML_child(const char * theName,
		int waitForResponse );			//specify it to wait for a response
    DML_child(const char * theName, 	//creates a child instance from file "name"
		const char *theArgv[],
		int waitforResponse = WAIT_RESPONSE,
		int theVerbosity = QUIET);
    ~DML_child();						//destructor
    
	setArgs( char const *[] );			//sets the child's arguments
    open(const char * theName);			//starts the child process running.
    sendInfoMsg();						//sends the info message to the process, gets the reply
    int beQuiet();						//suppresses printf messages in member functions. returns previous verbosity.
    									//passes on low verbosity to child, but the child is free to do with it as it pleases.
    int beLoud();						//opposite of beQuiet. returns previous verbosity
    
    attachProxy();						//attaches a proxy to the child
    int kick();							//triggers the proxy which is attached to the child.
    DML_child & print();				//prints info about the child.
	
	    
    static killChildren();
    static printChildren();	
	
			  
  private:
    const 	char **	localArgv;			//the child's arguments
    childInfoStruct msg, rmsg;			//used for messaging
    int 			verbosity;			//child can use this to determine whether or not to be verbose
	
    DML_child *		next;				//next child in list
	DML_child *		prev;				//previous child in list
	
	static DML_child *	childList; 		//pointer to first child
	static void 		childDeathHandler(int); 
};


class DML_master : public DML_process
{
public: 
    pid_t proxy;		//this is the proxy that the MASTER will use to kick the child
    int verbosity;

    DML_master();		//default constructor
    sendInfoMsg();		//gets that nefarious info message that a new child and master communicate with.
	    
};
	
#endif  //CHILD_HPP