Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/usr.sbin/cron Implement CRON_TZ and CRON_WITHIN to provide f...



details:   https://anonhg.NetBSD.org/src/rev/14e24f6ef364
branches:  trunk
changeset: 526100:14e24f6ef364
user:      atatat <atatat%NetBSD.org@localhost>
date:      Thu Apr 25 14:45:05 2002 +0000

description:
Implement CRON_TZ and CRON_WITHIN to provide finer control over job
execution.  CRON_TZ sets the time zone within which a job is
considered for execution (but not in which it runs), and CRON_WITHIN
allows jobs to be skipped whose execution is delayed for any reason
(eg, the system was sleeping or the load average is too high for
timely execution).

diffstat:

 usr.sbin/cron/cron.c    |  36 ++++++++++++++++++++++++++-------
 usr.sbin/cron/crontab.5 |  19 ++++++++++++++++-
 usr.sbin/cron/job.c     |  52 +++++++++++++++++++++++++++++++++++++++++++++---
 3 files changed, 94 insertions(+), 13 deletions(-)

diffs (217 lines):

diff -r b8a810dacbb7 -r 14e24f6ef364 usr.sbin/cron/cron.c
--- a/usr.sbin/cron/cron.c      Thu Apr 25 10:55:43 2002 +0000
+++ b/usr.sbin/cron/cron.c      Thu Apr 25 14:45:05 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cron.c,v 1.9 1999/03/17 20:57:05 fair Exp $    */
+/*     $NetBSD: cron.c,v 1.10 2002/04/25 14:45:05 atatat Exp $ */
 
 /* Copyright 1988,1990,1993,1994 by Paul Vixie
  * All rights reserved
@@ -22,7 +22,7 @@
 #if 0
 static char rcsid[] = "Id: cron.c,v 2.11 1994/01/15 20:43:43 vixie Exp";
 #else
-__RCSID("$NetBSD: cron.c,v 1.9 1999/03/17 20:57:05 fair Exp $");
+__RCSID("$NetBSD: cron.c,v 1.10 2002/04/25 14:45:05 atatat Exp $");
 #endif
 #endif
 
@@ -154,18 +154,32 @@
 cron_tick(db)
        cron_db *db;
 {
-       struct tm       *tm = localtime(&TargetTime);
+       char            *orig_tz, *job_tz;
+       struct tm       *tm;
        int             minute, hour, dom, month, dow;
        user            *u;
        entry           *e;
 
        /* make 0-based values out of these so we can use them as indicies
         */
-       minute = tm->tm_min -FIRST_MINUTE;
-       hour = tm->tm_hour -FIRST_HOUR;
-       dom = tm->tm_mday -FIRST_DOM;
-       month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
-       dow = tm->tm_wday -FIRST_DOW;
+#define maketime(tz1, tz2) do { \
+       char *t = tz1; \
+       if (t != NULL && *t != '\0') \
+               setenv("TZ", t, 1); \
+       else if ((tz2) != NULL) \
+               setenv("TZ", (tz2), 1); \
+       else \
+               unsetenv("TZ"); \
+       tm = localtime(&TargetTime); \
+       minute = tm->tm_min -FIRST_MINUTE; \
+       hour = tm->tm_hour -FIRST_HOUR; \
+       dom = tm->tm_mday -FIRST_DOM; \
+       month = tm->tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH; \
+       dow = tm->tm_wday -FIRST_DOW; \
+       } while (0)
+
+       orig_tz = getenv("TZ");
+       maketime(NULL, orig_tz);
 
        Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
                getpid(), minute, hour, dom, month, dow))
@@ -181,6 +195,8 @@
                        Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
                                          env_get("LOGNAME", e->envp),
                                          e->uid, e->gid, e->cmd))
+                       job_tz = env_get("CRON_TZ", e->envp);
+                       maketime(job_tz, orig_tz);
                        if (bit_test(e->minute, minute)
                         && bit_test(e->hour, hour)
                         && bit_test(e->month, month)
@@ -193,6 +209,10 @@
                        }
                }
        }
+       if (orig_tz != NULL)
+               setenv("TZ", orig_tz, 1);
+       else
+               unsetenv("TZ");
 }
 
 
diff -r b8a810dacbb7 -r 14e24f6ef364 usr.sbin/cron/crontab.5
--- a/usr.sbin/cron/crontab.5   Thu Apr 25 10:55:43 2002 +0000
+++ b/usr.sbin/cron/crontab.5   Thu Apr 25 14:45:05 2002 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: crontab.5,v 1.9 2002/02/08 01:38:48 ross Exp $
+.\"    $NetBSD: crontab.5,v 1.10 2002/04/25 14:45:05 atatat Exp $
 .\"
 .\"/* Copyright 1988,1990,1993,1994 by Paul Vixie
 .\" * All rights reserved
@@ -80,6 +80,23 @@
 your mailer when you install cron -- /bin/mail doesn't do aliasing, and UUCP
 usually doesn't read its mail.
 .PP
+In order to provide finer control over when jobs execute, users
+can also set the environment variables CRON_TZ and CRON_WITHIN.
+The CRON_TZ variable can be set to an alternate time zone in order
+to affect when the job is run.  Note that this only affects the
+scheduling of the job, not the time zone that the job perceives
+when it is run.  If CRON_TZ is defined but empty (CRON_TZ=""), jobs
+are scheduled with respect to the local time zone.
+.PP
+The CRON_WITHIN variable should indicate the number of seconds
+within a job's scheduled time that it should still be run.  On a
+heavily loaded system, or on a system that has just been "woken
+up", jobs will sometimes start later than originally intended, and
+by skipping non-critical jobs because of delays, system load can
+be lightened.  If CRON_WITHIN is defined but empty (CRON_WITHIN="") or
+set to some non-positive value (0, a negative number, or a non-numeric
+string), it is treated as if it was unset.
+.PP
 The format of a cron command is very much the V7 standard, with a number of
 upward-compatible extensions.  Each line has five time and date fields,
 followed by a user name if this is the system crontab file,
diff -r b8a810dacbb7 -r 14e24f6ef364 usr.sbin/cron/job.c
--- a/usr.sbin/cron/job.c       Thu Apr 25 10:55:43 2002 +0000
+++ b/usr.sbin/cron/job.c       Thu Apr 25 14:45:05 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: job.c,v 1.3 1998/01/31 14:40:35 christos Exp $ */
+/*     $NetBSD: job.c,v 1.4 2002/04/25 14:45:05 atatat Exp $   */
 
 /* Copyright 1988,1990,1993,1994 by Paul Vixie
  * All rights reserved
@@ -18,11 +18,17 @@
  */
 
 #include <sys/cdefs.h>
+#include <errno.h>
+#if SYS_TIME_H
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
 #if !defined(lint) && !defined(LINT)
 #if 0
 static char rcsid[] = "Id: job.c,v 1.6 1994/01/15 20:43:43 vixie Exp";
 #else
-__RCSID("$NetBSD: job.c,v 1.3 1998/01/31 14:40:35 christos Exp $");
+__RCSID("$NetBSD: job.c,v 1.4 2002/04/25 14:45:05 atatat Exp $");
 #endif
 #endif
 
@@ -34,12 +40,16 @@
        struct _job     *next;
        entry           *e;
        user            *u;
+       time_t          t;
 } job;
 
 
 static job     *jhead = NULL, *jtail = NULL;
 
 
+static int okay_to_go __P((job *));
+
+
 void
 job_add(e, u)
        entry *e;
@@ -49,13 +59,17 @@
 
        /* if already on queue, keep going */
        for (j=jhead; j; j=j->next)
-               if (j->e == e && j->u == u) { return; }
+               if (j->e == e && j->u == u) {
+                       j->t = TargetTime;
+                       return;
+               }
 
        /* build a job queue element */
        j = (job*)malloc(sizeof(job));
        j->next = (job*) NULL;
        j->e = e;
        j->u = u;
+       j->t = TargetTime;
 
        /* add it to the tail */
        if (!jhead) { jhead=j; }
@@ -71,7 +85,16 @@
        int     run = 0;
 
        for (j=jhead; j; j=jn) {
-               do_command(j->e, j->u);
+               if (okay_to_go(j))
+                       do_command(j->e, j->u);
+               else {
+                       char *x = mkprints((u_char *)j->e->cmd,
+                           strlen(j->e->cmd));
+                       char *usernm = env_get("LOGNAME", j->e->envp);
+
+                       log_it(usernm, getpid(), "CMD (skipped)", x);
+                       free(x);
+               }
                jn = j->next;
                free(j);
                run++;
@@ -79,3 +102,24 @@
        jhead = jtail = NULL;
        return run;
 }
+
+
+static int
+okay_to_go(j)
+       job     *j;
+{
+       char *within, *t;
+       int delta;
+
+       within = env_get("CRON_WITHIN", j->e->envp);
+       if (within == NULL)
+               return (1);
+
+       /* XXX handle 2m, 4h, etc? */
+       errno = 0;
+       delta = strtol(within, &t, 10);
+       if (errno == ERANGE || *t != '\0' || delta <= 0)
+               return (1);
+
+       return ((j->t + delta) > time(NULL));
+}



Home | Main Index | Thread Index | Old Index