From 214f6947f71faecf11cc8bb43ff89028d7b97dd5 Mon Sep 17 00:00:00 2001 From: Thibault Godouet Date: Sun, 11 Jun 2000 13:18:35 +0000 Subject: [PATCH] job based on system up time are now handle in a way similar to normal job --- database.c | 168 +++++++++-------------------------------------------- fcron.c | 103 ++++++++++++-------------------- fcron.h | 8 +-- global.h | 12 ++-- job.c | 44 +++++++------- 5 files changed, 96 insertions(+), 239 deletions(-) diff --git a/database.c b/database.c index a14f351..b34bd01 100644 --- a/database.c +++ b/database.c @@ -22,7 +22,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: database.c,v 1.7 2000-06-03 20:28:34 thib Exp $ */ + /* $Id: database.c,v 1.8 2000-06-11 13:18:35 thib Exp $ */ #include "fcron.h" @@ -40,38 +40,23 @@ test_jobs(time_t t2) debug("Looking for jobs to execute ..."); - /* job based on date & time */ while ( (j=queue_base) && j->j_line->cl_nextexe <= t2 ){ set_next_exe(j->j_line, 0); if (--(j->j_line->cl_remain) > 0) { - debug(" cl_Remain: %d", j->j_line->cl_remain); + debug(" cl_remain: %d", j->j_line->cl_remain); continue ; } - if (j->j_line->cl_pid > 0) { - warn(" process already running: %s '%s'", - j->j_line->cl_file->cf_user, - j->j_line->cl_shell - ); - j->j_line->cl_remain = j->j_line->cl_runfreq; - } - else { - j->j_line->cl_remain = j->j_line->cl_runfreq; - run_job(j->j_line); - } - } - /* job based on frequency */ - while ( (j=freq_base) && j->j_line->cl_remain <= 0 ){ - j->j_line->cl_remain = j->j_line->cl_timefreq; - insert_freq(j->j_line); + j->j_line->cl_remain = j->j_line->cl_runfreq; + if (j->j_line->cl_pid > 0) { warn(" process already running: %s '%s'", j->j_line->cl_file->cf_user, j->j_line->cl_shell ); - } else { + } + else run_job(j->j_line); - } } } @@ -279,11 +264,9 @@ set_next_exe(CL *line, char is_new_line) struct tm *ft; struct tm ftime; - time_t now; register int i; int max; - now = time(NULL); ft = localtime(&now); /* localtime() function seem to return every time the same pointer : @@ -371,21 +354,30 @@ set_next_exe(CL *line, char is_new_line) line->cl_nextexe = mktime(&ftime); - insert_nextexe(line); - - debug(" cmd: '%s' next exec %d/%d/%d wday:%d %02d:%02d", - line->cl_shell, (ftime.tm_mon + 1), ftime.tm_mday, - (ftime.tm_year + 1900), ftime.tm_wday, - ftime.tm_hour, ftime.tm_min); + if ( ! is_new_line ) + debug(" cmd: '%s' next exec %d/%d/%d wday:%d %02d:%02d", + line->cl_shell, (ftime.tm_mon + 1), ftime.tm_mday, + (ftime.tm_year + 1900), ftime.tm_wday, + ftime.tm_hour, ftime.tm_min); - } + else { + /* this is a job based on system up time */ + line->cl_nextexe = now + line->cl_timefreq; + debug(" cmd: '%s' next exec in %lds", line->cl_shell, + line->cl_timefreq); + } + + + insert_nextexe(line); + + } void insert_nextexe(CL *line) - /* insert a job based on time and date in the corresponding queue list */ + /* insert a job the queue list */ { struct job *newjob = NULL; @@ -443,126 +435,24 @@ insert_nextexe(CL *line) } -void -insert_freq(CL *line) - /* insert a job based on frequency in the corresponding queue list * - * if the job was already in the queue list, move it to the right rank. */ -{ - struct job *newjob = NULL; - - /* insert job in the queue */ - if (freq_base != NULL) { - struct job *j = NULL; - struct job *jprev = NULL; - struct job *old_entry = NULL; - - /* find the job in the list */ - for (j = freq_base; j != NULL ; j = j->j_next) - if ( j->j_line == line ) { - old_entry = j; - /* remove it from the list */ - if (jprev != NULL) { - jprev->j_next = j->j_next; - j = jprev; - } - else - /* first element of the list */ - j = freq_base = j->j_next; - - break; - } - - if ( j == NULL || line->cl_remain < j->j_line->cl_remain) - j = freq_base; - while (j != NULL && (line->cl_remain >= j->j_line->cl_remain)) { - jprev = j; - j = j->j_next; - } - - if (old_entry == NULL) { - /* this job wasn't in the queue : we append it */ - Alloc(newjob, job); - newjob->j_line = line; - } - else - /* this job was already in the queue : we move it */ - newjob = old_entry; - - newjob->j_next = j; - - if (jprev == NULL) - freq_base = newjob; - else - jprev->j_next = newjob; - } - else { - Alloc(newjob, job); - newjob->j_line = line; - freq_base = newjob; - } -} - long -time_to_sleep(short lim) +time_to_sleep(time_t lim) /* return the time to sleep until next task have to be executed. */ { /* we set tts to a big value, unless some problems can occurs * with files without any line */ time_t tts = lim; - time_t now; - now = time(NULL); - - if (queue_base == NULL && freq_base == NULL) - /* no lines : we sleep as much as we can, so how much lim permits us */ - goto end; - else if (queue_base == NULL && freq_base != NULL) { - tts = freq_base->j_line->cl_remain; - goto end; - } - else if (queue_base != NULL && freq_base == NULL) { - if ( (tts = queue_base->j_line->cl_nextexe - now) < 0 ) tts = 0; - goto end; + if ( queue_base != NULL ) { + if ( queue_base->j_line->cl_nextexe < lim ) + tts = queue_base->j_line->cl_nextexe; } - /* we have freq lines and normal lines */ - if(queue_base->j_line->cl_nextexe - now < freq_base->j_line->cl_remain) { - if ( (tts = queue_base->j_line->cl_nextexe - now) < 0 ) tts = 0; - } - else - tts = freq_base->j_line->cl_remain; - - end: - if (tts > lim) - tts = lim; + if ( (tts = tts - now) < 0) + tts = 0; debug("Time to sleep: %lds", tts); return tts; } - - -void -update_time_remaining(long dt) - /* update the remaining time of tasks run at a certain frequency */ -{ - - struct job *j = freq_base; - - debug("Updating time remaining ..."); - - for (j=freq_base; j != NULL; j = j->j_next ) { - - if ( (j->j_line->cl_remain - dt) >= 0 ) - j->j_line->cl_remain -= dt; - else - j->j_line->cl_remain = 0; - - debug(" '%s' cl_remain = %d", j->j_line->cl_shell, - j->j_line->cl_remain); - - } - -} - diff --git a/fcron.c b/fcron.c index 040e822..4c76511 100644 --- a/fcron.c +++ b/fcron.c @@ -21,11 +21,11 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: fcron.c,v 1.10 2000-06-04 12:07:50 thib Exp $ */ + /* $Id: fcron.c,v 1.11 2000-06-11 13:18:55 thib Exp $ */ #include "fcron.h" -char rcs_info[] = "$Id: fcron.c,v 1.10 2000-06-04 12:07:50 thib Exp $"; +char rcs_info[] = "$Id: fcron.c,v 1.11 2000-06-11 13:18:55 thib Exp $"; void main_loop(void); void info(void); @@ -49,17 +49,17 @@ pid_t daemon_pid; char *prog_name = NULL; /* have we got a signal ? */ -char sig_conf = 0; /* is 1 when we got a SIGHUP */ +char sig_conf = 0; /* is 1 when we got a SIGHUP, 2 for a SIGUSR1 */ char sig_chld = 0; /* is 1 when we got a SIGCHLD */ /* jobs database */ struct CF *file_base; /* point to the first file of the list */ struct job *queue_base; /* ordered list of normal jobs to be run */ struct job *serial_base; /* ordered list of job to be run one by one */ -struct job *freq_base; /* ordered list of jobs based on frequency */ struct job *exe_base; /* jobs which are executed */ -time_t t1; /* the time at which sleep began */ +time_t begin_sleep; /* the time at which sleep began */ +time_t now; /* the current time */ void @@ -102,18 +102,6 @@ xexit(int exit_value) /* exit after having freed memory and removed lock file */ { CF *f = NULL; - extern time_t t1; - time_t t2 = time(NULL); - time_t dt = 0; - - dt = t2 - t1; - - if (dt > 0) { - - debug("slept: %lds", dt); - - update_time_remaining(dt); - } /* we save all files now and after having waiting for all * job being executed because we might get a SIGKILL @@ -275,6 +263,7 @@ sighup_handler(int x) /* update configuration */ { signal(SIGHUP, sighup_handler); + siginterrupt(SIGHUP, 0); debug(""); explain("SIGHUP signal received"); /* we don't call the synchronize_dir() function directly, @@ -294,6 +283,7 @@ sigchild_handler(int x) sig_chld = 1; (void)signal(SIGCHLD, sigchild_handler); + siginterrupt(SIGCHLD, 0); } @@ -302,6 +292,7 @@ sigusr1_handler(int x) /* reload all configurations */ { signal(SIGUSR1, sigusr1_handler); + siginterrupt(SIGUSR1, 0); debug(""); explain("SIGUSR1 signal received"); /* we don't call the synchronize_dir() function directly, @@ -424,8 +415,11 @@ main(int argc, char **argv) (void)signal(SIGTERM, sigterm_handler); (void)signal(SIGHUP, sighup_handler); + siginterrupt(SIGHUP, 0); (void)signal(SIGCHLD, sigchild_handler); + siginterrupt(SIGCHLD, 0); (void)signal(SIGUSR1, sigusr1_handler); + siginterrupt(SIGUSR1, 0); main_loop(); @@ -438,32 +432,31 @@ void main_loop() /* main loop - get the time to sleep until next job execution, * sleep, and then test all jobs and execute if needed. */ { - extern time_t t1; /* time at the beginning of sleeping */ - time_t t2 = 0; /* time at the end of sleeping */ - time_t t3 = 0; /* time at the previous reception of SIGCHLD */ - long int dt = 0; /* time we slept */ - time_t save = SAVE; /* time remaining until next save */ - struct timeval tv; /* we use usec field to get more precision */ - time_t stime = 0; /* time to sleep until next job - * execution */ + extern time_t begin_sleep; /* time at the beginning of sleeping */ + time_t save; /* time remaining until next save */ + struct timeval tv; /* we use usec field to get more precision */ + time_t stime = 0; /* time to sleep until next job + * execution */ debug("Entering main loop"); - t1 = time(NULL); + now = begin_sleep = time(NULL); synchronize_dir("."); /* synchronize save with jobs execution */ - save += (60 - (t1 % 60)); + save = now + SAVE; + stime = time_to_sleep(save); for (;;) { - sleep: sleep(stime - 1); gettimeofday(&tv, NULL); usleep( 1000000 - tv.tv_usec ); + now = time(NULL); + if (sig_chld > 0) { /* sleep has been stopped too early : @@ -471,51 +464,27 @@ void main_loop() wait_chld(); sig_chld = 0; - if ( t3 < t1 ) t3 = t1; - dt = time(NULL) - t3; - - if ( dt > 0 ) { - /* update stime value */ - dt = stime - dt; - debug("remain %d s of sleeping", dt); - stime = dt; - t3 = time(NULL); - - } else - /* we have slept less than 1 second : old stime - * is still valid */ - ; - - goto sleep; - } + else if (sig_conf > 0) { - t2 = time(NULL); - dt = t2 - t1; + if (sig_conf == 1) + /* update configuration */ + synchronize_dir("."); + else + /* reload all configuration */ + reload_all("."); - if (dt > 0) { + sig_conf = 0; + } + else { debug("\n"); - debug("slept: %lds", dt); - - update_time_remaining(dt); - - if (sig_conf > 0) { - - if (sig_conf == 1) - /* update configuration */ - synchronize_dir("."); - else - /* reload all configuration */ - reload_all("."); - - sig_conf = 0; - } + debug("slept: %lds", now - begin_sleep); - test_jobs(t2); + test_jobs(now); - if ( (save = ( (save-dt) >= 0 ) ? save-dt : 0) <= 60) { - save = SAVE; + if ( save - now <= 60 ) { + save = now + SAVE; /* save all files */ save_file(NULL, NULL); } @@ -524,7 +493,7 @@ void main_loop() stime = time_to_sleep(save); - t1 = t2; + begin_sleep = now; if ( sig_chld == 1 ) { wait_chld(); diff --git a/fcron.h b/fcron.h index 5068282..e5bf2b2 100644 --- a/fcron.h +++ b/fcron.h @@ -21,7 +21,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: fcron.h,v 1.5 2000-05-31 19:11:42 thib Exp $ */ + /* $Id: fcron.h,v 1.6 2000-06-11 13:18:58 thib Exp $ */ #ifndef __FCRONH__ #define __FCRONH__ @@ -46,8 +46,8 @@ extern char sig_hup; extern CF *file_base; extern struct job *queue_base; extern struct job *serial_base; -extern struct job *freq_base; extern struct job *exe_base; +extern time_t now; /* end of global variables */ @@ -80,11 +80,9 @@ extern char *strdup2(const char *); extern void test_jobs(time_t t2); extern void wait_chld(void); extern void wait_all(int *counter); -extern time_t time_to_sleep(short lim); +extern time_t time_to_sleep(time_t lim); extern void set_next_exe(CL *line, char is_new_line); extern void insert_nextexe(CL *line); -extern void insert_freq(CL *line); -extern void update_time_remaining(long dt); /* end of database.c */ /* conf.c */ diff --git a/global.h b/global.h index 093b55c..c93d35a 100644 --- a/global.h +++ b/global.h @@ -21,7 +21,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: global.h,v 1.5 2000-05-31 19:11:44 thib Exp $ */ + /* $Id: global.h,v 1.6 2000-06-11 13:19:01 thib Exp $ */ /* @@ -57,7 +57,7 @@ #include "option.h" -#define FILEVERSION "002" /* syntax's version of fcrontabs : +#define FILEVERSION "003" /* syntax's version of fcrontabs : * must have a length of 3 characters */ @@ -100,16 +100,16 @@ typedef struct CL { pid_t cl_pid; /* running pid, 0, or armed (-1) */ pid_t cl_mailpid; /* mailer pid or 0 */ int cl_mailfd; /* running pid is for mail */ + time_t cl_nextexe; /* time and date of the next execution */ + short int cl_remain; /* remaining until next execution */ + time_t cl_timefreq; /* Run every n seconds */ + short int cl_runfreq; /* Run once every n matches */ /* see bitstring(3) man page for more details */ bitstr_t bit_decl(cl_mins, 60); /* 0-59 */ bitstr_t bit_decl(cl_hrs, 24); /* 0-23 */ bitstr_t bit_decl(cl_days, 32); /* 1-31 */ bitstr_t bit_decl(cl_mons, 12); /* 0-11 */ bitstr_t bit_decl(cl_dow, 8); /* 0-7, 0 and 7 are both Sunday */ - time_t cl_timefreq; /* Run every n min */ - short int cl_runfreq; /* Run once every n matches */ - time_t cl_remain; /* remaining until next execution */ - time_t cl_nextexe; /* time and date of the next execution */ } CL; typedef struct job { diff --git a/job.c b/job.c index 32c5574..acc8f25 100644 --- a/job.c +++ b/job.c @@ -22,7 +22,7 @@ * `LICENSE' that comes with the fcron source distribution. */ - /* $Id: job.c,v 1.6 2000-05-31 19:11:47 thib Exp $ */ + /* $Id: job.c,v 1.7 2000-06-11 13:19:17 thib Exp $ */ #include "fcron.h" @@ -323,25 +323,25 @@ int temp_file(void) /* Open a temporary file and return its file descriptor */ { - const int max_retries=50; - char *name; - int fd,i; - - i=0; - name=NULL; - do { - i++; - free(name); - name=tempnam(NULL,NULL); - if (name==NULL) die("Can't find a unique temporary filename"); - fd=open(name,O_RDWR|O_CREAT|O_EXCL|O_APPEND,S_IRUSR|S_IWUSR); - /* I'm not sure we actually need to be so persistent here */ - } while (fd==-1 && errno==EEXIST && i