/* ******************************************************************************* * Copyright (c) 1997 Martin Poole ******************************************************************************* ** ** WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! ** ** Any changes to be made to this file should first be checked with ** mplib1 source control for library integrity. ** ** mplib1 source control can be reached at mplib1@quatermass.co.uk ** * * $Source: /home/cvs/cvsroot/onelan/onelan/src/mplib1/util/watch_run.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:30 $ * $Revision: 1.2 $ * ******************************************************************************* * * Change History * * $Log: watch_run.c,v $ * Revision 1.2 2002/10/07 09:37:30 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:37:09 mpoole * Initial checkin of mplib1-3.1.0 * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/util/watch_run.c,v 1.2 2002/10/07 09:37:30 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "watchdog.h" /* ------------------------------------------------------------------ structures / defines ------------------------------------------------------------------ */ static int watch_run_debug=0; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static void set_env_variable( const char *name, const char *val ) { char *nep, obuf[500]; if (name && *name && val && *val) { sprintf( obuf, "%s=%s", name, val ); nep = strdup(obuf); putenv( nep ); } return; } static void load_env_file( const char *envname ) { char tbuf[255]; FILE *fp; char *nep; if ( (fp=fopen(envname, "r" )) ) { while (fgetline2( fp, tbuf, 255 ) ==0) { if (strchr( tbuf, '=' )) { nep = strdup(tbuf); putenv( nep ); } } fclose(fp); } return; } static int add_pid_track( struct program_hdr *pptr, int exp_time ) { struct pid_track *ptp; int rv=0; ptp = alloc_pid_track( pptr, exp_time ); if (ptp) { rv=1; } return(rv); } static int add_this_pid_track( struct program_hdr *pptr, pid_t the_pid ) { struct pid_track *ptp; int rv=0; ptp = alloc_pid_track( pptr, 0 ); if (ptp) { /* Now update the status of this track */ ptp->starting=0; ptp->dying = 0; ptp->the_pid = the_pid; ptp->track_by_pid=1; gen_pid_str( ptp->pid_str, the_pid ); rv=1; } return(rv); } static int is_dir( const char *dir_name ) { struct stat d_stat; int rv=0; if (stat(dir_name,&d_stat)==0) { rv = S_ISDIR(d_stat.st_mode); } return(rv); } int start_this_program( int nbr_to_start, struct program_hdr *pptr, const char *env_name, const char *out_name, const char *err_name, const char *run_dir, int exp_time, int track_by_pid ) { pid_t child_pid; int nbr_started=0; struct argv_track *argvtp; char *rdir; watch_run_debug = get_config_flag("WATCH_RUN_DEBUG"); exp_time = get_default_int( exp_time, "START_HYSTERESIS", 15 ); if (watch_run_debug) { fprintfile( stderr, "start_this_program: %s (%s %s) %d copies\n", pptr->prg_name, pptr->exe_name, pptr->opt_name, nbr_to_start ); } if (pptr->env_name && *pptr->env_name) env_name = pptr->env_name; if (pptr->out_name && *pptr->out_name) out_name = pptr->out_name; if (pptr->err_name && *pptr->err_name) err_name = pptr->err_name; if (exp_time<1) exp_time=2; argvtp = build_argv_track( NULL, pptr->exe_name, pptr->opt_name, NULL ); if (argvtp) { while(nbr_to_start--) { /* First we fork */ child_pid = fork(); if (child_pid == (pid_t)0) { /* OK so set things up and exec */ if (env_name && *env_name) load_env_file( env_name ); if (pptr->grp_name) set_env_variable( "PROGRAM_GROUP", pptr->grp_name ); if (pptr->prg_name) set_env_variable( "PROGRAM_NAME", pptr->prg_name ); restart_these_files( NULL, out_name, err_name ); if ( pptr->run_dir && *pptr->run_dir && (rdir=eval_config_default(NULL,pptr->run_dir)) && is_dir(rdir) ) { if (chdir(run_dir)) { fprintfile( stderr, "Unable to chdir %s<%d>\n", rdir, errno ); } }else if ( run_dir && *run_dir && is_dir(run_dir) ) { if (chdir(run_dir)) { fprintfile( stderr, "Unable to chdir %s<%d>\n", run_dir, errno ); } } execvp( pptr->exe_name, argvtp->argv ); fprintfile( stderr, "Unable to exec %s\n", pptr->prg_name ); exit(1); }else if (child_pid > (pid_t)0) { /* Add a program_pid entry */ nbr_started++; if (track_by_pid) add_this_pid_track( pptr, child_pid ); else add_pid_track( pptr, exp_time ); }else { fprintfile( stderr, "Unable to fork for %s\n", pptr->prg_name ); } }; free_argv_track(argvtp); } return(nbr_started); } void start_some_program( struct program_hdr *pptr, int copies ) { char *env_name,*out_name,*err_name,*run_dir; int stime; stime = pptr->startup; /* need to start some more */ env_name = strdup( eval_config_default( "ENVIRONMENT", "$HOME/config/environment" ) ); err_name = strdup( eval_config_default( "NEWSTDERR", "/dev/null" )); out_name = strdup( eval_config_default( "NEWSTDOUT", "/dev/null" )); run_dir = strdup( eval_config_default( "RUN_DIR", "." )); start_this_program( copies, pptr, env_name, out_name, err_name, run_dir, stime, pptr->track_by_pid ); free( run_dir ); free( out_name ); free( err_name ); free( env_name ); return; } /* -- End of File -- */