aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2026-05-14 16:05:56 +0100
committerRon Yorston <rmy@pobox.com>2026-05-15 07:52:14 +0100
commit7dfc5b04974ac428d8f43cf84a4e2d7ceb193675 (patch)
tree9c8bba256715a81d84b698b044ba88cc10711066
parent7c5a95ba4d0a05145d42e17e74c7c991a0c4ff76 (diff)
downloadbusybox-w32-cron_changes.tar.gz
busybox-w32-cron_changes.tar.bz2
busybox-w32-cron_changes.zip
crond: fix reboot special timecron_changes
The 'reboot' special time didn't work because the file to check for a reboot couldn't be created. And in any case, the mechanism used on Linux wouldn't work: Windows has no /var/run directory which is cleared on reboot. The crond.reboot file is now placed in the cron directory. If it doesn't exist when crond starts, it's created but the reboot job (if any) isn't run. If the file exists its modification time is compared with the time of the current boot. If it's older update its time and run the reboot job. Adds 144-224 bytes.
-rw-r--r--miscutils/crond.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 7278a1ad4..4bfe4a6c0 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -103,7 +103,11 @@
103 103
104#define CRON_DIR CONFIG_FEATURE_CROND_DIR 104#define CRON_DIR CONFIG_FEATURE_CROND_DIR
105#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs" 105#define CRONTABS CONFIG_FEATURE_CROND_DIR "/crontabs"
106#if ENABLE_PLATFORM_MINGW32
107#define CRON_REBOOT "crond.reboot"
108#else
106#define CRON_REBOOT CONFIG_PID_FILE_PATH "/crond.reboot" 109#define CRON_REBOOT CONFIG_PID_FILE_PATH "/crond.reboot"
110#endif
107#ifndef SENDMAIL 111#ifndef SENDMAIL
108# define SENDMAIL "sendmail" 112# define SENDMAIL "sendmail"
109#endif 113#endif
@@ -176,6 +180,7 @@ struct globals {
176 const char *crontab_dir_name; /* = CRONTABS; */ 180 const char *crontab_dir_name; /* = CRONTABS; */
177#if ENABLE_PLATFORM_MINGW32 181#if ENABLE_PLATFORM_MINGW32
178 const char *crondir_name; /* = CRON_DIR; */ 182 const char *crondir_name; /* = CRON_DIR; */
183 const char *reboot_name;
179#endif 184#endif
180 CronFile *cron_files; 185 CronFile *cron_files;
181 char *default_shell; 186 char *default_shell;
@@ -1061,6 +1066,30 @@ static void flag_starting_jobs(time_t t1, time_t t2)
1061#if ENABLE_FEATURE_CROND_SPECIAL_TIMES 1066#if ENABLE_FEATURE_CROND_SPECIAL_TIMES
1062static int touch_reboot_file(void) 1067static int touch_reboot_file(void)
1063{ 1068{
1069#if ENABLE_PLATFORM_MINGW32
1070 struct stat st;
1071 struct timespec now;
1072 long long ms_since_boot;
1073 const struct timespec ts[2] = {{0, UTIME_NOW}, {0, UTIME_NOW}};
1074 int fd, ret = 0;
1075
1076 if (stat(G.reboot_name, &st) == 0) {
1077 clock_gettime(CLOCK_REALTIME, &now);
1078 ms_since_boot = GetTickCount64();
1079
1080 if (st.st_mtim.tv_sec < now.tv_sec - ms_since_boot/1000) {
1081 // crond.reboot predates boot time, update it and run job
1082 utimensat(AT_FDCWD, G.reboot_name, ts, 0);
1083 ret = 1;
1084 }
1085 } else {
1086 // crond.reboot doesn't exist, create it, but don't run job
1087 fd = open(G.reboot_name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0000);
1088 if (fd >= 0)
1089 close(fd);
1090 }
1091 return ret;
1092#else
1064 int fd = open(CRON_REBOOT, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0000); 1093 int fd = open(CRON_REBOOT, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0000);
1065 if (fd >= 0) { 1094 if (fd >= 0) {
1066 close(fd); 1095 close(fd);
@@ -1068,6 +1097,7 @@ static int touch_reboot_file(void)
1068 } 1097 }
1069 /* File (presumably) exists - this is not the first run after reboot */ 1098 /* File (presumably) exists - this is not the first run after reboot */
1070 return 0; 1099 return 0;
1100#endif
1071} 1101}
1072#endif 1102#endif
1073 1103
@@ -1242,6 +1272,7 @@ int crond_main(int argc UNUSED_PARAM, char **argv)
1242 free((void *)G.crondir_name); 1272 free((void *)G.crondir_name);
1243 G.crondir_name = dirname(xstrdup(G.crontab_dir_name)); 1273 G.crondir_name = dirname(xstrdup(G.crontab_dir_name));
1244 } 1274 }
1275 G.reboot_name = concat_path_file(G.crondir_name, CRON_REBOOT);
1245#endif 1276#endif
1246 1277
1247 if (!(opts & OPT_f)) { 1278 if (!(opts & OPT_f)) {