Backed out the DST support changes.
This commit is contained in:
parent
ac2e223868
commit
6548bd5646
@ -25,7 +25,6 @@
|
|||||||
.Nd daemon to execute scheduled commands (Vixie Cron)
|
.Nd daemon to execute scheduled commands (Vixie Cron)
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl s
|
|
||||||
.Op Fl x Ar debugflag Ns Op ,...
|
.Op Fl x Ar debugflag Ns Op ,...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm Cron
|
.Nm Cron
|
||||||
@ -69,40 +68,6 @@ need not be restarted whenever a crontab file is modified. Note that the
|
|||||||
.Xr crontab 1
|
.Xr crontab 1
|
||||||
command updates the modtime of the spool directory whenever it changes a
|
command updates the modtime of the spool directory whenever it changes a
|
||||||
crontab.
|
crontab.
|
||||||
.Pp
|
|
||||||
Available options:
|
|
||||||
.Bl -tag -width indent
|
|
||||||
.It Fl s
|
|
||||||
Enable special handling of the switching between the standard time and
|
|
||||||
daylight saving time.
|
|
||||||
.Pp
|
|
||||||
If the time zone has daylight saving time which differs by one hour from
|
|
||||||
the standard time and the switch to and from daylight saving time occurs
|
|
||||||
at :00 minutes (as in most of the world with very few exceptions) then these
|
|
||||||
time switches would be handled specially by
|
|
||||||
.Nm cron .
|
|
||||||
The time zones with other variations of daylight saving time (such as with
|
|
||||||
30 minutes difference or switched at :30 minutes etc.) do not have such
|
|
||||||
support.
|
|
||||||
.Pp
|
|
||||||
In the supported time zones the jobs run during the switches to and
|
|
||||||
from daylinght saving time as
|
|
||||||
intuitively expected. If a job falls
|
|
||||||
into a time interval that disappears during the switch from
|
|
||||||
standard time to daylight saving time or is
|
|
||||||
duplicated during the reverse switch, then it's handled
|
|
||||||
in one of two ways. The jobs that run every hour work
|
|
||||||
as always, they skip the skipped hour or run in the added
|
|
||||||
hour as usual. But the jobs that run less frequently
|
|
||||||
are executed exactly once, they are not skipped nor
|
|
||||||
executed twice (unless cron is restarted or the user's
|
|
||||||
.Xr crontab 5
|
|
||||||
is changed during such a time interval). If an hour disappears
|
|
||||||
during the switch to daylight saving time, such jobs are
|
|
||||||
executed during the next hour at the first minute that is specified
|
|
||||||
for them in
|
|
||||||
.Xr crontab 5 .
|
|
||||||
.El
|
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr crontab 1 ,
|
.Xr crontab 1 ,
|
||||||
.Xr crontab 5
|
.Xr crontab 5
|
||||||
|
@ -36,22 +36,19 @@ static void usage __P((void)),
|
|||||||
run_reboot_jobs __P((cron_db *)),
|
run_reboot_jobs __P((cron_db *)),
|
||||||
cron_tick __P((cron_db *)),
|
cron_tick __P((cron_db *)),
|
||||||
cron_sync __P((void)),
|
cron_sync __P((void)),
|
||||||
cron_sleep __P((cron_db *)),
|
cron_sleep __P((void)),
|
||||||
cron_clean __P((cron_db *)),
|
|
||||||
#ifdef USE_SIGCHLD
|
#ifdef USE_SIGCHLD
|
||||||
sigchld_handler __P((int)),
|
sigchld_handler __P((int)),
|
||||||
#endif
|
#endif
|
||||||
sighup_handler __P((int)),
|
sighup_handler __P((int)),
|
||||||
parse_args __P((int c, char *v[]));
|
parse_args __P((int c, char *v[]));
|
||||||
|
|
||||||
static time_t last_time = 0;
|
|
||||||
static int dst_enabled = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage() {
|
usage() {
|
||||||
char **dflags;
|
char **dflags;
|
||||||
|
|
||||||
fprintf(stderr, "usage: cron [-s] [-x debugflag[,...]]\n");
|
fprintf(stderr, "usage: cron [-x debugflag[,...]]\n");
|
||||||
fprintf(stderr, "\ndebugflags: ");
|
fprintf(stderr, "\ndebugflags: ");
|
||||||
|
|
||||||
for(dflags = DebugFlagNames; *dflags; dflags++) {
|
for(dflags = DebugFlagNames; *dflags; dflags++) {
|
||||||
@ -69,6 +66,7 @@ main(argc, argv)
|
|||||||
char *argv[];
|
char *argv[];
|
||||||
{
|
{
|
||||||
cron_db database;
|
cron_db database;
|
||||||
|
|
||||||
ProgramName = argv[0];
|
ProgramName = argv[0];
|
||||||
|
|
||||||
#if defined(BSD)
|
#if defined(BSD)
|
||||||
@ -129,7 +127,7 @@ main(argc, argv)
|
|||||||
# if DEBUGGING
|
# if DEBUGGING
|
||||||
/* if (!(DebugFlags & DTEST)) */
|
/* if (!(DebugFlags & DTEST)) */
|
||||||
# endif /*DEBUGGING*/
|
# endif /*DEBUGGING*/
|
||||||
cron_sleep(&database);
|
cron_sleep();
|
||||||
|
|
||||||
load_database(&database);
|
load_database(&database);
|
||||||
|
|
||||||
@ -166,7 +164,6 @@ static void
|
|||||||
cron_tick(db)
|
cron_tick(db)
|
||||||
cron_db *db;
|
cron_db *db;
|
||||||
{
|
{
|
||||||
static struct tm lasttm;
|
|
||||||
register struct tm *tm = localtime(&TargetTime);
|
register struct tm *tm = localtime(&TargetTime);
|
||||||
register int minute, hour, dom, month, dow;
|
register int minute, hour, dom, month, dow;
|
||||||
register user *u;
|
register user *u;
|
||||||
@ -183,94 +180,6 @@ cron_tick(db)
|
|||||||
Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
|
Debug(DSCH, ("[%d] tick(%d,%d,%d,%d,%d)\n",
|
||||||
getpid(), minute, hour, dom, month, dow))
|
getpid(), minute, hour, dom, month, dow))
|
||||||
|
|
||||||
/* check for the daylight saving time change
|
|
||||||
* we support only change by +-1 hour happening at :00 minutes,
|
|
||||||
* those living in more strange timezones are out of luck
|
|
||||||
*/
|
|
||||||
if (dst_enabled && last_time != 0
|
|
||||||
&& TargetTime > last_time /* exclude stepping back */
|
|
||||||
&& tm->tm_isdst != lasttm.tm_isdst ) {
|
|
||||||
int prevhr, nexthr, runtime;
|
|
||||||
int lastmin, lasthour;
|
|
||||||
int trandom, tranmonth, trandow;
|
|
||||||
time_t diff; /* time difference in seconds */
|
|
||||||
|
|
||||||
lastmin = lasttm.tm_min -FIRST_MINUTE;
|
|
||||||
lasthour = lasttm.tm_hour -FIRST_HOUR;
|
|
||||||
|
|
||||||
prevhr = (hour + (HOUR_COUNT-1)) % HOUR_COUNT;
|
|
||||||
nexthr = (lasthour + 1) % HOUR_COUNT;
|
|
||||||
|
|
||||||
if ( lasttm.tm_isdst != 1 && tm->tm_isdst == 1 /* ST->DST */
|
|
||||||
&& prevhr == nexthr ) {
|
|
||||||
diff = ( (hour*MINUTE_COUNT + minute)
|
|
||||||
- (lasthour*MINUTE_COUNT + lastmin)
|
|
||||||
+ HOUR_COUNT*MINUTE_COUNT
|
|
||||||
) % (HOUR_COUNT*MINUTE_COUNT);
|
|
||||||
diff -= (TargetTime - last_time) / 60/*seconds*/;
|
|
||||||
if (diff != MINUTE_COUNT)
|
|
||||||
goto dstdone;
|
|
||||||
|
|
||||||
if (hour == 0) {
|
|
||||||
trandom = lasttm.tm_mday -FIRST_DOM;
|
|
||||||
tranmonth = lasttm.tm_mon +1 /* 0..11 -> 1..12 */ -FIRST_MONTH;
|
|
||||||
trandow = lasttm.tm_wday -FIRST_DOW;
|
|
||||||
} else {
|
|
||||||
trandom = dom;
|
|
||||||
tranmonth = month;
|
|
||||||
trandow = dow;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u = db->head; u != NULL; u = u->next) {
|
|
||||||
for (e = u->crontab; e != NULL; e = e->next) {
|
|
||||||
/* adjust only jobs less frequent than 1 hr */
|
|
||||||
if ( !bit_test(e->hour, prevhr)
|
|
||||||
|| bit_test(e->hour, lasthour)
|
|
||||||
|| bit_test(e->hour, hour) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ( bit_test(e->month, tranmonth)
|
|
||||||
&& ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
|
|
||||||
? (bit_test(e->dow,trandow) && bit_test(e->dom,trandom))
|
|
||||||
: (bit_test(e->dow,trandow) || bit_test(e->dom,trandom)) )
|
|
||||||
) {
|
|
||||||
bit_ffs(e->minute, MINUTE_COUNT, &runtime);
|
|
||||||
if(runtime >= 0) {
|
|
||||||
e->tmval = TargetTime + (runtime-minute)*60;
|
|
||||||
e->flags |= RUN_AT;
|
|
||||||
e->flags &= ~NOT_UNTIL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ( lasttm.tm_isdst == 1 && tm->tm_isdst != 1 /* DST->ST */
|
|
||||||
&& lasthour == hour ) {
|
|
||||||
diff = ( (lasthour*MINUTE_COUNT + lastmin)
|
|
||||||
- (hour*MINUTE_COUNT + minute)
|
|
||||||
+ HOUR_COUNT*MINUTE_COUNT
|
|
||||||
) % (HOUR_COUNT*MINUTE_COUNT);
|
|
||||||
diff += (TargetTime - last_time) / 60/*seconds*/;
|
|
||||||
if (diff != MINUTE_COUNT)
|
|
||||||
goto dstdone;
|
|
||||||
|
|
||||||
runtime = TargetTime + (MINUTE_COUNT - minute)*60;
|
|
||||||
for (u = db->head; u != NULL; u = u->next) {
|
|
||||||
for (e = u->crontab; e != NULL; e = e->next) {
|
|
||||||
/* adjust only jobs less frequent than 1 hr */
|
|
||||||
if ( !bit_test(e->hour, hour)
|
|
||||||
|| bit_test(e->hour, prevhr)
|
|
||||||
|| bit_test(e->hour, nexthr) )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
e->tmval = runtime;
|
|
||||||
e->flags |= NOT_UNTIL;
|
|
||||||
e->flags &= ~RUN_AT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dstdone:
|
|
||||||
|
|
||||||
/* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
|
/* the dom/dow situation is odd. '* * 1,15 * Sun' will run on the
|
||||||
* first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
|
* first and fifteenth AND every Sunday; '* * * * Sun' will run *only*
|
||||||
* on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this
|
* on Sundays; '* * 1,15 * *' will run *only* the 1st and 15th. this
|
||||||
@ -282,14 +191,7 @@ dstdone:
|
|||||||
Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
|
Debug(DSCH|DEXT, ("user [%s:%d:%d:...] cmd=\"%s\"\n",
|
||||||
env_get("LOGNAME", e->envp),
|
env_get("LOGNAME", e->envp),
|
||||||
e->uid, e->gid, e->cmd))
|
e->uid, e->gid, e->cmd))
|
||||||
if (e->flags & NOT_UNTIL) {
|
if (bit_test(e->minute, minute)
|
||||||
if (TargetTime >= e->tmval)
|
|
||||||
e->flags &= ~NOT_UNTIL;
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ( (e->flags & RUN_AT) && TargetTime == e->tmval
|
|
||||||
|| bit_test(e->minute, minute)
|
|
||||||
&& bit_test(e->hour, hour)
|
&& bit_test(e->hour, hour)
|
||||||
&& bit_test(e->month, month)
|
&& bit_test(e->month, month)
|
||||||
&& ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
|
&& ( ((e->flags & DOM_STAR) || (e->flags & DOW_STAR))
|
||||||
@ -297,14 +199,10 @@ dstdone:
|
|||||||
: (bit_test(e->dow,dow) || bit_test(e->dom,dom))
|
: (bit_test(e->dow,dow) || bit_test(e->dom,dom))
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
e->flags &= ~RUN_AT;
|
|
||||||
job_add(e, u);
|
job_add(e, u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
last_time = TargetTime;
|
|
||||||
lasttm = *tm;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -328,9 +226,7 @@ cron_sync() {
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
cron_sleep(db)
|
cron_sleep() {
|
||||||
cron_db *db;
|
|
||||||
{
|
|
||||||
int seconds_to_wait = 0;
|
int seconds_to_wait = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -345,7 +241,6 @@ cron_sleep(db)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (seconds_to_wait < -600 || seconds_to_wait > 600) {
|
if (seconds_to_wait < -600 || seconds_to_wait > 600) {
|
||||||
cron_clean(db);
|
|
||||||
cron_sync();
|
cron_sync();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -370,26 +265,6 @@ cron_sleep(db)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* if the time was changed abruptly, clear the flags related
|
|
||||||
* to the daylight time switch handling to avoid strange effects
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void
|
|
||||||
cron_clean(db)
|
|
||||||
cron_db *db;
|
|
||||||
{
|
|
||||||
user *u;
|
|
||||||
entry *e;
|
|
||||||
|
|
||||||
last_time = 0;
|
|
||||||
|
|
||||||
for (u = db->head; u != NULL; u = u->next) {
|
|
||||||
for (e = u->crontab; e != NULL; e = e->next) {
|
|
||||||
e->flags &= ~(RUN_AT|NOT_UNTIL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_SIGCHLD
|
#ifdef USE_SIGCHLD
|
||||||
static void
|
static void
|
||||||
sigchld_handler(x) {
|
sigchld_handler(x) {
|
||||||
@ -434,11 +309,8 @@ parse_args(argc, argv)
|
|||||||
{
|
{
|
||||||
int argch;
|
int argch;
|
||||||
|
|
||||||
while ((argch = getopt(argc, argv, "sx:")) != -1) {
|
while ((argch = getopt(argc, argv, "x:")) != -1) {
|
||||||
switch (argch) {
|
switch (argch) {
|
||||||
case 's':
|
|
||||||
dst_enabled = 1;
|
|
||||||
break;
|
|
||||||
case 'x':
|
case 'x':
|
||||||
if (!set_debug_flags(optarg))
|
if (!set_debug_flags(optarg))
|
||||||
usage();
|
usage();
|
||||||
|
@ -172,9 +172,6 @@ typedef struct _entry {
|
|||||||
#define DOM_STAR 0x01
|
#define DOM_STAR 0x01
|
||||||
#define DOW_STAR 0x02
|
#define DOW_STAR 0x02
|
||||||
#define WHEN_REBOOT 0x04
|
#define WHEN_REBOOT 0x04
|
||||||
#define RUN_AT 0x08
|
|
||||||
#define NOT_UNTIL 0x10
|
|
||||||
time_t tmval;
|
|
||||||
} entry;
|
} entry;
|
||||||
|
|
||||||
/* the crontab database will be a list of the
|
/* the crontab database will be a list of the
|
||||||
|
Loading…
x
Reference in New Issue
Block a user