scron

simple cron daemon
git clone git://git.2f30.org/scron.git
Log | Files | Refs | README | LICENSE

commit 2302cf8106c2eda42c18467374875260f128ec11
parent 727f9a6c45ab331f21149729d56e05345c5e9a45
Author: sin <sin@2f30.org>
Date:   Mon Jul  7 12:31:25 +0100

Don't reschedule commands that are already running

Make this the default behaviour.  If you want to avoid that, just
background the job in crontab.

Diffstat:
crond.c | 35+++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+), 0 deletions(-)
diff --git a/crond.c b/crond.c @@ -38,10 +38,17 @@ struct ctabentry { TAILQ_ENTRY(ctabentry) entry; }; +struct jobentry { + char *cmd; + pid_t pid; + TAILQ_ENTRY(jobentry) entry; +}; + char *argv0; static sig_atomic_t reload; static sig_atomic_t chldreap; static TAILQ_HEAD(, ctabentry) ctabhead = TAILQ_HEAD_INITIALIZER(ctabhead); +static TAILQ_HEAD(, jobentry) jobhead = TAILQ_HEAD_INITIALIZER(jobhead); static char *config = "/etc/crontab"; static int nflag; @@ -107,11 +114,21 @@ estrdup(const char *s) static void runjob(char *cmd) { + struct jobentry *je; time_t t; pid_t pid; t = time(NULL); + /* If command is already running, skip it */ + TAILQ_FOREACH(je, &jobhead, entry) { + if (strcmp(je->cmd, cmd) == 0) { + loginfo("already running %s pid: %d at %s", + je->cmd, je->pid, ctime(&t)); + return; + } + } + pid = fork(); if (pid < 0) { logerr("error: failed to fork job: %s time: %s", @@ -125,11 +142,17 @@ runjob(char *cmd) cmd, ctime(&t)); _exit(EXIT_FAILURE); } + + je = emalloc(sizeof(*je)); + je->cmd = estrdup(cmd); + je->pid = pid; + TAILQ_INSERT_TAIL(&jobhead, je, entry); } static void waitjob(void) { + struct jobentry *je, *tmp; int status; time_t t; pid_t pid; @@ -137,6 +160,18 @@ waitjob(void) t = time(NULL); while ((pid = waitpid(-1, &status, WNOHANG | WUNTRACED)) > 0) { + je = NULL; + TAILQ_FOREACH(tmp, &jobhead, entry) { + if (tmp->pid == pid) { + je = tmp; + break; + } + } + if (je) { + TAILQ_REMOVE(&jobhead, je, entry); + free(je->cmd); + free(je); + } if (WIFSIGNALED(status) == 1) { loginfo("complete: pid: %d terminated by signal: %d time: %s", pid, WTERMSIG(status), ctime(&t));