freebsd-ports/devel/git/files/patch-fix-maintenance.diff
Renato Botelho 82c314474f devel/git: Fix 'git maintenance start'
Add a patch from upstream to fix 'git maintenance start'.  Here follow
upstream commit message:

While cron is specified by POSIX, there are a wide variety of
implementations in use.  On FreeBSD, the cron implementation requires a
file name argument: if the user wants to edit standard input, they must
specify "-".  However, this notation is not specified by POSIX, allowing
the possibility that making such a change may break other, less common
implementations.

Since POSIX tells us that cron must accept a file name argument, let's
solve this problem by specifying a temporary file instead.  This will
ensure that we work with the vast majority of implementations.

Note that because delete_tempfile closes the file for us, we should not
call fclose here on the handle, since doing so will introduce a double
free.

PR:		260746
Reported by:	Mark Waite <mark.earl.waite@gmail.com>
Obtained from:	https://lore.kernel.org/git/1dd29f43-1a8e-eb69-3320-7f5140a0e18e@github.com/T/#me47087c1f9034c82da8eae83db18cc6114c2c1e5
Sponsored by:	Rubicon Communications, LLC ("Netgate")
2022-08-29 07:49:23 -03:00

112 lines
3.5 KiB
Diff

[PATCH v2] gc: use temporary file for editing crontab
While cron is specified by POSIX, there are a wide variety of
implementations in use. On FreeBSD, the cron implementation requires a
file name argument: if the user wants to edit standard input, they must
specify "-". However, this notation is not specified by POSIX, allowing
the possibility that making such a change may break other, less common
implementations.
Since POSIX tells us that cron must accept a file name argument, let's
solve this problem by specifying a temporary file instead. This will
ensure that we work with the vast majority of implementations.
Note that because delete_tempfile closes the file for us, we should not
call fclose here on the handle, since doing so will introduce a double
free.
Reported-by: Renato Botelho <garga@FreeBSD.org>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
diff --git builtin/gc.c builtin/gc.c
index eeff2b760e..0d9e6dabef 100644
--- builtin/gc.c
+++ builtin/gc.c
@@ -2065,6 +2065,7 @@ static int crontab_update_schedule(int run_maintenance, int fd)
struct child_process crontab_edit = CHILD_PROCESS_INIT;
FILE *cron_list, *cron_in;
struct strbuf line = STRBUF_INIT;
+ struct tempfile *tmpedit = NULL;
get_schedule_cmd(&cmd, NULL);
strvec_split(&crontab_list.args, cmd);
@@ -2079,6 +2080,17 @@ static int crontab_update_schedule(int run_maintenance, int fd)
/* Ignore exit code, as an empty crontab will return error. */
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
* schedule while appending the new schedule.
@@ -2086,19 +2098,6 @@ static int crontab_update_schedule(int run_maintenance, int fd)
cron_list = fdopen(fd, "r");
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)) {
if (!in_old_region && !strcmp(line.buf, BEGIN_LINE))
in_old_region = 1;
@@ -2132,14 +2131,22 @@ static int crontab_update_schedule(int run_maintenance, int fd)
}
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))
result = error(_("'crontab' died"));
else
fclose(cron_list);
+out:
+ delete_tempfile(&tmpedit);
return result;
}
diff --git t/helper/test-crontab.c t/helper/test-crontab.c
index e7c0137a47..2942543046 100644
--- t/helper/test-crontab.c
+++ t/helper/test-crontab.c
@@ -17,8 +17,8 @@ int cmd__crontab(int argc, const char **argv)
if (!from)
return 0;
to = stdout;
- } else if (argc == 2) {
- from = stdin;
+ } else if (argc == 3) {
+ from = fopen(argv[2], "r");
to = fopen(argv[1], "w");
} else
return error("unknown arguments");