Package: cron
Version: 3.0pl1-100
Severity: normal

Jobs scheduled to run between 1 and 2 am
are not run when time moves forward
for 1-3 hours (at the beginning of DST) and
are run twice when time moves backward
for 1-3 hours (at the end of DST).

Included is the patch against current trunk.


*** pkg-cron-trunk-dst.diff
Index: cron.c
===================================================================
--- cron.c      (revision 413)
+++ cron.c      (working copy)
@@ -37,7 +37,7 @@
 static void    usage __P((void)),
                run_reboot_jobs __P((cron_db *)),
                find_jobs __P((time_min, cron_db *, int, int)),
-               set_time __P((void)),
+               set_time __P((int)),
                cron_sleep __P((time_min)),
 #ifdef USE_SIGCHLD
                sigchld_handler __P((int)),
@@ -152,7 +152,7 @@
 #endif
        load_database(&database);
 
-       set_time();
+       set_time(TRUE);
        run_reboot_jobs(&database);
        timeRunning = virtualTime = clockTime;
 
@@ -173,7 +173,7 @@
                /* ... wait for the time (in minutes) to change ... */
                do {
                        cron_sleep(timeRunning + 1);
-                       set_time();
+                       set_time(FALSE);
                } while (clockTime == timeRunning);
                timeRunning = clockTime;
 
@@ -186,6 +186,9 @@
                 */
                timeDiff = timeRunning - virtualTime;
 
+               Debug(DSCH, ("[%d] pulse: %d = %d - %d\n",
+                   getpid(), timeDiff, timeRunning, virtualTime));
+
                /* shortcut for the most common case */
                if (timeDiff == 1) {
                        virtualTime = timeRunning;
@@ -239,7 +242,7 @@
                                                sleep(10);
                                        virtualTime++;
                                        find_jobs(virtualTime, &database, 
FALSE, TRUE);
-                                       set_time();
+                                       set_time(FALSE);
                                } while (virtualTime< timeRunning &&
                                    clockTime == timeRunning);
                                break;
@@ -326,7 +329,7 @@
        int doNonWild;
 {
        time_t   virtualSecond  = vtime * SECONDS_PER_MINUTE;
-       register struct tm      *tm = localtime(&virtualSecond);
+       register struct tm      *tm = gmtime(&virtualSecond);
        register int            minute, hour, dom, month, dow;
        register user           *u;
        register entry          *e;
@@ -375,10 +378,22 @@
  * note that clockTime is a unix wallclock time converted to minutes
  */
 static void
-set_time()
+set_time(int initialize)
 {
-       StartTime = time((time_t *)0);
-       clockTime = StartTime / (unsigned long)SECONDS_PER_MINUTE;
+    struct tm tm;
+    static int isdst;
+
+    StartTime = time(NULL);
+
+    /* We adjust the time to GMT so we can catch DST changes. */
+    tm = *localtime(&StartTime);
+    if (initialize || tm.tm_isdst != isdst) {
+       isdst = tm.tm_isdst;
+       GMToff = get_gmtoff(&StartTime, &tm);
+       Debug(DSCH, ("[%ld] GMToff=%ld\n",
+           (long)getpid(), (long)GMToff))
+    }
+    clockTime = (StartTime + GMToff) / (time_t)SECONDS_PER_MINUTE;
 }
 
 /*
@@ -390,12 +405,19 @@
 {
        register int    seconds_to_wait;
 
-       seconds_to_wait = (int)(target*SECONDS_PER_MINUTE - time((time_t*)0)) + 
1;
+       time_t t1, t2;
+       t1 = time(NULL) + GMToff;
+
+       seconds_to_wait = (int)(target * SECONDS_PER_MINUTE - t1) + 1;
        Debug(DSCH, ("[%d] TargetTime=%ld, sec-to-wait=%d\n",
            getpid(), (long)target*SECONDS_PER_MINUTE, seconds_to_wait))
 
-       if (seconds_to_wait > 0 && seconds_to_wait< 65)
+       while (seconds_to_wait > 0 && seconds_to_wait< 65) {
                sleep((unsigned int) seconds_to_wait);
+               t2 = time(NULL) + GMToff;
+               seconds_to_wait -= (int)(t2 - t1);
+               t1 = t2;
+       }
 }
 
 
Index: cron.h
===================================================================
--- cron.h      (revision 413)
+++ cron.h      (working copy)
@@ -279,6 +279,7 @@
 time_min timeRunning;
 time_min virtualTime;
 time_min clockTime;
+static long GMToff;
 
 int    stay_foreground;
 int     lsbsysinit_mode;
Index: misc.c
===================================================================
--- misc.c      (revision 413)
+++ misc.c      (working copy)
@@ -718,3 +718,38 @@
 }
 int swap_uids_back() { return swap_uids(); }
 #endif /*HAVE_SAVED_UIDS*/
+
+
+/* Return the offset from GMT in seconds (algorithm taken from sendmail).
+ *
+ * warning:
+ *      clobbers the static storage space used by localtime() and gmtime().
+ *      If the local pointer is non-NULL it *must* point to a local copy.
+ */
+#ifndef HAVE_TM_GMTOFF
+long get_gmtoff(time_t *clock, struct tm *local)
+{
+        struct tm gmt;
+        long offset;
+
+        gmt = *gmtime(clock);
+        if (local == NULL)
+                local = localtime(clock);
+
+        offset = (local->tm_sec - gmt.tm_sec) +
+            ((local->tm_min - gmt.tm_min) * 60) +
+            ((local->tm_hour - gmt.tm_hour) * 3600);
+
+        /* Timezone may cause year rollover to happen on a different day. */
+        if (local->tm_year < gmt.tm_year)
+                offset -= 24 * 3600;
+        else if (local->tm_year > gmt.tm_year)
+                offset -= 24 * 3600;
+        else if (local->tm_yday < gmt.tm_yday)
+                offset -= 24 * 3600;
+        else if (local->tm_yday > gmt.tm_yday)
+                offset += 24 * 3600;
+
+        return (offset);
+}
+#endif /* HAVE_TM_GMTOFF */


-- System Information:
Debian Release: 4.0
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.22-4-amd64
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)

Versions of packages cron depends on:
ii  adduser                3.102             Add and remove users and groups
ii  debianutils            2.17              Miscellaneous utilities specific t
ii  libc6                  2.3.6.ds1-13etch5 GNU C Library: Shared libraries
ii  libpam0g               0.79-5            Pluggable Authentication Modules l
ii  libselinux1            1.32-3            SELinux shared libraries
ii  lsb-base               3.1-23.2etch1     Linux Standard Base 3.1 init scrip

Versions of packages cron recommends:
ii  postfix [mail-transport-agent 2.3.8-2    A high-performance mail transport 

-- no debconf information



-- 
To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Reply via email to