commit 2302cf8106c2eda42c18467374875260f128ec11
parent 727f9a6c45ab331f21149729d56e05345c5e9a45
Author: sin <sin@2f30.org>
Date: Mon, 7 Jul 2014 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:
M | 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));