Skip to content

Commit

Permalink
do not let git_path clobber errno when reporting errors
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jrn authored and gitster committed Nov 17, 2011
1 parent 4d2440f commit 418c9b1
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 24 deletions.
49 changes: 29 additions & 20 deletions builtin/merge.c
Expand Up @@ -316,13 +316,15 @@ static void squash_message(struct commit *commit)
struct rev_info rev;
struct strbuf out = STRBUF_INIT;
struct commit_list *j;
const char *filename;
int fd;
struct pretty_print_context ctx = {0};

printf(_("Squash commit -- not updating HEAD\n"));
fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
filename = git_path("SQUASH_MSG");
fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not write to '%s'"), git_path("SQUASH_MSG"));
die_errno(_("Could not write to '%s'"), filename);

init_revisions(&rev, NULL);
rev.ignore_merges = 1;
Expand Down Expand Up @@ -492,14 +494,16 @@ static void merge_name(const char *remote, struct strbuf *msg)

if (!strcmp(remote, "FETCH_HEAD") &&
!access(git_path("FETCH_HEAD"), R_OK)) {
const char *filename;
FILE *fp;
struct strbuf line = STRBUF_INIT;
char *ptr;

fp = fopen(git_path("FETCH_HEAD"), "r");
filename = git_path("FETCH_HEAD");
fp = fopen(filename, "r");
if (!fp)
die_errno(_("could not open '%s' for reading"),
git_path("FETCH_HEAD"));
filename);
strbuf_getline(&line, fp, '\n');
fclose(fp);
ptr = strstr(line.buf, "\tnot-for-merge\t");
Expand Down Expand Up @@ -847,20 +851,22 @@ static void add_strategies(const char *string, unsigned attr)

static void write_merge_msg(struct strbuf *msg)
{
int fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
const char *filename = git_path("MERGE_MSG");
int fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_MSG"));
filename);
if (write_in_full(fd, msg->buf, msg->len) != msg->len)
die_errno(_("Could not write to '%s'"), git_path("MERGE_MSG"));
die_errno(_("Could not write to '%s'"), filename);
close(fd);
}

static void read_merge_msg(struct strbuf *msg)
{
const char *filename = git_path("MERGE_MSG");
strbuf_reset(msg);
if (strbuf_read_file(msg, git_path("MERGE_MSG"), 0) < 0)
die_errno(_("Could not read from '%s'"), git_path("MERGE_MSG"));
if (strbuf_read_file(msg, filename, 0) < 0)
die_errno(_("Could not read from '%s'"), filename);
}

static void write_merge_state(void);
Expand Down Expand Up @@ -948,13 +954,14 @@ static int finish_automerge(struct commit *head,

static int suggest_conflicts(int renormalizing)
{
const char *filename;
FILE *fp;
int pos;

fp = fopen(git_path("MERGE_MSG"), "a");
filename = git_path("MERGE_MSG");
fp = fopen(filename, "a");
if (!fp)
die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_MSG"));
die_errno(_("Could not open '%s' for writing"), filename);
fprintf(fp, "\nConflicts:\n");
for (pos = 0; pos < active_nr; pos++) {
struct cache_entry *ce = active_cache[pos];
Expand Down Expand Up @@ -1046,31 +1053,33 @@ static int setup_with_upstream(const char ***argv)

static void write_merge_state(void)
{
const char *filename;
int fd;
struct commit_list *j;
struct strbuf buf = STRBUF_INIT;

for (j = remoteheads; j; j = j->next)
strbuf_addf(&buf, "%s\n",
sha1_to_hex(j->item->object.sha1));
fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
filename = git_path("MERGE_HEAD");
fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_HEAD"));
die_errno(_("Could not open '%s' for writing"), filename);
if (write_in_full(fd, buf.buf, buf.len) != buf.len)
die_errno(_("Could not write to '%s'"), git_path("MERGE_HEAD"));
die_errno(_("Could not write to '%s'"), filename);
close(fd);
strbuf_addch(&merge_msg, '\n');
write_merge_msg(&merge_msg);
fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);

filename = git_path("MERGE_MODE");
fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"),
git_path("MERGE_MODE"));
die_errno(_("Could not open '%s' for writing"), filename);
strbuf_reset(&buf);
if (!allow_fast_forward)
strbuf_addf(&buf, "no-ff");
if (write_in_full(fd, buf.buf, buf.len) != buf.len)
die_errno(_("Could not write to '%s'"), git_path("MERGE_MODE"));
die_errno(_("Could not write to '%s'"), filename);
close(fd);
}

Expand Down
9 changes: 5 additions & 4 deletions builtin/revert.c
Expand Up @@ -288,17 +288,18 @@ static char *get_encoding(const char *message)

static void write_cherry_pick_head(struct commit *commit)
{
const char *filename;
int fd;
struct strbuf buf = STRBUF_INIT;

strbuf_addf(&buf, "%s\n", sha1_to_hex(commit->object.sha1));

fd = open(git_path("CHERRY_PICK_HEAD"), O_WRONLY | O_CREAT, 0666);
filename = git_path("CHERRY_PICK_HEAD");
fd = open(filename, O_WRONLY | O_CREAT, 0666);
if (fd < 0)
die_errno(_("Could not open '%s' for writing"),
git_path("CHERRY_PICK_HEAD"));
die_errno(_("Could not open '%s' for writing"), filename);
if (write_in_full(fd, buf.buf, buf.len) != buf.len || close(fd))
die_errno(_("Could not write to '%s'"), git_path("CHERRY_PICK_HEAD"));
die_errno(_("Could not write to '%s'"), filename);
strbuf_release(&buf);
}

Expand Down

0 comments on commit 418c9b1

Please sign in to comment.