do not let git_path clobber errno when reporting errors

Because git_path() calls vsnprintf(), code like fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666); die_errno(_("Could not write to '%s'"), git_path("SQUASH_MSG")); can end up printing an error indicator from vsnprintf() instead of open() by mistake. Store the path we are trying to write to in a temporary variable and pass _that_ to die_errno(), so the messages written by git cherry-pick/revert and git merge can avoid this source of confusion. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Nieder committed Nov 16, 2011 at 02:03 UTC 418c9b176cbabf954b6325cca0bea7f9be251afe
2 files changed +34 -24
builtin/merge.c
+29 -20
@@ -316,13 +316,15 @@ static void squash_message(struct commit *commit)
316 struct rev_info rev;
317 struct strbuf out = STRBUF_INIT;
318 struct commit_list *j;
319 + const char *filename;
320 int fd;
321 struct pretty_print_context ctx = {0};
322
323 printf(_("Squash commit -- not updating HEAD\n"));
323 - fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
324 + filename = git_path("SQUASH_MSG");
325 + fd = open(filename, O_WRONLY | O_CREAT, 0666);
326 if (fd < 0)
325 - die_errno(_("Could not write to '%s'"), git_path("SQUASH_MSG"));
327 + die_errno(_("Could not write to '%s'"), filename);
328
329 init_revisions(&rev, NULL);
330 rev.ignore_merges = 1;
@@ -492,14 +494,16 @@ static void merge_name(const char *remote, struct strbuf *msg)
494
495 if (!strcmp(remote, "FETCH_HEAD") &&
496 !access(git_path("FETCH_HEAD"), R_OK)) {
497 + const char *filename;
498 FILE *fp;
499 struct strbuf line = STRBUF_INIT;
500 char *ptr;
501
499 - fp = fopen(git_path("FETCH_HEAD"), "r");
502 + filename = git_path("FETCH_HEAD");
503 + fp = fopen(filename, "r");
504 if (!fp)
505 die_errno(_("could not open '%s' for reading"),
502 - git_path("FETCH_HEAD"));
506 + filename);
507 strbuf_getline(&line, fp, '\n');
508 fclose(fp);
509 ptr = strstr(line.buf, "\tnot-for-merge\t");
@@ -847,20 +851,22 @@ static void add_strategies(const char *string, unsigned attr)
851
852 static void write_merge_msg(struct strbuf *msg)
853 {
850 - int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
854 + const char *filename = git_path("MERGE_MSG");
855 + int fd = open(filename, O_WRONLY | O_CREAT, 0666);
856 if (fd < 0)
857 die_errno(_("Could not open '%s' for writing"),
853 - git_path("MERGE_MSG"));
858 + filename);
859 if (write_in_full(fd, msg->buf, msg->len) != msg->len)
855 - die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
860 + die_errno(_("Could not write to '%s'"), filename);
861 close(fd);
862 }
863
864 static void read_merge_msg(struct strbuf *msg)
865 {
866 + const char *filename = git_path("MERGE_MSG");
867 strbuf_reset(msg);
862 - if (strbuf_read_file(msg, git_path("MERGE_MSG"), 0) < 0)
863 - die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG"));
868 + if (strbuf_read_file(msg, filename, 0) < 0)
869 + die_errno(_("Could not read from '%s'"), filename);
870 }
871
872 static void write_merge_state(void);
@@ -948,13 +954,14 @@ static int finish_automerge(struct commit *head,
954
955 static int suggest_conflicts(int renormalizing)
956 {
957 + const char *filename;
958 FILE *fp;
959 int pos;
960
954 - fp = fopen(git_path("MERGE_MSG"), "a");
961 + filename = git_path("MERGE_MSG");
962 + fp = fopen(filename, "a");
963 if (!fp)
956 - die_errno(_("Could not open '%s' for writing"),
957 - git_path("MERGE_MSG"));
964 + die_errno(_("Could not open '%s' for writing"), filename);
965 fprintf(fp, "\nConflicts:\n");
966 for (pos = 0; pos < active_nr; pos++) {
967 struct cache_entry *ce = active_cache[pos];
@@ -1046,6 +1053,7 @@ static int setup_with_upstream(const char ***argv)
1053
1054 static void write_merge_state(void)
1055 {
1056 + const char *filename;
1057 int fd;
1058 struct commit_list *j;
1059 struct strbuf buf = STRBUF_INIT;
@@ -1053,24 +1061,25 @@ static void write_merge_state(void)
1061 for (j = remoteheads; j; j = j->next)
1062 strbuf_addf(&buf, "%s\n",
1063 sha1_to_hex(j->item->object.sha1));
1056 - fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
1064 + filename = git_path("MERGE_HEAD");
1065 + fd = open(filename, O_WRONLY | O_CREAT, 0666);
1066 if (fd < 0)
1058 - die_errno(_("Could not open '%s' for writing"),
1059 - git_path("MERGE_HEAD"));
1067 + die_errno(_("Could not open '%s' for writing"), filename);
1068 if (write_in_full(fd, buf.buf, buf.len) != buf.len)
1061 - die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD"));
1069 + die_errno(_("Could not write to '%s'"), filename);
1070 close(fd);
1071 strbuf_addch(&merge_msg, '\n');
1072 write_merge_msg(&merge_msg);
1065 - fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
1073 +
1074 + filename = git_path("MERGE_MODE");
1075 + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
1076 if (fd < 0)
1067 - die_errno(_("Could not open '%s' for writing"),
1068 - git_path("MERGE_MODE"));
1077 + die_errno(_("Could not open '%s' for writing"), filename);
1078 strbuf_reset(&buf);
1079 if (!allow_fast_forward)
1080 strbuf_addf(&buf, "no-ff");
1081 if (write_in_full(fd, buf.buf, buf.len) != buf.len)
1073 - die_errno(_("Could not write to '%s'"), git_path("MERGE_MODE"));
1082 + die_errno(_("Could not write to '%s'"), filename);
1083 close(fd);
1084 }
1085
builtin/revert.c
+5 -4
@@ -288,17 +288,18 @@ static char *get_encoding(const char *message)
288
289 static void write_cherry_pick_head(struct commit *commit)
290 {
291 + const char *filename;
292 int fd;
293 struct strbuf buf = STRBUF_INIT;
294
295 strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));
296
296 - fd = open(git_path("CHERRY_PICK_HEAD"), O_WRONLY | O_CREAT, 0666);
297 + filename = git_path("CHERRY_PICK_HEAD");
298 + fd = open(filename, O_WRONLY | O_CREAT, 0666);
299 if (fd < 0)
298 - die_errno(_("Could not open '%s' for writing"),
299 - git_path("CHERRY_PICK_HEAD"));
300 + die_errno(_("Could not open '%s' for writing"), filename);
301 if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd))
301 - die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
302 + die_errno(_("Could not write to '%s'"), filename);
303 strbuf_release(&buf);
304 }
305