Skip to content

Commit 95235f5

Browse files
dschogitster
authored andcommitted
format-patch: avoid freopen()
We just taught the relevant functions to respect the diffopt.file field, to allow writing somewhere else than stdout. Let's make use of it. Technically, we do not need to avoid that call in a builtin: we assume that builtins (as opposed to library functions) are stand-alone programs that may do with their (global) state. Yet, we want to be able to reuse that code in properly lib-ified code, e.g. when converting scripts into builtins. Further, while we did not *have* to touch the cmd_show() and cmd_cherry() code paths (because they do not want to write anywhere but stdout as of yet), it just makes sense to be consistent, making it easier and safer to move the code later. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 11f4eb1 commit 95235f5

1 file changed

Lines changed: 33 additions & 31 deletions

File tree

builtin/log.c

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ static void show_early_header(struct rev_info *rev, const char *stage, int nr)
236236
if (rev->commit_format != CMIT_FMT_ONELINE)
237237
putchar(rev->diffopt.line_termination);
238238
}
239-
printf(_("Final output: %d %s\n"), nr, stage);
239+
fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage);
240240
}
241241

242242
static struct itimerval early_output_timer;
@@ -454,7 +454,7 @@ static void show_tagger(char *buf, int len, struct rev_info *rev)
454454
pp.fmt = rev->commit_format;
455455
pp.date_mode = rev->date_mode;
456456
pp_user_info(&pp, "Tagger", &out, buf, get_log_output_encoding());
457-
printf("%s", out.buf);
457+
fprintf(rev->diffopt.file, "%s", out.buf);
458458
strbuf_release(&out);
459459
}
460460

@@ -465,7 +465,7 @@ static int show_blob_object(const unsigned char *sha1, struct rev_info *rev, con
465465
char *buf;
466466
unsigned long size;
467467

468-
fflush(stdout);
468+
fflush(rev->diffopt.file);
469469
if (!DIFF_OPT_TOUCHED(&rev->diffopt, ALLOW_TEXTCONV) ||
470470
!DIFF_OPT_TST(&rev->diffopt, ALLOW_TEXTCONV))
471471
return stream_blob_to_fd(1, sha1, NULL, 0);
@@ -505,7 +505,7 @@ static int show_tag_object(const unsigned char *sha1, struct rev_info *rev)
505505
}
506506

507507
if (offset < size)
508-
fwrite(buf + offset, size - offset, 1, stdout);
508+
fwrite(buf + offset, size - offset, 1, rev->diffopt.file);
509509
free(buf);
510510
return 0;
511511
}
@@ -514,7 +514,8 @@ static int show_tree_object(const unsigned char *sha1,
514514
struct strbuf *base,
515515
const char *pathname, unsigned mode, int stage, void *context)
516516
{
517-
printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
517+
FILE *file = context;
518+
fprintf(file, "%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
518519
return 0;
519520
}
520521

@@ -574,7 +575,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
574575

575576
if (rev.shown_one)
576577
putchar('\n');
577-
printf("%stag %s%s\n",
578+
fprintf(rev.diffopt.file, "%stag %s%s\n",
578579
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
579580
t->tag,
580581
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
@@ -593,12 +594,12 @@ int cmd_show(int argc, const char **argv, const char *prefix)
593594
case OBJ_TREE:
594595
if (rev.shown_one)
595596
putchar('\n');
596-
printf("%stree %s%s\n\n",
597+
fprintf(rev.diffopt.file, "%stree %s%s\n\n",
597598
diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
598599
name,
599600
diff_get_color_opt(&rev.diffopt, DIFF_RESET));
600601
read_tree_recursive((struct tree *)o, "", 0, 0, &match_all,
601-
show_tree_object, NULL);
602+
show_tree_object, rev.diffopt.file);
602603
rev.shown_one = 1;
603604
break;
604605
case OBJ_COMMIT:
@@ -808,7 +809,7 @@ static FILE *realstdout = NULL;
808809
static const char *output_directory = NULL;
809810
static int outdir_offset;
810811

811-
static int reopen_stdout(struct commit *commit, const char *subject,
812+
static int open_next_file(struct commit *commit, const char *subject,
812813
struct rev_info *rev, int quiet)
813814
{
814815
struct strbuf filename = STRBUF_INIT;
@@ -832,7 +833,7 @@ static int reopen_stdout(struct commit *commit, const char *subject,
832833
if (!quiet)
833834
fprintf(realstdout, "%s\n", filename.buf + outdir_offset);
834835

835-
if (freopen(filename.buf, "w", stdout) == NULL)
836+
if ((rev->diffopt.file = fopen(filename.buf, "w")) == NULL)
836837
return error(_("Cannot open patch file %s"), filename.buf);
837838

838839
strbuf_release(&filename);
@@ -891,15 +892,15 @@ static void gen_message_id(struct rev_info *info, char *base)
891892
info->message_id = strbuf_detach(&buf, NULL);
892893
}
893894

894-
static void print_signature(void)
895+
static void print_signature(FILE *file)
895896
{
896897
if (!signature || !*signature)
897898
return;
898899

899-
printf("-- \n%s", signature);
900+
fprintf(file, "-- \n%s", signature);
900901
if (signature[strlen(signature)-1] != '\n')
901-
putchar('\n');
902-
putchar('\n');
902+
putc('\n', file);
903+
putc('\n', file);
903904
}
904905

905906
static void add_branch_description(struct strbuf *buf, const char *branch_name)
@@ -968,7 +969,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
968969
committer = git_committer_info(0);
969970

970971
if (!use_stdout &&
971-
reopen_stdout(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
972+
open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
972973
return;
973974

974975
log_write_email_headers(rev, head, &pp.subject, &pp.after_subject,
@@ -991,7 +992,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
991992
pp_title_line(&pp, &msg, &sb, encoding, need_8bit_cte);
992993
pp_remainder(&pp, &msg, &sb, 0);
993994
add_branch_description(&sb, branch_name);
994-
printf("%s\n", sb.buf);
995+
fprintf(rev->diffopt.file, "%s\n", sb.buf);
995996

996997
strbuf_release(&sb);
997998

@@ -1000,6 +1001,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
10001001
log.wrap = 72;
10011002
log.in1 = 2;
10021003
log.in2 = 4;
1004+
log.file = rev->diffopt.file;
10031005
for (i = 0; i < nr; i++)
10041006
shortlog_add_commit(&log, list[i]);
10051007

@@ -1022,8 +1024,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
10221024
diffcore_std(&opts);
10231025
diff_flush(&opts);
10241026

1025-
printf("\n");
1026-
print_signature();
1027+
fprintf(rev->diffopt.file, "\n");
1028+
print_signature(rev->diffopt.file);
10271029
}
10281030

10291031
static const char *clean_message_id(const char *msg_id)
@@ -1333,7 +1335,7 @@ static void prepare_bases(struct base_tree_info *bases,
13331335
}
13341336
}
13351337

1336-
static void print_bases(struct base_tree_info *bases)
1338+
static void print_bases(struct base_tree_info *bases, FILE *file)
13371339
{
13381340
int i;
13391341

@@ -1342,11 +1344,11 @@ static void print_bases(struct base_tree_info *bases)
13421344
return;
13431345

13441346
/* Show the base commit */
1345-
printf("base-commit: %s\n", oid_to_hex(&bases->base_commit));
1347+
fprintf(file, "base-commit: %s\n", oid_to_hex(&bases->base_commit));
13461348

13471349
/* Show the prerequisite patches */
13481350
for (i = bases->nr_patch_id - 1; i >= 0; i--)
1349-
printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
1351+
fprintf(file, "prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i]));
13501352

13511353
free(bases->patch_id);
13521354
bases->nr_patch_id = 0;
@@ -1704,7 +1706,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
17041706
gen_message_id(&rev, "cover");
17051707
make_cover_letter(&rev, use_stdout,
17061708
origin, nr, list, branch_name, quiet);
1707-
print_bases(&bases);
1709+
print_bases(&bases, rev.diffopt.file);
17081710
total++;
17091711
start_number--;
17101712
}
@@ -1750,7 +1752,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
17501752
}
17511753

17521754
if (!use_stdout &&
1753-
reopen_stdout(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
1755+
open_next_file(rev.numbered_files ? NULL : commit, NULL, &rev, quiet))
17541756
die(_("Failed to create output files"));
17551757
shown = log_tree_commit(&rev, commit);
17561758
free_commit_buffer(commit);
@@ -1765,15 +1767,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
17651767
rev.shown_one = 0;
17661768
if (shown) {
17671769
if (rev.mime_boundary)
1768-
printf("\n--%s%s--\n\n\n",
1770+
fprintf(rev.diffopt.file, "\n--%s%s--\n\n\n",
17691771
mime_boundary_leader,
17701772
rev.mime_boundary);
17711773
else
1772-
print_signature();
1773-
print_bases(&bases);
1774+
print_signature(rev.diffopt.file);
1775+
print_bases(&bases, rev.diffopt.file);
17741776
}
17751777
if (!use_stdout)
1776-
fclose(stdout);
1778+
fclose(rev.diffopt.file);
17771779
}
17781780
free(list);
17791781
free(branch_name);
@@ -1805,15 +1807,15 @@ static const char * const cherry_usage[] = {
18051807
};
18061808

18071809
static void print_commit(char sign, struct commit *commit, int verbose,
1808-
int abbrev)
1810+
int abbrev, FILE *file)
18091811
{
18101812
if (!verbose) {
1811-
printf("%c %s\n", sign,
1813+
fprintf(file, "%c %s\n", sign,
18121814
find_unique_abbrev(commit->object.oid.hash, abbrev));
18131815
} else {
18141816
struct strbuf buf = STRBUF_INIT;
18151817
pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
1816-
printf("%c %s %s\n", sign,
1818+
fprintf(file, "%c %s %s\n", sign,
18171819
find_unique_abbrev(commit->object.oid.hash, abbrev),
18181820
buf.buf);
18191821
strbuf_release(&buf);
@@ -1894,7 +1896,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
18941896
commit = list->item;
18951897
if (has_commit_patch_id(commit, &ids))
18961898
sign = '-';
1897-
print_commit(sign, commit, verbose, abbrev);
1899+
print_commit(sign, commit, verbose, abbrev, revs.diffopt.file);
18981900
list = list->next;
18991901
}
19001902

0 commit comments

Comments
 (0)