1494
#define BEGIN_LINE "# BEGIN GIT MAINTENANCE SCHEDULE"
1495
#define END_LINE "# END GIT MAINTENANCE SCHEDULE"
1496
1497
-static int update_background_schedule(int run_maintenance)
1497
+static int crontab_update_schedule(int run_maintenance, int fd, const char *cmd)
1498
{
1499
int result = 0;
1500
int in_old_region = 0;
1501
struct child_process crontab_list = CHILD_PROCESS_INIT;
1502
struct child_process crontab_edit = CHILD_PROCESS_INIT;
1503
FILE *cron_list, *cron_in;
1504
- const char *crontab_name;
1504
struct strbuf line = STRBUF_INIT;
1506
- struct lock_file lk;
1507
- char *lock_path = xstrfmt("%s/schedule", the_repository->objects->odb->path);
1505
1509
- if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0)
1510
- return error(_("another process is scheduling background maintenance"));
1511
-
1512
- crontab_name = getenv("GIT_TEST_CRONTAB");
1513
- if (!crontab_name)
1514
- crontab_name = "crontab";
1515
-
1516
- strvec_split(&crontab_list.args, crontab_name);
1506
+ strvec_split(&crontab_list.args, cmd);
1507
strvec_push(&crontab_list.args, "-l");
1508
crontab_list.in = -1;
1519
- crontab_list.out = dup(lk.tempfile->fd);
1509
+ crontab_list.out = dup(fd);
1510
crontab_list.git_cmd = 0;
1511
1522
- if (start_command(&crontab_list)) {
1523
- result = error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
1524
- goto cleanup;
1525
- }
1512
+ if (start_command(&crontab_list))
1513
+ return error(_("failed to run 'crontab -l'; your system might not support 'cron'"));
1514
1515
/* Ignore exit code, as an empty crontab will return error. */
1516
finish_command(&crontab_list);
1519
* Read from the .lock file, filtering out the old
1520
* schedule while appending the new schedule.
1521
*/
1534
- cron_list = fdopen(lk.tempfile->fd, "r");
1522
+ cron_list = fdopen(fd, "r");
1523
rewind(cron_list);
1524
1537
- strvec_split(&crontab_edit.args, crontab_name);
1525
+ strvec_split(&crontab_edit.args, cmd);
1526
crontab_edit.in = -1;
1527
crontab_edit.git_cmd = 0;
1528
1541
- if (start_command(&crontab_edit)) {
1542
- result = error(_("failed to run 'crontab'; your system might not support 'cron'"));
1543
- goto cleanup;
1544
- }
1529
+ if (start_command(&crontab_edit))
1530
+ return error(_("failed to run 'crontab'; your system might not support 'cron'"));
1531
1532
cron_in = fdopen(crontab_edit.in, "w");
1533
if (!cron_in) {
1572
close(crontab_edit.in);
1573
1574
done_editing:
1589
- if (finish_command(&crontab_edit)) {
1575
+ if (finish_command(&crontab_edit))
1576
result = error(_("'crontab' died"));
1591
- goto cleanup;
1577
+ else
1578
+ fclose(cron_list);
1579
+ return result;
1580
+}
1581
+
1582
+static const char platform_scheduler[] = "crontab";
1583
+
1584
+static int update_background_schedule(int enable)
1585
+{
1586
+ int result;
1587
+ const char *scheduler = platform_scheduler;
1588
+ const char *cmd = scheduler;
1589
+ char *testing;
1590
+ struct lock_file lk;
1591
+ char *lock_path = xstrfmt("%s/schedule", the_repository->objects->odb->path);
1592
+
1593
+ testing = xstrdup_or_null(getenv("GIT_TEST_MAINT_SCHEDULER"));
1594
+ if (testing) {
1595
+ char *sep = strchr(testing, ':');
1596
+ if (!sep)
1597
+ die("GIT_TEST_MAINT_SCHEDULER unparseable: %s", testing);
1598
+ *sep = '\0';
1599
+ scheduler = testing;
1600
+ cmd = sep + 1;
1601
}
1593
- fclose(cron_list);
1602
1595
-cleanup:
1603
+ if (hold_lock_file_for_update(&lk, lock_path, LOCK_NO_DEREF) < 0)
1604
+ return error(_("another process is scheduling background maintenance"));
1605
+
1606
+ if (!strcmp(scheduler, "crontab"))
1607
+ result = crontab_update_schedule(enable, lk.tempfile->fd, cmd);
1608
+ else
1609
+ die("unknown background scheduler: %s", scheduler);
1610
+
1611
rollback_lock_file(&lk);
1612
+ free(testing);
1613
return result;
1614
}
1615