diff -up cronie-1.2/src/database.c.reload cronie-1.2/src/database.c --- cronie-1.2/src/database.c.reload 2008-12-19 11:34:04.000000000 +0100 +++ cronie-1.2/src/database.c 2008-12-22 14:22:30.000000000 +0100 @@ -153,7 +153,7 @@ process_crontab(const char *uname, const #if defined WITH_INOTIFY void -check_inotify_database(cron_db *old_db, int fd) { +check_inotify_database(cron_db *old_db) { cron_db new_db; DIR_T *dp; DIR *dir; @@ -167,17 +167,18 @@ check_inotify_database(cron_db *old_db, time.tv_usec = 0; FD_ZERO(&rfds); - FD_SET(fd, &rfds); + FD_SET(old_db->ifd, &rfds); - retval = select(fd + 1, &rfds, NULL, NULL, &time); + retval = select(old_db->ifd + 1, &rfds, NULL, NULL, &time); if (retval == -1) { if (errno != EINTR) log_it("CRON", pid, "INOTIFY", "select failed", errno); return; } - else if (FD_ISSET(fd, &rfds)) { + else if (FD_ISSET(old_db->ifd, &rfds)) { new_db.head = new_db.tail = NULL; - while ((retval=read(fd, buf, sizeof(buf))) == -1 && errno == EINTR); + new_db.ifd = old_db->ifd; + while ((retval=read(old_db->ifd, buf, sizeof(buf))) == -1 && errno == EINTR); if (retval == 0) { /* this should not happen as the buffer is large enough */ @@ -195,7 +196,7 @@ check_inotify_database(cron_db *old_db, /* we must reinstate the watches here - TODO reinstate only watches * which get IN_IGNORED event */ - set_cron_watched(fd); + set_cron_watched(old_db->ifd); /* TODO: parse the events and read only affected files */ @@ -269,7 +270,7 @@ overwrite_database(cron_db *old_db, cron *old_db = *new_db; } -void +int load_database(cron_db *old_db) { struct stat statbuf, syscron_stat, crond_stat; cron_db new_db; @@ -318,7 +319,7 @@ load_database(cron_db *old_db) { ){ Debug(DLOAD, ("[%ld] spool dir mtime unch, no load needed.\n", (long)pid)) - return; + return 0; } /* something's different. make a new database, moving unchanged @@ -329,6 +330,9 @@ load_database(cron_db *old_db) { new_db.mtime = TMAX(crond_stat.st_mtime, TMAX(statbuf.st_mtime, syscron_stat.st_mtime)); new_db.head = new_db.tail = NULL; +#if defined WITH_INOTIFY + new_db.ifd = old_db->ifd; +#endif if (syscron_stat.st_mtime) process_crontab("root", NULL, SYSCRONTAB, &new_db, old_db); @@ -382,6 +386,7 @@ load_database(cron_db *old_db) { overwrite_database(old_db, &new_db); Debug(DLOAD, ("load_database is done\n")) + return 1; } void diff -up cronie-1.2/src/funcs.h.reload cronie-1.2/src/funcs.h --- cronie-1.2/src/funcs.h.reload 2008-06-26 14:56:00.000000000 +0200 +++ cronie-1.2/src/funcs.h 2008-12-22 12:12:30.000000000 +0100 @@ -41,14 +41,13 @@ void set_cron_uid(void), log_it(const char *, PID_T, const char *, const char *, int), log_close(void); #if defined WITH_INOTIFY -void load_inotify_database(cron_db *, int ), - set_cron_watched(int ), +void set_cron_watched(int ), set_cron_unwatched(int ), - check_inotify_database(cron_db *, int ); + check_inotify_database(cron_db *); #endif -void load_database(cron_db *); -int job_runqueue(void), +int load_database(cron_db *), + job_runqueue(void), set_debug_flags(const char *), get_char(FILE *), get_string(char *, int, FILE *, char *), diff -up cronie-1.2/src/structs.h.reload cronie-1.2/src/structs.h --- cronie-1.2/src/structs.h.reload 2008-06-26 14:56:00.000000000 +0200 +++ cronie-1.2/src/structs.h 2008-12-22 12:06:04.000000000 +0100 @@ -60,6 +60,9 @@ typedef struct _user { typedef struct _cron_db { user *head, *tail; /* links */ time_t mtime; /* last modtime on spooldir */ +#ifdef WITH_INOTIFY + int ifd; +#endif } cron_db; /* in the C tradition, we only create * variables for the main program, just diff -up cronie-1.2/src/cron.c.reload cronie-1.2/src/cron.c --- cronie-1.2/src/cron.c.reload 2008-06-26 14:56:00.000000000 +0200 +++ cronie-1.2/src/cron.c 2008-12-22 14:38:13.000000000 +0100 @@ -79,7 +79,8 @@ set_cron_watched(int fd) { int w; w = inotify_add_watch(fd, watchpaths[i], - IN_CLOSE_WRITE | IN_ATTRIB | IN_MOVED_TO | IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE); + IN_CREATE | IN_CLOSE_WRITE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO | + IN_MOVED_FROM | IN_MOVE_SELF | IN_DELETE | IN_DELETE_SELF); if (w < 0) { if (wd[i] != -1) { log_it("CRON", pid, "This directory or file can't be watched", watchpaths[i], errno); @@ -101,6 +102,27 @@ set_cron_watched(int fd) { #endif static void +handle_signals(cron_db *database) { + if (got_sighup) { + got_sighup = 0; +#if defined WITH_INOTIFY + /* watches must be reinstated on reload */ + if (inotify_enabled) { + set_cron_unwatched(database->ifd); + inotify_enabled = 0; + } +#endif + database->mtime = (time_t) 0; + log_close(); + } + + if (got_sigchld) { + got_sigchld = 0; + sigchld_reaper(); + } +} + +static void usage(void) { const char **dflags; @@ -216,7 +238,7 @@ main(int argc, char *argv[]) { wd[i] = -2; } - fd = inotify_init(); + database.ifd = fd = inotify_init(); if (fd < 0) log_it("CRON", pid, "INFO", "Inotify init failed", errno); set_cron_watched(fd); @@ -252,19 +274,19 @@ main(int argc, char *argv[]) { * clock. Classify the change into one of 4 cases. */ timeDiff = timeRunning - virtualTime; - if (inotify_enabled) { #if defined WITH_INOTIFY - check_inotify_database(&database, fd); -#endif + if (inotify_enabled) { + check_inotify_database(&database); } else { - load_database(&database); -#if defined WITH_INOTIFY - /* try reinstating the watches */ - set_cron_watched(fd); -#endif + if(load_database(&database)) + /* try reinstating the watches */ + set_cron_watched(fd); } - +#else + load_database(&database); +#endif + /* shortcut for the most common case */ if (timeDiff == 1) { virtualTime = timeRunning; @@ -354,17 +376,7 @@ main(int argc, char *argv[]) { /* Jobs to be run (if any) are loaded; clear the queue. */ job_runqueue(); - /* Check to see if we received a signal while running jobs. */ - if (got_sighup) { - got_sighup = 0; - if (!inotify_enabled) - database.mtime = (time_t) 0; - log_close(); - } - if (got_sigchld) { - got_sigchld = 0; - sigchld_reaper(); - } + handle_signals(&database); } #if defined WITH_INOTIFY @@ -502,16 +514,8 @@ cron_sleep(int target, cron_db *db) { * If so, service the signal(s) then continue sleeping * where we left off. */ - if (got_sighup) { - got_sighup = 0; - if (!inotify_enabled) - db->mtime = (time_t) 0; - log_close(); - } - if (got_sigchld) { - got_sigchld = 0; - sigchld_reaper(); - } + handle_signals(db); + t2 = time(NULL) + GMToff; seconds_to_wait -= (int)(t2 - t1); t1 = t2;