git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 1/3] do not let git_path clobber errno when reporting errors

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Nov 16, 2011, 08:03 UTC
Message-ID
<20111116080336.GC13706@elie.hsd1.il.comcast.net>
In-Reply-To
<20111116075955.GB13706@elie.hsd1.il.comcast.net>
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>
---
 builtin/merge.c  |   49 +++++++++++++++++++++++++++++--------------------
 builtin/revert.c |    9 +++++----
 2 files changed, 34 insertions(+), 24 deletions(-)
diff --git a/builtin/merge.c b/builtin/merge.c
index dffd5ec1..2870a6af 100644
--- a/builtin/merge.c
+++ b/builtin/merge.c
@@ -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;
@@ -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");
@@ -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);
@@ -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];
@@ -1046,6 +1053,7 @@ 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;
@@ -1053,24 +1061,25 @@ static void write_merge_state(void)
 	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);
 }
 
diff --git a/builtin/revert.c b/builtin/revert.c
index 87df70ed..985f95b0 100644
--- a/builtin/revert.c
+++ b/builtin/revert.c
@@ -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);
 }
 
-- 
1.7.8.rc0
Previous: Jonathan NiederNext: Jonathan Nieder
Message 21 of 47 in “Sequencer: working around historical mistakes”
  1. 0/5 Sequencer: working around historical mistakesRamkumar Ramachandra, Nov 5, 2011
  2. 1/5 sequencer: factor code out of revert builtinRamkumar Ramachandra, Nov 5, 2011
  3. Jonathan NiederNov 6, 2011
  4. Ramkumar RamachandraNov 13, 2011
  5. Junio C HamanoNov 13, 2011
  6. Ramkumar RamachandraNov 15, 2011
  7. Miles BaderNov 15, 2011
  8. Jonathan NiederNov 15, 2011
  9. 2/5 sequencer: remove CHERRY_PICK_HEAD with sequencer stateRamkumar Ramachandra, Nov 5, 2011
  10. Jonathan NiederNov 6, 2011
  11. 3/5 sequencer: sequencer state is useless without todoRamkumar Ramachandra, Nov 5, 2011
  12. Jonathan NiederNov 6, 2011
  13. Ramkumar RamachandraNov 13, 2011
  14. Junio C HamanoNov 13, 2011
  15. Ramkumar RamachandraNov 15, 2011
  16. Jonathan NiederNov 15, 2011
  17. Junio C HamanoNov 15, 2011
  18. Ramkumar RamachandraNov 16, 2011
  19. Junio C HamanoNov 16, 2011
  20. 0/3 avoiding unintended consequences of git_path() usageJonathan Nieder, Nov 16, 2011
  21. 1/3 do not let git_path clobber errno when reporting errorsJonathan Nieder, Nov 16, 2011
  22. 2/3 Bigfile: dynamically allocate buffer for marks file nameJonathan Nieder, Nov 16, 2011
  23. 3/3 rename git_path() to git_path_unsafe()Jonathan Nieder, Nov 16, 2011
  24. Junio C HamanoNov 17, 2011
  25. Jonathan NiederNov 17, 2011
  26. Nguyen Thai Ngoc DuyNov 16, 2011
  27. Nguyen Thai Ngoc DuyNov 16, 2011
  28. Jonathan NiederNov 16, 2011
  29. Nguyen Thai Ngoc DuyNov 16, 2011
  30. Ramsay JonesNov 19, 2011
  31. introduce strbuf_addpath()Jonathan Nieder, Nov 16, 2011
  32. Nguyen Thai Ngoc DuyNov 18, 2011
  33. Junio C HamanoNov 16, 2011
  34. Ramkumar RamachandraNov 16, 2011
  35. Nguyen Thai Ngoc DuyNov 16, 2011
  36. Michael HaggertyNov 16, 2011
  37. Nguyen Thai Ngoc DuyNov 18, 2011
  38. 4/5 sequencer: handle single commit pick separatelyRamkumar Ramachandra, Nov 5, 2011
  39. Jonathan NiederNov 6, 2011
  40. 5/5 sequencer: revert d3f4628eRamkumar Ramachandra, Nov 5, 2011
  41. Jonathan NiederNov 6, 2011
  42. Junio C HamanoNov 6, 2011
  43. Ramkumar RamachandraNov 7, 2011
  44. Ramkumar RamachandraNov 12, 2011
  45. Jonathan NiederNov 12, 2011
  46. Jonathan NiederNov 5, 2011
  47. Ramkumar RamachandraNov 13, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.