summaryrefslogtreecommitdiffstats
path: root/usr.sbin/cron/cron
diff options
context:
space:
mode:
authorsobomax <sobomax@FreeBSD.org>2012-10-15 08:21:49 +0000
committersobomax <sobomax@FreeBSD.org>2012-10-15 08:21:49 +0000
commit4e207a16566ea6611a8f6460d61721231ec1cef9 (patch)
tree4480269ff163dda5d57dde705f23d272bfb89474 /usr.sbin/cron/cron
parenteecb11a14ebdeb7bd14f77b9d3085e02f243e10a (diff)
downloadFreeBSD-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.c26
-rw-r--r--usr.sbin/cron/cron/cron.h5
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);
OpenPOWER on IntegriCloud