Here's a diff to use st_mtim instead of st_mtime which fixes the
issue.

 - todd

Index: usr.sbin/cron/atrun.c
===================================================================
RCS file: /cvs/src/usr.sbin/cron/atrun.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 atrun.c
--- usr.sbin/cron/atrun.c       17 Nov 2015 22:31:44 -0000      1.42
+++ usr.sbin/cron/atrun.c       10 Jan 2016 22:36:00 -0000
@@ -91,7 +91,7 @@ scan_atjobs(at_db **db, struct timespec 
                close(dfd);
                return (0);
        }
-       if (old_db != NULL && old_db->mtime == sb.st_mtime) {
+       if (old_db != NULL && timespeccmp(&old_db->mtime, &sb.st_mtim, ==)) {
                close(dfd);
                return (0);
        }
@@ -106,7 +106,7 @@ scan_atjobs(at_db **db, struct timespec 
                closedir(atdir);
                return (0);
        }
-       new_db->mtime = sb.st_mtime;    /* stash at dir mtime */
+       new_db->mtime = sb.st_mtim;     /* stash at dir mtime */
        TAILQ_INIT(&new_db->jobs);
 
        pending = 0;
Index: usr.sbin/cron/cron.c
===================================================================
RCS file: /cvs/src/usr.sbin/cron/cron.c,v
retrieving revision 1.73
diff -u -p -u -r1.73 cron.c
--- usr.sbin/cron/cron.c        15 Nov 2015 23:24:24 -0000      1.73
+++ usr.sbin/cron/cron.c        10 Jan 2016 22:46:37 -0000
@@ -373,7 +373,7 @@ cron_sleep(time_t target, sigset_t *mask
                                (void) read(fd, &poke, 1);
                                close(fd);
                                if (poke & RELOAD_CRON) {
-                                       database->mtime = 0;
+                                       timespecclear(&database->mtime);
                                        load_database(&database);
                                }
                                if (poke & RELOAD_AT) {
@@ -383,7 +383,7 @@ cron_sleep(time_t target, sigset_t *mask
                                         * jobs immediately.
                                         */
                                        clock_gettime(CLOCK_REALTIME, &t2);
-                                       at_database->mtime = 0;
+                                       timespecclear(&at_database->mtime);
                                        if (scan_atjobs(&at_database, &t2))
                                                atrun(at_database,
                                                    batch_maxload, t2.tv_sec);
Index: usr.sbin/cron/database.c
===================================================================
RCS file: /cvs/src/usr.sbin/cron/database.c,v
retrieving revision 1.33
diff -u -p -u -r1.33 database.c
--- usr.sbin/cron/database.c    14 Nov 2015 13:09:14 -0000      1.33
+++ usr.sbin/cron/database.c    10 Jan 2016 22:39:15 -0000
@@ -47,6 +47,7 @@ load_database(cron_db **db)
 {
        struct stat statbuf, syscron_stat;
        cron_db *new_db, *old_db = *db;
+       struct timespec mtime;
        struct dirent *dp;
        DIR *dir;
        user *u;
@@ -63,15 +64,20 @@ load_database(cron_db **db)
        /* track system crontab file
         */
        if (stat(_PATH_SYS_CRONTAB, &syscron_stat) < 0)
-               syscron_stat.st_mtime = 0;
+               timespecclear(&syscron_stat.st_mtim);
+
+       /* hash mtime of system crontab file and crontab dir
+        */
+       mtime.tv_sec =
+           HASH(statbuf.st_mtim.tv_sec, syscron_stat.st_mtim.tv_sec);
+       mtime.tv_nsec =
+           HASH(statbuf.st_mtim.tv_nsec, syscron_stat.st_mtim.tv_nsec);
 
        /* if spooldir's mtime has not changed, we don't need to fiddle with
         * the database.
         */
-       if (old_db != NULL &&
-           old_db->mtime == HASH(statbuf.st_mtime, syscron_stat.st_mtime)) {
+       if (old_db != NULL && timespeccmp(&mtime, &old_db->mtime, ==))
                return;
-       }
 
        /* something's different.  make a new database, moving unchanged
         * elements from the old database, reloading elements that have
@@ -80,10 +86,10 @@ load_database(cron_db **db)
         */
        if ((new_db = malloc(sizeof(*new_db))) == NULL)
                return;
-       new_db->mtime = HASH(statbuf.st_mtime, syscron_stat.st_mtime);
+       new_db->mtime = mtime;
        TAILQ_INIT(&new_db->users);
 
-       if (syscron_stat.st_mtime) {
+       if (timespecisset(&syscron_stat.st_mtim)) {
                process_crontab(AT_FDCWD, "*system*", _PATH_SYS_CRONTAB,
                                &syscron_stat, new_db, old_db);
        }
@@ -212,7 +218,7 @@ process_crontab(int dfd, const char *una
                /* if crontab has not changed since we last read it
                 * in, then we can just use our existing entry.
                 */
-               if (u->mtime == statbuf->st_mtime) {
+               if (timespeccmp(&u->mtime, &statbuf->st_mtim, ==)) {
                        TAILQ_REMOVE(&old_db->users, u, entries);
                        TAILQ_INSERT_TAIL(&new_db->users, u, entries);
                        goto next_crontab;
@@ -231,7 +237,7 @@ process_crontab(int dfd, const char *una
        }
        u = load_user(crontab_fd, pw, fname);
        if (u != NULL) {
-               u->mtime = statbuf->st_mtime;
+               u->mtime = statbuf->st_mtim;
                TAILQ_INSERT_TAIL(&new_db->users, u, entries);
        }
 
Index: usr.sbin/cron/structs.h
===================================================================
RCS file: /cvs/src/usr.sbin/cron/structs.h,v
retrieving revision 1.7
diff -u -p -u -r1.7 structs.h
--- usr.sbin/cron/structs.h     9 Nov 2015 01:12:27 -0000       1.7
+++ usr.sbin/cron/structs.h     10 Jan 2016 22:29:56 -0000
@@ -20,6 +20,7 @@
 #include <sys/queue.h>
 
 struct passwd;
+struct timespec;
 
 typedef        struct _entry {
        SLIST_ENTRY(_entry) entries;
@@ -50,13 +51,13 @@ typedef     struct _entry {
 typedef        struct _user {
        TAILQ_ENTRY(_user) entries;     /* links */
        char            *name;
-       time_t          mtime;          /* last modtime of crontab */
+       struct timespec mtime;          /* last modtime of crontab */
        SLIST_HEAD(crontab_list, _entry) crontab;       /* this person's 
crontab */
 } user;
 
 typedef        struct _cron_db {
        TAILQ_HEAD(user_list, _user) users;
-       time_t          mtime;          /* last modtime on spooldir */
+       struct timespec mtime;          /* last modtime on spooldir */
 } cron_db;
 
 typedef struct _atjob {
@@ -69,5 +70,5 @@ typedef struct _atjob {
 
 typedef struct _at_db {
        TAILQ_HEAD(atjob_list, _atjob) jobs;
-       time_t          mtime;          /* last modtime on spooldir */
+       struct timespec mtime;          /* last modtime on spooldir */
 } at_db;

Reply via email to