/*
 * SUBPROCS - Support for managing subprocesses and communicating with them
 *
 * Author:
 * Emile van Bergen, emile@evbergen.xs4all.nl
 *
 * Permission to redistribute an original or modified version of this program
 * in source, intermediate or object code form is hereby granted exclusively
 * under the terms of the GNU General Public License, version 2. Please see the
 * file COPYING for details, or refer to http://www.gnu.org/copyleft/gpl.html.
 *
 * History:
 * 2001/07/18 - EvB - Created all over based on test/newproctest.c
 * 2002/03/19 - EvB - Added support for custom working directory
 * 2003/06/23 - EvB - Changed ring size to C_MAX_MSGSIZE instead of fixed value
 */


#ifndef __SUBPROCS_H
#define __SUBPROCS_H	1


/*
 * INCLUDES & DEFINES
 */

#include <sys/select.h>		/* for fd_set */

#include <platform.h>		/* for U_INT32_T */
#include <constants.h>
#include <misc.h>
#include <ringbuf.h>
#include <metatype.h>


/* Process states */

#define PRS_IDLE		0	/* Started and waiting for message */
#define PRS_SENDING		1
#define PRS_RECEIVING		2
#define PRS_XFERING		3	/* Sending + Receiving */
#define PRS_WAITING		4	/* Created and waiting for start sign */
#define PRS_STARTING		8	/* Attempted to start but retrying */
#define PRS_KILLING		0x10	/* Between sent TERM and recvd. CHLD */

#define PRS_ISRUNNING(state)	((state) <= 3)


/* Environment */

#define PR_ENV_VARS		2

#define PR_ENV_IFACEVER		"RADIUSINTERFACEVERSION="
#define PR_ENV_IFACEFLAGS	"RADIUSINTERFACEFLAGS=0x"


/* Ring size - send/receive window, really */

#define PR_RING_SIZE		C_MAX_MSGSIZE


/* Timers */

#define PRT_RETRYSTART		5	/* time before trying to start again */
#define PRT_RESTART		2	/* time before restarting after end */
#define PRT_XFERTIMEOUT		10	/* default watchdog time for procs */
#define PRT_END			5	/* time before SIGKILL if TERM fails */


/* Some useful constants */

#define PIPE_R			0	/* Reading end of a pipe */
#define PIPE_W			1	/* Writing end of a pipe */


/*
 * TYPES
 */


/* One process */

typedef struct proc {
	struct proc *next;	/* next in list of all processes */
	struct chan *chan;	/* interface channel it's associated with */

	char *cmd;		/* free this */
	char **argv;		/* free this but don't free the elements */
	char **envp;		/* free this and do free the elements */
	char *cwd;		/* free this */
	pid_t pid;

	RING *r, *w;		/* free these */
	int rfd, wfd;

	int flags, xfertimeout, expectedlen;
	time_t timer;
	int state;
} PROC;


/* Set of processes */

typedef struct proc_set {

	PROC *p;
	fd_set rfds, wfds;
	int highestfd;
	time_t firsttimer;

} PROC_SET;


/*
 * PROTOTYPES
 */


PROC *proc_new(char *cmdline, int cmdlinelen, int flags, int xfertimeout, 
	       struct chan *chan, char *basepath, char *progcwd);
void proc_del(PROC *p);

int proc_start(PROC *p, time_t t);
void proc_stop(PROC *p, time_t t);

ssize_t have_binmsg_inring(RING *r, U_INT32_T magic);
ssize_t have_ascline_inring(RING *r);

void proc_handle_read(PROC *p, time_t t);
void proc_handle_write(PROC *p, time_t t);
void proc_handle_timeout(PROC *p, time_t t);
void proc_handle_end(PROC *p, time_t t, int exitcode);


#endif



syntax highlighted by Code2HTML, v. 0.9.1