* `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"
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);
- }
}
}
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 :
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;
}
-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);
-
- }
-
-}
-
* `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);
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
/* 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
/* update configuration */
{
signal(SIGHUP, sighup_handler);
+ siginterrupt(SIGHUP, 0);
debug("");
explain("SIGHUP signal received");
/* we don't call the synchronize_dir() function directly,
sig_chld = 1;
(void)signal(SIGCHLD, sigchild_handler);
+ siginterrupt(SIGCHLD, 0);
}
/* reload all configurations */
{
signal(SIGUSR1, sigusr1_handler);
+ siginterrupt(SIGUSR1, 0);
debug("");
explain("SIGUSR1 signal received");
/* we don't call the synchronize_dir() function directly,
(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();
/* 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 :
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);
}
stime = time_to_sleep(save);
- t1 = t2;
+ begin_sleep = now;
if ( sig_chld == 1 ) {
wait_chld();
* `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__
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 */
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 */
* `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 $ */
/*
#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 */
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 {
* `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"
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<max_retries);
- if (fd==-1) die_e("Can't open temporary file");
- if (unlink(name)) die_e("Can't unlink temporary file");
- free(name);
- fcntl(fd,F_SETFD,1); /* set close-on-exec flag */
- return fd;
+ 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 < max_retries);
+ if (fd == -1) die_e("Can't open temporary file");
+ if (unlink(name)) die_e("Can't unlink temporary file");
+ free(name);
+ fcntl(fd, F_SETFD,1); /* set close-on-exec flag */
+ return fd;
}
/* Write (using write()) the string "string" to temporary file "fd".
* Don't return on failure */
{
- if (write(fd,string,strlen(string))==-1)
- die_e("Can't write to temporary file");
+ if ( write(fd, string, strlen(string)) == -1 )
+ die_e("Can't write to temporary file");
}