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;