Skip to content

Commit 56785a3

Browse files
committed
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
2 parents 2d88021 + ee69e78 commit 56785a3

File tree

2 files changed

+25
-18
lines changed

2 files changed

+25
-18
lines changed

builtin/gc.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,6 +2087,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)
20872087
struct child_process crontab_edit = CHILD_PROCESS_INIT;
20882088
FILE *cron_list, *cron_in;
20892089
struct strbuf line = STRBUF_INIT;
2090+
struct tempfile *tmpedit = NULL;
20902091

20912092
get_schedule_cmd(&cmd, NULL);
20922093
strvec_split(&crontab_list.args, cmd);
@@ -2101,26 +2102,24 @@ static int crontab_update_schedule(int run_maintenance, int fd)
21012102
/* Ignore exit code, as an empty crontab will return error. */
21022103
finish_command(&crontab_list);
21032104

2105+
tmpedit = mks_tempfile_t(".git_cron_edit_tmpXXXXXX");
2106+
if (!tmpedit) {
2107+
result = error(_("failed to create crontab temporary file"));
2108+
goto out;
2109+
}
2110+
cron_in = fdopen_tempfile(tmpedit, "w");
2111+
if (!cron_in) {
2112+
result = error(_("failed to open temporary file"));
2113+
goto out;
2114+
}
2115+
21042116
/*
21052117
* Read from the .lock file, filtering out the old
21062118
* schedule while appending the new schedule.
21072119
*/
21082120
cron_list = fdopen(fd, "r");
21092121
rewind(cron_list);
21102122

2111-
strvec_split(&crontab_edit.args, cmd);
2112-
crontab_edit.in = -1;
2113-
crontab_edit.git_cmd = 0;
2114-
2115-
if (start_command(&crontab_edit))
2116-
return error(_("failed to run 'crontab'; your system might not support 'cron'"));
2117-
2118-
cron_in = fdopen(crontab_edit.in, "w");
2119-
if (!cron_in) {
2120-
result = error(_("failed to open stdin of 'crontab'"));
2121-
goto done_editing;
2122-
}
2123-
21242123
while (!strbuf_getline_lf(&line, cron_list)) {
21252124
if (!in_old_region && !strcmp(line.buf, BEGIN_LINE))
21262125
in_old_region = 1;
@@ -2154,14 +2153,22 @@ static int crontab_update_schedule(int run_maintenance, int fd)
21542153
}
21552154

21562155
fflush(cron_in);
2157-
fclose(cron_in);
2158-
close(crontab_edit.in);
21592156

2160-
done_editing:
2157+
strvec_split(&crontab_edit.args, cmd);
2158+
strvec_push(&crontab_edit.args, get_tempfile_path(tmpedit));
2159+
crontab_edit.git_cmd = 0;
2160+
2161+
if (start_command(&crontab_edit)) {
2162+
result = error(_("failed to run 'crontab'; your system might not support 'cron'"));
2163+
goto out;
2164+
}
2165+
21612166
if (finish_command(&crontab_edit))
21622167
result = error(_("'crontab' died"));
21632168
else
21642169
fclose(cron_list);
2170+
out:
2171+
delete_tempfile(&tmpedit);
21652172
return result;
21662173
}
21672174

t/helper/test-crontab.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ int cmd__crontab(int argc, const char **argv)
1717
if (!from)
1818
return 0;
1919
to = stdout;
20-
} else if (argc == 2) {
21-
from = stdin;
20+
} else if (argc == 3) {
21+
from = fopen(argv[2], "r");
2222
to = fopen(argv[1], "w");
2323
} else
2424
return error("unknown arguments");

0 commit comments

Comments
 (0)