diff options
author | sobomax <sobomax@FreeBSD.org> | 2012-10-15 08:21:49 +0000 |
---|---|---|
committer | sobomax <sobomax@FreeBSD.org> | 2012-10-15 08:21:49 +0000 |
commit | 4e207a16566ea6611a8f6460d61721231ec1cef9 (patch) | |
tree | 4480269ff163dda5d57dde705f23d272bfb89474 /usr.sbin/cron/cron | |
parent | eecb11a14ebdeb7bd14f77b9d3085e02f243e10a (diff) | |
download | FreeBSD-src-4e207a16566ea6611a8f6460d61721231ec1cef9.zip FreeBSD-src-4e207a16566ea6611a8f6460d61721231ec1cef9.tar.gz |
Add per-second scheduling into the cron(8). Right now it's
only available via the new @every_second shortcut. ENOTIME to
implement crontab(5) format extensions to allow more flexible
scheduling.
In order to address some concerns expressed by Terry Lambert
while discussing the topic few years ago, about per-second cron
possibly causing some bad effects on /etc/crontab by stat()ing
it every second instead of every minute now (i.e. atime update),
only check that database needs to be reloaded on every 60-th
loop run. This should be close enough to the current behaviour.
Add "@every_minute" shortcut while I am here.
MFC after: 1 month
Diffstat (limited to 'usr.sbin/cron/cron')
-rw-r--r-- | usr.sbin/cron/cron/cron.c | 26 | ||||
-rw-r--r-- | usr.sbin/cron/cron/cron.h | 5 |
2 files changed, 22 insertions, 9 deletions
diff --git a/usr.sbin/cron/cron/cron.c b/usr.sbin/cron/cron/cron.c index 8524ff9..011458a 100644 --- a/usr.sbin/cron/cron/cron.c +++ b/usr.sbin/cron/cron/cron.c @@ -98,6 +98,7 @@ main(argc, argv) char *argv[]; { cron_db database; + int runnum; ProgramName = argv[0]; @@ -149,21 +150,24 @@ main(argc, argv) load_database(&database); run_reboot_jobs(&database); cron_sync(); + runnum = 0; while (TRUE) { # if DEBUGGING /* if (!(DebugFlags & DTEST)) */ # endif /*DEBUGGING*/ cron_sleep(&database); - load_database(&database); + if (runnum % 60 == 0) + load_database(&database); /* do this iteration */ cron_tick(&database); - /* sleep 1 minute + /* sleep 1 second */ - TargetTime += 60; + TargetTime += 1; + runnum += 1; } } @@ -194,22 +198,23 @@ cron_tick(db) static time_t diff = 0, /* time difference in seconds from the last offset change */ difflimit = 0; /* end point for the time zone correction */ struct tm otztm; /* time in the old time zone */ - int otzminute, otzhour, otzdom, otzmonth, otzdow; + int otzsecond, otzminute, otzhour, otzdom, otzmonth, otzdow; register struct tm *tm = localtime(&TargetTime); - register int minute, hour, dom, month, dow; + register int second, minute, hour, dom, month, dow; register user *u; register entry *e; /* make 0-based values out of these so we can use them as indicies */ + second = tm->tm_sec -FIRST_SECOND; 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; - Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n", - getpid(), minute, hour, dom, month, dow)) + Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d,%d)\n", + getpid(), second, minute, hour, dom, month, dow)) if (dst_enabled && last_time != 0 && TargetTime > last_time /* exclude stepping back */ @@ -262,6 +267,7 @@ cron_tick(db) /* make 0-based values out of these so we can use them as indicies */ + otzsecond = otztm.tm_sec -FIRST_SECOND; otzminute = otztm.tm_min -FIRST_MINUTE; otzhour = otztm.tm_hour -FIRST_HOUR; otzdom = otztm.tm_mday -FIRST_DOM; @@ -283,7 +289,8 @@ cron_tick(db) e->uid, e->gid, e->cmd)) if ( diff != 0 && (e->flags & (RUN_AT|NOT_UNTIL)) ) { - if (bit_test(e->minute, otzminute) + if (bit_test(e->second, otzsecond) + && bit_test(e->minute, otzminute) && bit_test(e->hour, otzhour) && bit_test(e->month, otzmonth) && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR)) @@ -302,7 +309,8 @@ cron_tick(db) continue; } - if (bit_test(e->minute, minute) + if (bit_test(e->second, second) + && bit_test(e->minute, minute) && bit_test(e->hour, hour) && bit_test(e->month, month) && ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR)) diff --git a/usr.sbin/cron/cron/cron.h b/usr.sbin/cron/cron/cron.h index 38eb33b..387c72b 100644 --- a/usr.sbin/cron/cron/cron.h +++ b/usr.sbin/cron/cron/cron.h @@ -124,6 +124,10 @@ LineNumber = ln; \ } +#define FIRST_SECOND 0 +#define LAST_SECOND 59 +#define SECOND_COUNT (LAST_SECOND - FIRST_SECOND + 1) + #define FIRST_MINUTE 0 #define LAST_MINUTE 59 #define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1) @@ -165,6 +169,7 @@ typedef struct _entry { #endif char **envp; char *cmd; + bitstr_t bit_decl(second, SECOND_COUNT); bitstr_t bit_decl(minute, MINUTE_COUNT); bitstr_t bit_decl(hour, HOUR_COUNT); bitstr_t bit_decl(dom, DOM_COUNT); |