Merge branch 'bc/gc-crontab-fix'

FreeBSD portability fix for "git maintenance" that spawns "crontab"
to schedule tasks.

* bc/gc-crontab-fix:
  gc: use temporary file for editing crontab
This commit is contained in:
Junio C Hamano 2022-09-05 18:33:41 -07:00
commit 56785a3fad
2 changed files with 25 additions and 18 deletions

View File

@ -2087,6 +2087,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)
struct child_process crontab_edit = CHILD_PROCESS_INIT; struct child_process crontab_edit = CHILD_PROCESS_INIT;
FILE *cron_list, *cron_in; FILE *cron_list, *cron_in;
struct strbuf line = STRBUF_INIT; struct strbuf line = STRBUF_INIT;
struct tempfile *tmpedit = NULL;
get_schedule_cmd(&cmd, NULL); get_schedule_cmd(&cmd, NULL);
strvec_split(&crontab_list.args, cmd); strvec_split(&crontab_list.args, cmd);
@ -2101,6 +2102,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
/* Ignore exit code, as an empty crontab will return error. */ /* Ignore exit code, as an empty crontab will return error. */
finish_command(&crontab_list); finish_command(&crontab_list);
tmpedit = mks_tempfile_t(".git_cron_edit_tmpXXXXXX");
if (!tmpedit) {
result = error(_("failed to create crontab temporary file"));
goto out;
}
cron_in = fdopen_tempfile(tmpedit, "w");
if (!cron_in) {
result = error(_("failed to open temporary file"));
goto out;
}
/* /*
* Read from the .lock file, filtering out the old * Read from the .lock file, filtering out the old
* schedule while appending the new schedule. * schedule while appending the new schedule.
@ -2108,19 +2120,6 @@ static int crontab_update_schedule(int run_maintenance, int fd)
cron_list = fdopen(fd, "r"); cron_list = fdopen(fd, "r");
rewind(cron_list); rewind(cron_list);
strvec_split(&crontab_edit.args, cmd);
crontab_edit.in = -1;
crontab_edit.git_cmd = 0;
if (start_command(&crontab_edit))
return error(_("failed to run 'crontab'; your system might not support 'cron'"));
cron_in = fdopen(crontab_edit.in, "w");
if (!cron_in) {
result = error(_("failed to open stdin of 'crontab'"));
goto done_editing;
}
while (!strbuf_getline_lf(&line, cron_list)) { while (!strbuf_getline_lf(&line, cron_list)) {
if (!in_old_region && !strcmp(line.buf, BEGIN_LINE)) if (!in_old_region && !strcmp(line.buf, BEGIN_LINE))
in_old_region = 1; in_old_region = 1;
@ -2154,14 +2153,22 @@ static int crontab_update_schedule(int run_maintenance, int fd)
} }
fflush(cron_in); fflush(cron_in);
fclose(cron_in);
close(crontab_edit.in);
done_editing: strvec_split(&crontab_edit.args, cmd);
strvec_push(&crontab_edit.args, get_tempfile_path(tmpedit));
crontab_edit.git_cmd = 0;
if (start_command(&crontab_edit)) {
result = error(_("failed to run 'crontab'; your system might not support 'cron'"));
goto out;
}
if (finish_command(&crontab_edit)) if (finish_command(&crontab_edit))
result = error(_("'crontab' died")); result = error(_("'crontab' died"));
else else
fclose(cron_list); fclose(cron_list);
out:
delete_tempfile(&tmpedit);
return result; return result;
} }

View File

@ -17,8 +17,8 @@ int cmd__crontab(int argc, const char **argv)
if (!from) if (!from)
return 0; return 0;
to = stdout; to = stdout;
} else if (argc == 2) { } else if (argc == 3) {
from = stdin; from = fopen(argv[2], "r");
to = fopen(argv[1], "w"); to = fopen(argv[1], "w");
} else } else
return error("unknown arguments"); return error("unknown arguments");