git@vger.kernel.org list mirror (unofficial, one of many)
 help / color / mirror / code / Atom feed
* [PATCH] add strerror(errno) to die() calls where applicable
@ 2009-06-02 21:34 Thomas Rast
  2009-06-03  1:55 ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-02 21:34 UTC (permalink / raw)
  To: git; +Cc: Junio C Hamano

Lots of die() calls did not actually report the kind of error, which
can leave the user confused as to the real problem.  Add a
strerror(errno) where the die() is immediately preceded by a
system/library call that sets errno on failure, or by one of the
following that wrap such calls:

  odb_pack_keep
  read_ancestry
  read_in_full
  strbuf_read
  strbuf_read_file
  strbuf_readlink
  write_buffer
  write_in_full

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 abspath.c               |   17 +++++++++++------
 builtin-add.c           |    2 +-
 builtin-apply.c         |    8 ++++----
 builtin-archive.c       |    5 +++--
 builtin-blame.c         |   16 ++++++++++------
 builtin-clone.c         |   16 ++++++++++------
 builtin-commit.c        |   15 +++++++++------
 builtin-fast-export.c   |    5 +++--
 builtin-fmt-merge-msg.c |    2 +-
 builtin-fsck.c          |    7 ++++---
 builtin-init-db.c       |   27 +++++++++++++++++----------
 builtin-log.c           |    4 ++--
 builtin-mailsplit.c     |    7 ++++---
 builtin-merge.c         |   25 ++++++++++++++++---------
 builtin-rev-parse.c     |    3 ++-
 builtin-revert.c        |    2 +-
 builtin-stripspace.c    |    2 +-
 builtin-tag.c           |    3 ++-
 builtin-tar-tree.c      |    2 +-
 combine-diff.c          |    3 ++-
 diff.c                  |    6 +++---
 entry.c                 |    3 ++-
 fast-import.c           |    4 ++--
 hash-object.c           |    2 +-
 ll-merge.c              |    2 +-
 mktag.c                 |    2 +-
 read-cache.c            |    2 +-
 setup.c                 |   15 ++++++++++-----
 sha1_file.c             |    2 +-
 transport.c             |    6 ++++--
 unpack-file.c           |    2 +-
 31 files changed, 131 insertions(+), 86 deletions(-)

diff --git a/abspath.c b/abspath.c
index 649f34f..7fff78f 100644
--- a/abspath.c
+++ b/abspath.c
@@ -41,13 +41,16 @@ int is_directory(const char *path)
 
 		if (*buf) {
 			if (!*cwd && !getcwd(cwd, sizeof(cwd)))
-				die ("Could not get current working directory");
+				die ("Could not get current working directory: %s",
+				     strerror(errno));
 
 			if (chdir(buf))
-				die ("Could not switch to '%s'", buf);
+				die ("Could not switch to '%s': %s", buf,
+				     strerror(errno));
 		}
 		if (!getcwd(buf, PATH_MAX))
-			die ("Could not get current working directory");
+			die ("Could not get current working directory: %s",
+			     strerror(errno));
 
 		if (last_elem) {
 			int len = strlen(buf);
@@ -63,7 +66,8 @@ int is_directory(const char *path)
 		if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
 			len = readlink(buf, next_buf, PATH_MAX);
 			if (len < 0)
-				die ("Invalid symlink: %s", buf);
+				die ("Invalid symlink '%s': %s", buf,
+				     strerror(errno));
 			if (PATH_MAX <= len)
 				die("symbolic link too long: %s", buf);
 			next_buf[len] = '\0';
@@ -75,7 +79,7 @@ int is_directory(const char *path)
 	}
 
 	if (*cwd && chdir(cwd))
-		die ("Could not change back to '%s'", cwd);
+		die ("Could not change back to '%s': %s", cwd, strerror(errno));
 
 	return buf;
 }
@@ -109,7 +113,8 @@ int is_directory(const char *path)
 	} else {
 		const char *cwd = get_pwd_cwd();
 		if (!cwd)
-			die("Cannot determine the current working directory");
+			die("Cannot determine the current working directory",
+			    strerror(errno));
 		if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
 			die("Too long path: %.*s", 60, path);
 	}
diff --git a/builtin-add.c b/builtin-add.c
index c1b229a..88c6672 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -220,7 +220,7 @@ int edit_patch(int argc, const char **argv, const char *prefix)
 	launch_editor(file, NULL, NULL);
 
 	if (stat(file, &st))
-		die("Could not stat '%s'", file);
+		die("Could not stat '%s': %s", file, strerror(errno));
 	if (!st.st_size)
 		die("Empty patch. Aborted.");
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 94ba2bd..1ea5113 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned 
 	} else {
 		if (!cached) {
 			if (lstat(path, &st) < 0)
-				die("unable to stat newly created file %s",
-				    path);
+				die("unable to stat newly created file '%s': %s",
+				    path, strerror(errno));
 			fill_stat_cache_info(ce, &st);
 		}
 		if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 	strbuf_release(&nbuf);
 
 	if (close(fd) < 0)
-		die("closing file %s: %s", path, strerror(errno));
+		die("closing file '%s': %s", path, strerror(errno));
 	return 0;
 }
 
@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
 			++nr;
 		}
 	}
-	die("unable to write file %s mode %o", path, mode);
+	die("unable to write file '%s' mode %o: %s", path, mode, strerror(errno));
 }
 
 static void create_file(struct patch *patch)
diff --git a/builtin-archive.c b/builtin-archive.c
index 3c5a5a7..10877ef 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -13,10 +13,11 @@ static void create_output_file(const char *output_file)
 {
 	int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 	if (output_fd < 0)
-		die("could not create archive file: %s ", output_file);
+		die("could not create archive file '%s': %s", output_file,
+		    strerror(errno));
 	if (output_fd != 1) {
 		if (dup2(output_fd, 1) < 0)
-			die("could not redirect output");
+			die("could not redirect output: %s", strerror(errno));
 		else
 			close(output_fd);
 	}
diff --git a/builtin-blame.c b/builtin-blame.c
index 9dc3335..e5b465e 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -1998,23 +1998,27 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 
 		if (contents_from) {
 			if (stat(contents_from, &st) < 0)
-				die("Cannot stat %s", contents_from);
+				die("Cannot stat '%s': %s", contents_from,
+				    strerror(errno));
 			read_from = contents_from;
 		}
 		else {
 			if (lstat(path, &st) < 0)
-				die("Cannot lstat %s", path);
+				die("Cannot lstat '%s': %s", path,
+				    strerror(errno));
 			read_from = path;
 		}
 		mode = canon_mode(st.st_mode);
 		switch (st.st_mode & S_IFMT) {
 		case S_IFREG:
 			if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
-				die("cannot open or read %s", read_from);
+				die("cannot open or read '%s': %s", read_from,
+				    strerror(errno));
 			break;
 		case S_IFLNK:
 			if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
-				die("cannot readlink %s", read_from);
+				die("cannot readlink '%s': %s", read_from,
+				    strerror(errno));
 			break;
 		default:
 			die("unsupported file type %s", read_from);
@@ -2251,7 +2255,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 	argc = parse_options_end(&ctx);
 
 	if (revs_file && read_ancestry(revs_file))
-		die("reading graft file %s failed: %s",
+		die("reading graft file '%s' failed: %s",
 		    revs_file, strerror(errno));
 
 	if (cmd_is_annotate) {
@@ -2340,7 +2344,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 
 		setup_work_tree();
 		if (!has_string_in_work_tree(path))
-			die("cannot stat path %s: %s", path, strerror(errno));
+			die("cannot stat path '%s': %s", path, strerror(errno));
 	}
 
 	setup_revisions(argc, argv, &revs, NULL);
diff --git a/builtin-clone.c b/builtin-clone.c
index 5c46496..a175ed1 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -220,13 +220,15 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 
 	dir = opendir(src->buf);
 	if (!dir)
-		die("failed to open %s", src->buf);
+		die("failed to open '%s': %s", src->buf, strerror(errno));
 
 	if (mkdir(dest->buf, 0777)) {
 		if (errno != EEXIST)
-			die("failed to create directory %s", dest->buf);
+			die("failed to create directory '%s': %s", dest->buf,
+			    strerror(errno));
 		else if (stat(dest->buf, &buf))
-			die("failed to stat %s", dest->buf);
+			die("failed to stat '%s': %s", dest->buf,
+			    strerror(errno));
 		else if (!S_ISDIR(buf.st_mode))
 			die("%s exists and is not a directory", dest->buf);
 	}
@@ -252,17 +254,19 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 		}
 
 		if (unlink(dest->buf) && errno != ENOENT)
-			die("failed to unlink %s: %s",
+			die("failed to unlink '%s': %s",
 			    dest->buf, strerror(errno));
 		if (!option_no_hardlinks) {
 			if (!link(src->buf, dest->buf))
 				continue;
 			if (option_local)
-				die("failed to create link %s", dest->buf);
+				die("failed to create link '%s': %s", dest->buf,
+				    strerror(errno));
 			option_no_hardlinks = 1;
 		}
 		if (copy_file(dest->buf, src->buf, 0666))
-			die("failed to copy file to %s", dest->buf);
+			die("failed to copy file to '%s': %s", dest->buf,
+			    strerror(errno));
 	}
 	closedir(dir);
 }
diff --git a/builtin-commit.c b/builtin-commit.c
index 41e222d..c21c16b 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -434,7 +434,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		if (isatty(0))
 			fprintf(stderr, "(reading log message from standard input)\n");
 		if (strbuf_read(&sb, 0, 0) < 0)
-			die("could not read log from standard input");
+			die("could not read log from standard input: %s",
+			    strerror(errno));
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
@@ -458,7 +459,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg1 = "squash";
 	} else if (template_file && !stat(template_file, &statbuf)) {
 		if (strbuf_read_file(&sb, template_file, 0) < 0)
-			die("could not read %s: %s",
+			die("could not read '%s': %s",
 			    template_file, strerror(errno));
 		hook_arg1 = "template";
 	}
@@ -472,7 +473,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
 	fp = fopen(git_path(commit_editmsg), "w");
 	if (fp == NULL)
-		die("could not open %s: %s",
+		die("could not open '%s': %s",
 		    git_path(commit_editmsg), strerror(errno));
 
 	if (cleanup_mode != CLEANUP_NONE)
@@ -968,7 +969,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	strbuf_reset(&sb);
 	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
 		rollback_index_files();
-		die("could not read commit message");
+		die("could not read commit message: %s", strerror(errno));
 	}
 
 	/* Truncate the message just before the diff, if any. */
@@ -1021,8 +1022,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 	if (commit_index_files())
 		die ("Repository has been updated, but unable to write\n"
-		     "new_index file. Check that disk is not full or quota is\n"
-		     "not exceeded, and then \"git reset HEAD\" to recover.");
+		     "new_index file: %s.\n"
+		     "Check that disk is not full or quota is not exceeded,\n"
+		     "and then \"git reset HEAD\" to recover.",
+		     strerror(errno));
 
 	rerere();
 	run_hook(get_index_file(), "post-commit", NULL);
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 6cef810..45a3ec8 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -119,7 +119,8 @@ static void handle_object(const unsigned char *sha1)
 
 	printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
 	if (size && fwrite(buf, size, 1, stdout) != 1)
-		die ("Could not write blob %s", sha1_to_hex(sha1));
+		die ("Could not write blob '%s': %s", sha1_to_hex(sha1),
+		     strerror(errno));
 	printf("\n");
 
 	show_progress();
@@ -451,7 +452,7 @@ static void import_marks(char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die("cannot read '%s': %s", input_file, strerror(errno));
 
 	while (fgets(line, sizeof(line), f)) {
 		uint32_t mark;
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index fbf9582..051f4a4 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	if (inpath && strcmp(inpath, "-")) {
 		in = fopen(inpath, "r");
 		if (!in)
-			die("cannot open %s", inpath);
+			die("cannot open '%s': %s", inpath, strerror(errno));
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 7da706c..e22f1a4 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -217,7 +217,8 @@ static void check_unreachable_object(struct object *obj)
 				return;
 			}
 			if (!(f = fopen(filename, "w")))
-				die("Could not open %s", filename);
+				die("Could not open '%s': %s", filename,
+				    strerror(errno));
 			if (obj->type == OBJ_BLOB) {
 				enum object_type type;
 				unsigned long size;
@@ -225,14 +226,14 @@ static void check_unreachable_object(struct object *obj)
 						&type, &size);
 				if (buf) {
 					if (fwrite(buf, size, 1, f) != 1)
-						die("Could not write %s: %s",
+						die("Could not write '%s': %s",
 						    filename, strerror(errno));
 					free(buf);
 				}
 			} else
 				fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
 			if (fclose(f))
-				die("Could not finish %s: %s",
+				die("Could not finish '%s': %s",
 				    filename, strerror(errno));
 		}
 		return;
diff --git a/builtin-init-db.c b/builtin-init-db.c
index d1fa12a..4cdeb21 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -61,20 +61,23 @@ static void copy_templates_1(char *path, int baselen,
 		memcpy(template + template_baselen, de->d_name, namelen+1);
 		if (lstat(path, &st_git)) {
 			if (errno != ENOENT)
-				die("cannot stat %s", path);
+				die("cannot stat '%s': %s", path,
+				    strerror(errno));
 		}
 		else
 			exists = 1;
 
 		if (lstat(template, &st_template))
-			die("cannot stat template %s", template);
+			die("cannot stat template '%s': %s", template,
+			    strerror(errno));
 
 		if (S_ISDIR(st_template.st_mode)) {
 			DIR *subdir = opendir(template);
 			int baselen_sub = baselen + namelen;
 			int template_baselen_sub = template_baselen + namelen;
 			if (!subdir)
-				die("cannot opendir %s", template);
+				die("cannot opendir '%s': %s", template,
+				    strerror(errno));
 			path[baselen_sub++] =
 				template[template_baselen_sub++] = '/';
 			path[baselen_sub] =
@@ -91,16 +94,19 @@ static void copy_templates_1(char *path, int baselen,
 			int len;
 			len = readlink(template, lnk, sizeof(lnk));
 			if (len < 0)
-				die("cannot readlink %s", template);
+				die("cannot readlink '%s': %s", template,
+				    strerror(errno));
 			if (sizeof(lnk) <= len)
 				die("insanely long symlink %s", template);
 			lnk[len] = 0;
 			if (symlink(lnk, path))
-				die("cannot symlink %s %s", lnk, path);
+				die("cannot symlink '%s' '%s': %s", lnk, path,
+				    strerror(errno));
 		}
 		else if (S_ISREG(st_template.st_mode)) {
 			if (copy_file(path, template, st_template.st_mode))
-				die("cannot copy %s to %s", template, path);
+				die("cannot copy '%s' to '%s': %s", template,
+				    path, strerror(errno));
 		}
 		else
 			error("ignoring template %s", template);
@@ -350,7 +356,7 @@ static int guess_repository_type(const char *git_dir)
 	if (!strcmp(".", git_dir))
 		return 1;
 	if (!getcwd(cwd, sizeof(cwd)))
-		die("cannot tell cwd");
+		die("cannot tell cwd: %s", strerror(errno));
 	if (!strcmp(git_dir, cwd))
 		return 1;
 	/*
@@ -440,11 +446,12 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		if (!git_work_tree_cfg) {
 			git_work_tree_cfg = xcalloc(PATH_MAX, 1);
 			if (!getcwd(git_work_tree_cfg, PATH_MAX))
-				die ("Cannot access current working directory.");
+				die ("Cannot access current working directory: %s",
+				     strerror(errno));
 		}
 		if (access(get_git_work_tree(), X_OK))
-			die ("Cannot access work tree '%s'",
-			     get_git_work_tree());
+			die ("Cannot access work tree '%s': %s",
+			     get_git_work_tree(), strerror(errno));
 	}
 
 	set_git_dir(make_absolute_path(git_dir));
diff --git a/builtin-log.c b/builtin-log.c
index 0d34050..76cb3e2 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		if (use_stdout)
 			die("standard output, or directory, which one?");
 		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
-			die("Could not create directory %s",
-			    output_directory);
+			die("Could not create directory '%s': %s",
+			    output_directory, strerror(errno));
 	}
 
 	if (rev.pending.nr == 1) {
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c
index 71f3b3b..30c4e6f 100644
--- a/builtin-mailsplit.c
+++ b/builtin-mailsplit.c
@@ -81,7 +81,8 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 
 	fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
 	if (fd < 0)
-		die("cannot open output file %s", name);
+		die("cannot open output file '%s': %s", name,
+		    strerror(errno));
 	output = fdopen(fd, "w");
 
 	/* Copy it out, while searching for a line that begins with
@@ -91,7 +92,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 		int is_partial = len && buf[len-1] != '\n';
 
 		if (fwrite(buf, 1, len, output) != len)
-			die("cannot write output");
+			die("cannot write output: %s", strerror(errno));
 
 		len = read_line_with_nul(buf, sizeof(buf), mbox);
 		if (len == 0) {
@@ -99,7 +100,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 				status = 1;
 				break;
 			}
-			die("cannot read mbox");
+			die("cannot read mbox: %s", strerror(errno));
 		}
 		if (!is_partial && !is_bare && is_from_line(buf, len))
 			break; /* done with one message */
diff --git a/builtin-merge.c b/builtin-merge.c
index 8d101ef..4bac88e 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -268,7 +268,8 @@ static void squash_message(void)
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
 	if (fd < 0)
-		die("Could not write to %s", git_path("SQUASH_MSG"));
+		die("Could not write to '%s': %s", git_path("SQUASH_MSG"),
+		    strerror(errno));
 
 	init_revisions(&rev, NULL);
 	rev.ignore_merges = 1;
@@ -764,7 +765,8 @@ static int suggest_conflicts(void)
 
 	fp = fopen(git_path("MERGE_MSG"), "a");
 	if (!fp)
-		die("Could not open %s for writing", git_path("MERGE_MSG"));
+		die("Could not open '%s' for writing: %s", git_path("MERGE_MSG"),
+		    strerror(errno));
 	fprintf(fp, "\nConflicts:\n");
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
@@ -1186,27 +1188,32 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 				sha1_to_hex(j->item->object.sha1));
 		fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing",
-				git_path("MERGE_HEAD"));
+			die("Could not open '%s' for writing: %s",
+			    git_path("MERGE_HEAD"), strerror(errno));
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_HEAD"));
+			die("Could not write to '%s': %s",
+			    git_path("MERGE_HEAD"), strerror(errno));
 		close(fd);
 		strbuf_addch(&merge_msg, '\n');
 		fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MSG"));
+			die("Could not open '%s' for writing: %s",
+			    git_path("MERGE_MSG"), strerror(errno));
 		if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
 			merge_msg.len)
-			die("Could not write to %s", git_path("MERGE_MSG"));
+			die("Could not write to '%s': %s",
+			    git_path("MERGE_MSG"), strerror(errno));
 		close(fd);
 		fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MODE"));
+			die("Could not open '%s' for writing",
+			    git_path("MERGE_MODE"), strerror(errno));
 		strbuf_reset(&buf);
 		if (!allow_fast_forward)
 			strbuf_addf(&buf, "no-ff");
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_MODE"));
+			die("Could not write to '%s': %s",
+			    git_path("MERGE_MODE"), strerror(errno));
 		close(fd);
 	}
 
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 112d622..bbc21f8 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -592,7 +592,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 					continue;
 				}
 				if (!getcwd(cwd, PATH_MAX))
-					die("unable to get current working directory");
+					die("unable to get current working directory: %s",
+					    strerror(errno));
 				printf("%s/.git\n", cwd);
 				continue;
 			}
diff --git a/builtin-revert.c b/builtin-revert.c
index c87115a..a82c4b8 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)
 {
 	int len = strlen(string);
 	if (write_in_full(msg_fd, string, len) < 0)
-		die ("Could not write to MERGE_MSG");
+		die ("Could not write to MERGE_MSG: %s", strerror(errno));
 }
 
 static void add_message_to_msg(const char *message)
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index d6e3896..7444f3f 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
 		strip_comments = 1;
 
 	if (strbuf_read(&buf, 0, 1024) < 0)
-		die("could not read the input");
+		die("could not read the input: %s", strerror(errno));
 
 	stripspace(&buf, strip_comments);
 
diff --git a/builtin-tag.c b/builtin-tag.c
index dc3db62..e509888 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -443,7 +443,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		else {
 			if (!strcmp(msgfile, "-")) {
 				if (strbuf_read(&buf, 0, 1024) < 0)
-					die("cannot read %s", msgfile);
+					die("cannot read '%s': %s", msgfile,
+					    strerror(errno));
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
 					die("could not open or read '%s': %s",
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index f88e721..066887f 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
 
 	n = write_in_full(1, content + 11, 41);
 	if (n < 41)
-		die("git get-tar-commit-id: write error");
+		die("git get-tar-commit-id: write error: %s", strerror(errno));
 
 	return 0;
 }
diff --git a/combine-diff.c b/combine-diff.c
index 60d0367..540e877 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -746,7 +746,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 
 			done = read_in_full(fd, result, len);
 			if (done < 0)
-				die("read error '%s'", elem->path);
+				die("read error '%s': %s", elem->path,
+				    strerror(errno));
 			else if (done < len)
 				die("early EOF '%s'", elem->path);
 
diff --git a/diff.c b/diff.c
index dcfbcb0..6c0ba41 100644
--- a/diff.c
+++ b/diff.c
@@ -1974,7 +1974,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		size = buf.len;
 	}
 	if (write_in_full(fd, blob, size) != size)
-		die("unable to write temp-file");
+		die("unable to write temp-file: %s", strerror(errno));
 	close(fd);
 	temp->name = temp->tmp_path;
 	strcpy(temp->hex, sha1_to_hex(sha1));
@@ -2016,7 +2016,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
 			if (strbuf_readlink(&sb, name, st.st_size) < 0)
-				die("readlink(%s)", name);
+				die("readlink(%s): %s", name, strerror(errno));
 			prep_temp_blob(name, temp, sb.buf, sb.len,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
@@ -2209,7 +2209,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
 				return;
 			}
 			if (lstat(one->path, &st) < 0)
-				die("stat %s", one->path);
+				die("stat '%s': %s", one->path, strerror(errno));
 			if (index_path(one->sha1, one->path, &st, 0))
 				die("cannot hash %s", one->path);
 		}
diff --git a/entry.c b/entry.c
index cc841ed..0dde848 100644
--- a/entry.c
+++ b/entry.c
@@ -37,7 +37,8 @@ static void create_directories(const char *path, int path_len,
 			if (errno == EEXIST && state->force &&
 			    !unlink_or_warn(buf) && !mkdir(buf, 0777))
 				continue;
-			die("cannot create directory at %s", buf);
+			die("cannot create directory at '%s': %s", buf,
+			    strerror(errno));
 		}
 	}
 	free(buf);
diff --git a/fast-import.c b/fast-import.c
index a2a2458..686cafc 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)
 
 	keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
 	if (keep_fd < 0)
-		die("cannot create keep file");
+		die("cannot create keep file: %s", strerror(errno));
 	write_or_die(keep_fd, keep_msg, strlen(keep_msg));
 	if (close(keep_fd))
-		die("failed to write keep file");
+		die("failed to write keep file: %s", strerror(errno));
 
 	snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
 		 get_object_directory(), sha1_to_hex(pack_data->sha1));
diff --git a/hash-object.c b/hash-object.c
index 47cf43c..778dabe 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,
 	int fd;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Cannot open %s", path);
+		die("Cannot open '%s': %s", path, strerror(errno));
 	hash_fd(fd, type, write_object, vpath);
 }
 
diff --git a/ll-merge.c b/ll-merge.c
index 81c02ad..681f3a0 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, src->ptr, src->size) != src->size)
-		die("unable to write temp-file");
+		die("unable to write temp-file: %s", strerror(errno));
 	close(fd);
 }
 
diff --git a/mktag.c b/mktag.c
index 99a356e..238269a 100644
--- a/mktag.c
+++ b/mktag.c
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
 	setup_git_directory();
 
 	if (strbuf_read(&buf, 0, 4096) < 0) {
-		die("could not read from stdin");
+		die("could not read from stdin: %s", strerror(errno));
 	}
 
 	/* Verify it for some basic sanity: it needs to start with
diff --git a/read-cache.c b/read-cache.c
index 3f58711..2bb142c 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)
 	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	close(fd);
 	if (mmap == MAP_FAILED)
-		die("unable to map index file");
+		die("unable to map index file: %s", strerror(errno));
 
 	hdr = mmap;
 	if (verify_hdr(hdr, mmap_size) < 0)
diff --git a/setup.c b/setup.c
index ebd60de..8548801 100644
--- a/setup.c
+++ b/setup.c
@@ -327,7 +327,8 @@ static int check_repository_format_gently(int *nongit_ok)
 				return NULL;
 			set_git_dir(make_absolute_path(gitdirenv));
 			if (chdir(work_tree_env) < 0)
-				die ("Could not chdir to %s", work_tree_env);
+				die ("Could not chdir to %s: %s", work_tree_env,
+				     strerror(errno));
 			strcat(buffer, "/");
 			return retval;
 		}
@@ -339,7 +340,8 @@ static int check_repository_format_gently(int *nongit_ok)
 	}
 
 	if (!getcwd(cwd, sizeof(cwd)-1))
-		die("Unable to read current working directory");
+		die("Unable to read current working directory: %s",
+		    strerror(errno));
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -382,7 +384,8 @@ static int check_repository_format_gently(int *nongit_ok)
 		if (offset <= ceil_offset) {
 			if (nongit_ok) {
 				if (chdir(cwd))
-					die("Cannot come back to cwd");
+					die("Cannot come back to cwd: %s",
+					    strerror(errno));
 				*nongit_ok = 1;
 				return NULL;
 			}
@@ -493,10 +496,12 @@ int check_repository_format(void)
 		static char buffer[PATH_MAX + 1];
 		char *rel;
 		if (retval && chdir(retval))
-			die ("Could not jump back into original cwd");
+			die ("Could not jump back into original cwd: %s",
+			     strerror(errno));
 		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
 		if (rel && *rel && chdir(get_git_work_tree()))
-			die ("Could not jump to working directory");
+			die ("Could not jump to working directory: %s",
+			     strerror(errno));
 		return rel && *rel ? strcat(rel, "/") : NULL;
 	}
 
diff --git a/sha1_file.c b/sha1_file.c
index e73cd4f..f6fc256 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2382,7 +2382,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,
 	size = stream.total_out;
 
 	if (write_buffer(fd, compressed, size) < 0)
-		die("unable to write sha1 file");
+		die("unable to write sha1 file: %s", strerror(errno));
 	close_sha1_file(fd);
 	free(compressed);
 
diff --git a/transport.c b/transport.c
index 17891d5..93cc9a6 100644
--- a/transport.c
+++ b/transport.c
@@ -158,7 +158,8 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die ("Could not make temporary directory: %s",
+		     strerror(errno));
 	temp_dir_len = temp_dir.len;
 
 	strbuf_addstr(&buf, rsync_url(transport->url));
@@ -321,7 +322,8 @@ static int rsync_transport_push(struct transport *transport,
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die ("Could not make temporary directory: %s",
+		     strerror(errno));
 	strbuf_addch(&temp_dir, '/');
 
 	if (flags & TRANSPORT_PUSH_ALL) {
diff --git a/unpack-file.c b/unpack-file.c
index 75cd2f1..af9afc8 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -17,7 +17,7 @@
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, buf, size) != size)
-		die("unable to write temp-file");
+		die("unable to write temp-file: %s", strerror(errno));
 	close(fd);
 	return path;
 }
-- 
1.6.3.1.325.g02d91

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] add strerror(errno) to die() calls where applicable
  2009-06-02 21:34 [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
@ 2009-06-03  1:55 ` Jeff King
       [not found]   ` <2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com>
                     ` (2 more replies)
  0 siblings, 3 replies; 42+ messages in thread
From: Jeff King @ 2009-06-03  1:55 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git, Junio C Hamano

On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:

> Lots of die() calls did not actually report the kind of error, which
> can leave the user confused as to the real problem.  Add a
> strerror(errno) where the die() is immediately preceded by a
> system/library call that sets errno on failure, or by one of the
> following that wrap such calls:

I like this, as I remember being frustrated in the past by "cannot $foo"
messages with no indication of the cause of the error. My only questions
or concerns with such a patch would be:

  1. How did you determine the set of callsites? Did you check that each
     non-syscall function always sets errno? Are there are functions
     which are setting errno which could also be included?

  2. Extra error conditions may leak information about the filesystem to
     people feeding bogus paths to upload-pack. I didn't see anything
     obvious in your patch that would cause this, but it is something to
     consider.

  3. This is such a common thing to do, I wonder if we would be better
     off adding a "diesys" function that appends ": strerror(errno)"
     to the emitted error. Something like the (totally untested) patch
     below.

And a few comments on the patch itself:

> @@ -109,7 +113,8 @@ int is_directory(const char *path)
>  	} else {
>  		const char *cwd = get_pwd_cwd();
>  		if (!cwd)
> -			die("Cannot determine the current working directory");
> +			die("Cannot determine the current working directory",
> +			    strerror(errno));

Missing ": %s" here?

> -		die("closing file %s: %s", path, strerror(errno));
> +		die("closing file '%s': %s", path, strerror(errno));

This one is actually just a style change, though I think it is
worthwhile (and there are a few others like it).


The diesys patch is below.

---
diff --git a/git-compat-util.h b/git-compat-util.h
index 4236647..410ac87 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -155,6 +155,7 @@
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
diff --git a/usage.c b/usage.c
index 820d09f..da5e58e 100644
--- a/usage.c
+++ b/usage.c
@@ -12,6 +12,14 @@ static void report(const char *prefix, const char *err, va_list params)
 	fprintf(stderr, "%s%s\n", prefix, msg);
 }
 
+static void report_sys(int err, const char *prefix, const char *fmt, va_list
+		params)
+{
+	char msg[1024];
+	vsnprintf(msg, sizeof(msg), fmt, params);
+	fprintf(stderr, "%s%s: %s\n", prefix, msg, hstrerror(err));
+}
+
 static NORETURN void usage_builtin(const char *err)
 {
 	fprintf(stderr, "usage: %s\n", err);
@@ -24,6 +32,12 @@ static NORETURN void die_builtin(const char *err, va_list params)
 	exit(128);
 }
 
+static NORETURN void diesys_builtin(int err, const char *fmt, va_list params)
+{
+	report_sys(err, "fatal: ", fmt, params);
+	exit(128);
+}
+
 static void error_builtin(const char *err, va_list params)
 {
 	report("error: ", err, params);
@@ -38,6 +52,7 @@ static void warn_builtin(const char *warn, va_list params)
  * (ugh), so keep things static. */
 static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
 static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
+static void (*diesys_routine)(int err, const char *fmt, va_list params) NORETURN = diesys_builtin;
 static void (*error_routine)(const char *err, va_list params) = error_builtin;
 static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
 
@@ -60,6 +75,16 @@ void die(const char *err, ...)
 	va_end(params);
 }
 
+void diesys(const char *fmt, ...)
+{
+	va_list params;
+	int err = errno;
+
+	va_start(params, fmt);
+	diesys_routine(err, fmt, params);
+	va_end(params);
+}
+
 int error(const char *err, ...)
 {
 	va_list params;

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] add strerror(errno) to die() calls where applicable
       [not found]   ` <2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com>
@ 2009-06-04  1:58     ` Alexander Potashev
  2009-06-04 20:32       ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Alexander Potashev @ 2009-06-04  1:58 UTC (permalink / raw)
  To: Thomas Rast; +Cc: git, Junio C Hamano

Hi Jeff,
I was also thinking (about 1 month ago) about a helper function
similar to your 'diesys', but I never thought that adding yet another
"backend" function (diesys_routine) is reasonable.

Following your approach, you will need to add 'set_diesys_routine' and
call it along with 'set_die_routine' (however, if you want to use
'diesys', but there are several places in 'daemon.c' and
'fast-import.c' where 'die' is being used to write 'strerror(errno)').

I think, we should just keep the backend interface as is and implement
'diesys' through 'die_routine'.


Alexander


2009/6/3 Jeff King <peff@peff.net>:
> On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:
>
>> Lots of die() calls did not actually report the kind of error, which
>> can leave the user confused as to the real problem.  Add a
>> strerror(errno) where the die() is immediately preceded by a
>> system/library call that sets errno on failure, or by one of the
>> following that wrap such calls:
>
> I like this, as I remember being frustrated in the past by "cannot $foo"
> messages with no indication of the cause of the error. My only questions
> or concerns with such a patch would be:
>
>  1. How did you determine the set of callsites? Did you check that each
>     non-syscall function always sets errno? Are there are functions
>     which are setting errno which could also be included?
>
>  2. Extra error conditions may leak information about the filesystem to
>     people feeding bogus paths to upload-pack. I didn't see anything
>     obvious in your patch that would cause this, but it is something to
>     consider.
>
>  3. This is such a common thing to do, I wonder if we would be better
>     off adding a "diesys" function that appends ": strerror(errno)"
>     to the emitted error. Something like the (totally untested) patch
>     below.
>
> And a few comments on the patch itself:
>
>> @@ -109,7 +113,8 @@ int is_directory(const char *path)
>>       } else {
>>               const char *cwd = get_pwd_cwd();
>>               if (!cwd)
>> -                     die("Cannot determine the current working directory");
>> +                     die("Cannot determine the current working directory",
>> +                         strerror(errno));
>
> Missing ": %s" here?
>
>> -             die("closing file %s: %s", path, strerror(errno));
>> +             die("closing file '%s': %s", path, strerror(errno));
>
> This one is actually just a style change, though I think it is
> worthwhile (and there are a few others like it).
>
>
> The diesys patch is below.
>
> ---
> diff --git a/git-compat-util.h b/git-compat-util.h
> index 4236647..410ac87 100644
> --- a/git-compat-util.h
> +++ b/git-compat-util.h
> @@ -155,6 +155,7 @@
>  /* General helper functions */
>  extern void usage(const char *err) NORETURN;
>  extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
> +extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
>  extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
>  extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
>
> diff --git a/usage.c b/usage.c
> index 820d09f..da5e58e 100644
> --- a/usage.c
> +++ b/usage.c
> @@ -12,6 +12,14 @@ static void report(const char *prefix, const char *err, va_list params)
>        fprintf(stderr, "%s%s\n", prefix, msg);
>  }
>
> +static void report_sys(int err, const char *prefix, const char *fmt, va_list
> +               params)
> +{
> +       char msg[1024];
> +       vsnprintf(msg, sizeof(msg), fmt, params);
> +       fprintf(stderr, "%s%s: %s\n", prefix, msg, hstrerror(err));
> +}
> +
>  static NORETURN void usage_builtin(const char *err)
>  {
>        fprintf(stderr, "usage: %s\n", err);
> @@ -24,6 +32,12 @@ static NORETURN void die_builtin(const char *err, va_list params)
>        exit(128);
>  }
>
> +static NORETURN void diesys_builtin(int err, const char *fmt, va_list params)
> +{
> +       report_sys(err, "fatal: ", fmt, params);
> +       exit(128);
> +}
> +
>  static void error_builtin(const char *err, va_list params)
>  {
>        report("error: ", err, params);
> @@ -38,6 +52,7 @@ static void warn_builtin(const char *warn, va_list params)
>  * (ugh), so keep things static. */
>  static void (*usage_routine)(const char *err) NORETURN = usage_builtin;
>  static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;
> +static void (*diesys_routine)(int err, const char *fmt, va_list params) NORETURN = diesys_builtin;
>  static void (*error_routine)(const char *err, va_list params) = error_builtin;
>  static void (*warn_routine)(const char *err, va_list params) = warn_builtin;
>
> @@ -60,6 +75,16 @@ void die(const char *err, ...)
>        va_end(params);
>  }
>
> +void diesys(const char *fmt, ...)
> +{
> +       va_list params;
> +       int err = errno;
> +
> +       va_start(params, fmt);
> +       diesys_routine(err, fmt, params);
> +       va_end(params);
> +}
> +
>  int error(const char *err, ...)
>  {
>        va_list params;
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-03  1:55 ` Jeff King
       [not found]   ` <2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com>
@ 2009-06-04  2:05   ` Alexander Potashev
  2009-06-04 20:50     ` Jeff King
  2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
  2 siblings, 1 reply; 42+ messages in thread
From: Alexander Potashev @ 2009-06-04  2:05 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Git Mailing List, Jeff King, Thomas Rast, Alexander Potashev

Signed-off-by: Alexander Potashev <aspotashev@gmail.com>
---
Firstly I was going to write a 'adapt_to_fmt' function which would
double all inclusions of '%', and then use it for strerror(err) and
make printf-like functions happy (actually 'die_routine').

BUT, Have you ever seen an error description containing '%'? I haven't.
So, handling the case of '%'s is not worth injecting several dump lines
into the sources of the Beatiful Content Tracker.



 git-compat-util.h |    1 +
 usage.c           |   18 ++++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index f25f7f1..cbfee60 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -162,6 +162,7 @@ extern char *gitbasename(char *);
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
diff --git a/usage.c b/usage.c
index 820d09f..e20f696 100644
--- a/usage.c
+++ b/usage.c
@@ -60,6 +60,24 @@ void die(const char *err, ...)
 	va_end(params);
 }
 
+void diesys(const char *err, ...)
+{
+	va_list params;
+	char *fullfmt;
+	const char *strerr;
+
+	va_start(params, err);
+
+	strerr = strerror(errno);
+	if (strchr(strerr, '%'))
+		strerr = "<error description contains '%%'>";
+	fullfmt = xmalloc(strlen(err) + strlen(strerr) + 3);
+	sprintf(fullfmt, "%s: %s", err, strerr);
+	die_routine(fullfmt, params);
+
+	va_end(params);
+}
+
 int error(const char *err, ...)
 {
 	va_list params;
-- 
1.6.2.3

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] add strerror(errno) to die() calls where applicable
  2009-06-04  1:58     ` Alexander Potashev
@ 2009-06-04 20:32       ` Jeff King
  0 siblings, 0 replies; 42+ messages in thread
From: Jeff King @ 2009-06-04 20:32 UTC (permalink / raw)
  To: Alexander Potashev; +Cc: Thomas Rast, git, Junio C Hamano

On Thu, Jun 04, 2009 at 05:58:14AM +0400, Alexander Potashev wrote:

> I was also thinking (about 1 month ago) about a helper function
> similar to your 'diesys', but I never thought that adding yet another
> "backend" function (diesys_routine) is reasonable.
> 
> Following your approach, you will need to add 'set_diesys_routine' and
> call it along with 'set_die_routine' (however, if you want to use
> 'diesys', but there are several places in 'daemon.c' and
> 'fast-import.c' where 'die' is being used to write 'strerror(errno)').

Yeah, I didn't look into who is actually using set_die_routine, but
adding another routine like this makes it a lot more annoying for
git-daemon to use it. So I think your approach is probably better,
though I have a few comments on the patch itself (which I'll put in the
next mail).

-Peff

PS Actually, the nicest interface IMHO would be a variadic macro
like:

  #define diesys(fmt, ...) die(fmt ": %s", __VA_ARGS__, strerror(errno))

but that requires a c99 compiler, which we otherwise do not need.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-04  2:05   ` [PATCH] diesys calls die and also reports strerror(errno) Alexander Potashev
@ 2009-06-04 20:50     ` Jeff King
  2009-06-04 21:13       ` Junio C Hamano
  2009-06-05  6:25       ` Johannes Sixt
  0 siblings, 2 replies; 42+ messages in thread
From: Jeff King @ 2009-06-04 20:50 UTC (permalink / raw)
  To: Alexander Potashev; +Cc: Junio C Hamano, Git Mailing List, Thomas Rast

On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:

> Firstly I was going to write a 'adapt_to_fmt' function which would
> double all inclusions of '%', and then use it for strerror(err) and
> make printf-like functions happy (actually 'die_routine').
> 
> BUT, Have you ever seen an error description containing '%'? I haven't.
> So, handling the case of '%'s is not worth injecting several dump lines
> into the sources of the Beatiful Content Tracker.

That makes me a little nervous. No, I don't think there are any '%'
signs in standard 'C' locale messages (at least not in GNU libc). But
what about other locales, especially ones which use a multi-byte
encoding?

Though your code does at least recognize the situation and does
something sane instead of feeding bogus parameters to fprintf.

> +void diesys(const char *err, ...)
> +{
> +	va_list params;
> +	char *fullfmt;
> +	const char *strerr;
> +
> +	va_start(params, err);
> +
> +	strerr = strerror(errno);
> +	if (strchr(strerr, '%'))
> +		strerr = "<error description contains '%%'>";
> +	fullfmt = xmalloc(strlen(err) + strlen(strerr) + 3);
> +	sprintf(fullfmt, "%s: %s", err, strerr);
> +	die_routine(fullfmt, params);
> +
> +	va_end(params);
> +}

Should we be calling malloc here? One of the possible error conditions
is that we're out of memory (though xmalloc itself just uses "die"). I
don't think there is a good reason not to use a reasonably-sized static
buffer, which should increase robustness (report() is already using a
1024-character buffer, so any message would be truncated there anyway).

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-04 20:50     ` Jeff King
@ 2009-06-04 21:13       ` Junio C Hamano
  2009-06-05  6:25       ` Johannes Sixt
  1 sibling, 0 replies; 42+ messages in thread
From: Junio C Hamano @ 2009-06-04 21:13 UTC (permalink / raw)
  To: Jeff King
  Cc: Alexander Potashev, Junio C Hamano, Git Mailing List, Thomas Rast

Jeff King <peff@peff.net> writes:

> Should we be calling malloc here? One of the possible error conditions
> is that we're out of memory (though xmalloc itself just uses "die"). I
> don't think there is a good reason not to use a reasonably-sized static
> buffer, which should increase robustness (report() is already using a
> 1024-character buffer, so any message would be truncated there anyway).

Yup, and at that point, tacking strerror value while expanding possible %
becomes even easier.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-04 20:50     ` Jeff King
  2009-06-04 21:13       ` Junio C Hamano
@ 2009-06-05  6:25       ` Johannes Sixt
  2009-06-05  7:12         ` Junio C Hamano
  1 sibling, 1 reply; 42+ messages in thread
From: Johannes Sixt @ 2009-06-05  6:25 UTC (permalink / raw)
  To: Jeff King
  Cc: Alexander Potashev, Junio C Hamano, Git Mailing List, Thomas Rast

Jeff King schrieb:
> On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:
>> +void diesys(const char *err, ...)

Am I the only one who thinks that 'die_errno' would be a better name for
this function?

-- Hannes

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-05  6:25       ` Johannes Sixt
@ 2009-06-05  7:12         ` Junio C Hamano
  2009-06-06 22:09           ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2009-06-05  7:12 UTC (permalink / raw)
  To: Johannes Sixt
  Cc: Jeff King, Alexander Potashev, Git Mailing List, Thomas Rast

Johannes Sixt <j.sixt@viscovery.net> writes:

> Jeff King schrieb:
>> On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:
>>> +void diesys(const char *err, ...)
>
> Am I the only one who thinks that 'die_errno' would be a better name for
> this function?

You are not alone.  I did find diesys() unreadable, but simply did not
think of an obviously better alternative like you did.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] add strerror(errno) to die() calls where applicable
  2009-06-03  1:55 ` Jeff King
       [not found]   ` <2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com>
  2009-06-04  2:05   ` [PATCH] diesys calls die and also reports strerror(errno) Alexander Potashev
@ 2009-06-06 13:09   ` Thomas Rast
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
                       ` (3 more replies)
  2 siblings, 4 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 13:09 UTC (permalink / raw)
  To: Jeff King; +Cc: git, Junio C Hamano

[-- Attachment #1: Type: text/plain, Size: 2854 bytes --]

Sorry for not getting around to this again all week.  I'll try to
reroll later today...

Jeff King wrote:
>   1. How did you determine the set of callsites? Did you check that each
>      non-syscall function always sets errno? Are there are functions
>      which are setting errno which could also be included?

Basically by 'git grep die | grep -v errno' and then looking at the
code immediately before the die().  Rather tedious, but I couldn't see
an obvious way to automate the task.

As for the non-syscall functions, at first I had a longer list but I
eventually settled with the ones mentioned, but I decided it was too
risky and just stuck with those that are very clear:

> On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:
> >   odb_pack_keep

Tries open() in two ways, but can only return <0 by passing the return
value of the second.

> >   read_ancestry

Only returns -1 if fopen() returned NULL.

> >   read_in_full

Only returns <=0 if xread() returned <=0, which in turn only happens
if read() returned <0.

> >   strbuf_read

Returns -1 if xread() did so.

> >   strbuf_read_file

Returns -1 if open() or strbuf_read() failed.

> >   strbuf_readlink

Returns -1 if readlink() failed.  (The other option, that the buffer
was still too small at STRBUF_MAXLINK, would imply that readlink()
wanted to return more than PATH_MAX chars.)

> >   write_buffer

I'll drop this one, I missed that it actually does its own errno
reporting already.  (Other than that it's just a thin wrapper around
write_in_full.)

> >   write_in_full

Symmetric to read_in_full: only returns <=0 if xwrite() did, which in
turn only happens if write() returned <0.


There were lots of cases that aren't quite as clear-cut.  For example,
there are many call sites where the index is written out that look
like

	if (write_cache(fd, active_cache, active_nr) ||
	    close_lock_file(&index_lock))
		die("unable to write new_index file");

Dealing with those will be somewhat more complicated, as the error
case is not all that clearly defined.  But at least at a quick glance,
write_cache does not even indicate what file it failed to write.

>   2. Extra error conditions may leak information about the filesystem to
>      people feeding bogus paths to upload-pack. I didn't see anything
>      obvious in your patch that would cause this, but it is something to
>      consider.

Good point.

> > -		die("closing file %s: %s", path, strerror(errno));
> > +		die("closing file '%s': %s", path, strerror(errno));
> 
> This one is actually just a style change, though I think it is
> worthwhile (and there are a few others like it).

Yes, as I was already going through the calls I thought some
consistency would be nice.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch>
  2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
@ 2009-06-06 14:44     ` Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 0/3] die_errno() Thomas Rast
                         ` (3 more replies)
  2009-06-06 14:44     ` [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
                       ` (2 subsequent siblings)
  3 siblings, 4 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 14:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

So here's the reroll.

Changes since v1:

- add die_errno() [1/3] and use it [2/3]

- [3/3] dropped errno reporting after write_buffer, as it already does
  error(..., strerror(errno))

- [3/3] save errno around rollback_locks in builtin-commit.c:965



Thomas Rast (3):
  Introduce die_errno() that appends strerror(errno) to die()
  Convert existing die(..., strerror(errno)) to die_errno()
  Use die_errno() instead of die() when checking syscalls

 abspath.c                |   12 ++++++------
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-add.c            |    2 +-
 builtin-apply.c          |   12 ++++++------
 builtin-archive.c        |    4 ++--
 builtin-blame.c          |   16 +++++++---------
 builtin-clone.c          |   22 ++++++++++------------
 builtin-commit-tree.c    |    3 +--
 builtin-commit.c         |   36 +++++++++++++++++-------------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    5 ++---
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    5 ++---
 builtin-fsck.c           |   10 +++++-----
 builtin-grep.c           |    2 +-
 builtin-init-db.c        |   22 +++++++++++-----------
 builtin-log.c            |    4 ++--
 builtin-mailsplit.c      |    7 +++----
 builtin-merge.c          |   33 +++++++++++++++++++--------------
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rev-parse.c      |    2 +-
 builtin-revert.c         |    2 +-
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-stripspace.c     |    2 +-
 builtin-tag.c            |    9 ++++-----
 builtin-tar-tree.c       |    2 +-
 builtin-unpack-objects.c |    2 +-
 combine-diff.c           |    2 +-
 connect.c                |    4 ++--
 csum-file.c              |    5 ++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |   10 +++++-----
 dir.c                    |    2 +-
 entry.c                  |   10 +++++-----
 fast-import.c            |    8 ++++----
 git-compat-util.h        |    1 +
 git.c                    |    6 +++---
 hash-object.c            |    2 +-
 index-pack.c             |   21 ++++++++++-----------
 ll-merge.c               |    2 +-
 merge-recursive.c        |    6 +++---
 mktag.c                  |    2 +-
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    8 ++++----
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |   18 +++++++++---------
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 transport.c              |    4 ++--
 unpack-file.c            |    2 +-
 usage.c                  |   13 +++++++++++++
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 61 files changed, 219 insertions(+), 220 deletions(-)

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
@ 2009-06-06 14:44     ` Thomas Rast
  2009-06-06 20:36       ` Johannes Sixt
  2009-06-06 22:13       ` Jeff King
  2009-06-06 14:44     ` [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
  2009-06-06 14:44     ` [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
  3 siblings, 2 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 14:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

There are many calls to die() that do, or should, report
strerror(errno) to indicate how the syscall they guard failed.
Introduce a small helper function for this case.

Code by Jeff King and Alexander Potashev, name by Johannes Sixt.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-compat-util.h |    1 +
 usage.c           |   13 +++++++++++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index f25f7f1..0366cde 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -162,6 +162,7 @@
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
diff --git a/usage.c b/usage.c
index 820d09f..1819e0a 100644
--- a/usage.c
+++ b/usage.c
@@ -60,6 +60,19 @@ void die(const char *err, ...)
 	va_end(params);
 }
 
+void die_errno(const char *err, ...)
+{
+	va_list params;
+	char msg[1024];
+
+	va_start(params, err);
+
+	vsnprintf(msg, sizeof(msg), err, params);
+	die("%s: %s", msg, strerror(errno));
+
+	va_end(params);
+}
+
 int error(const char *err, ...)
 {
 	va_list params;
-- 
1.6.3.2.288.g40844

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno()
  2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
  2009-06-06 14:44     ` [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
@ 2009-06-06 14:44     ` Thomas Rast
  2009-06-06 20:31       ` Johannes Sixt
  2009-06-06 14:44     ` [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
  3 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 14:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

Change calls to die(..., strerror(errno)) to use the new die_errno().

In the process, also make slight style adjustments: at least state
_something_ about the function that failed (instead of just printing
the pathname), and put paths in single quotes.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-apply.c          |    6 +++---
 builtin-blame.c          |    7 +++----
 builtin-clone.c          |   11 +++++------
 builtin-commit-tree.c    |    2 +-
 builtin-commit.c         |   23 ++++++++++-------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    2 +-
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    3 +--
 builtin-fsck.c           |    8 ++++----
 builtin-grep.c           |    2 +-
 builtin-merge.c          |    8 ++++----
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-tag.c            |    7 +++----
 builtin-unpack-objects.c |    2 +-
 connect.c                |    4 ++--
 csum-file.c              |    6 +++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |    4 ++--
 dir.c                    |    2 +-
 entry.c                  |    8 ++++----
 fast-import.c            |    4 ++--
 git.c                    |    6 +++---
 index-pack.c             |   21 ++++++++++-----------
 merge-recursive.c        |    6 +++---
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    6 +++---
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |    8 ++++----
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 43 files changed, 120 insertions(+), 135 deletions(-)

diff --git a/bisect.c b/bisect.c
index c43c120..281e16a 100644
--- a/bisect.c
+++ b/bisect.c
@@ -461,7 +461,7 @@ void read_bisect_paths(struct argv_array *array)
 	FILE *fp = fopen(filename, "r");
 
 	if (!fp)
-		die("Could not open file '%s': %s", filename, strerror(errno));
+		die_errno("Could not open file '%s'", filename);
 
 	while (strbuf_getline(&str, fp, '\n') != EOF) {
 		char *quoted;
@@ -632,8 +632,7 @@ static void mark_expected_rev(char *bisect_rev_hex)
 	int fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 
 	if (fd < 0)
-		die("could not create file '%s': %s",
-		    filename, strerror(errno));
+		die_errno("could not create file '%s'", filename);
 
 	bisect_rev_hex[len] = '\n';
 	write_or_die(fd, bisect_rev_hex, len + 1);
diff --git a/branch.c b/branch.c
index 62030af..05ef3f5 100644
--- a/branch.c
+++ b/branch.c
@@ -172,7 +172,7 @@ void create_branch(const char *head,
 
 	lock = lock_any_ref_for_update(ref.buf, NULL, 0);
 	if (!lock)
-		die("Failed to lock ref for update: %s.", strerror(errno));
+		die_errno("Failed to lock ref for update");
 
 	if (reflog)
 		log_all_ref_updates = 1;
@@ -188,7 +188,7 @@ void create_branch(const char *head,
 		setup_tracking(name, real_ref, track);
 
 	if (write_ref_sha1(lock, sha1, msg) < 0)
-		die("Failed to write ref: %s.", strerror(errno));
+		die_errno("Failed to write ref");
 
 	strbuf_release(&ref);
 	free(real_ref);
diff --git a/builtin-apply.c b/builtin-apply.c
index 94ba2bd..6526c08 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,
 static void read_patch_file(struct strbuf *sb, int fd)
 {
 	if (strbuf_read(sb, fd, 0) < 0)
-		die("git apply: read returned %s", strerror(errno));
+		die_errno("git apply: failed to read");
 
 	/*
 	 * Make sure that we have some slop in the buffer
@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 	strbuf_release(&nbuf);
 
 	if (close(fd) < 0)
-		die("closing file %s: %s", path, strerror(errno));
+		die_errno("closing file '%s'", path);
 	return 0;
 }
 
@@ -3354,7 +3354,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 
 		fd = open(arg, O_RDONLY);
 		if (fd < 0)
-			die("can't open patch '%s': %s", arg, strerror(errno));
+			die_errno("can't open patch '%s'", arg);
 		read_stdin = 0;
 		set_default_whitespace_mode(whitespace_option);
 		errs |= apply_patch(fd, arg, options);
diff --git a/builtin-blame.c b/builtin-blame.c
index 0c2d29a..7d8fbd5 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2035,7 +2035,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 		contents_from = "standard input";
 		mode = 0;
 		if (strbuf_read(&buf, 0, 0) < 0)
-			die("read error %s from stdin", strerror(errno));
+			die_errno("failed to read from stdin");
 	}
 	convert_to_git(path, buf.buf, buf.len, &buf, 0);
 	origin->file.ptr = buf.buf;
@@ -2261,8 +2261,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 	argc = parse_options_end(&ctx);
 
 	if (revs_file && read_ancestry(revs_file))
-		die("reading graft file %s failed: %s",
-		    revs_file, strerror(errno));
+		die_errno("reading graft file '%s' failed", revs_file);
 
 	if (cmd_is_annotate) {
 		output_option |= OUTPUT_ANNOTATE_COMPAT;
@@ -2350,7 +2349,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 
 		setup_work_tree();
 		if (!has_string_in_work_tree(path))
-			die("cannot stat path %s: %s", path, strerror(errno));
+			die_errno("cannot stat path '%s'", path);
 	}
 
 	setup_revisions(argc, argv, &revs, NULL);
diff --git a/builtin-clone.c b/builtin-clone.c
index 5c46496..5f34414 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -252,8 +252,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 		}
 
 		if (unlink(dest->buf) && errno != ENOENT)
-			die("failed to unlink %s: %s",
-			    dest->buf, strerror(errno));
+			die_errno("failed to unlink '%s'", dest->buf);
 		if (!option_no_hardlinks) {
 			if (!link(src->buf, dest->buf))
 				continue;
@@ -420,11 +419,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (!option_bare) {
 		junk_work_tree = work_tree;
 		if (safe_create_leading_directories_const(work_tree) < 0)
-			die("could not create leading directories of '%s': %s",
-					work_tree, strerror(errno));
+			die_errno("could not create leading directories of '%s'",
+				  work_tree);
 		if (!dest_exists && mkdir(work_tree, 0755))
-			die("could not create work tree dir '%s': %s.",
-					work_tree, strerror(errno));
+			die_errno("could not create work tree dir '%s'.",
+				  work_tree);
 		set_git_work_tree(work_tree);
 	}
 	junk_git_dir = git_dir;
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 0453425..6467077 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -124,7 +124,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&buffer, 0, 0) < 0)
-		die("git commit-tree: read returned %s", strerror(errno));
+		die_errno("git commit-tree: failed to read");
 
 	if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
 		printf("%s\n", sha1_to_hex(commit_sha1));
diff --git a/builtin-commit.c b/builtin-commit.c
index 41e222d..cce25b5 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -438,8 +438,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
-			die("could not read log file '%s': %s",
-			    logfile, strerror(errno));
+			die_errno("could not read log file '%s'",
+				  logfile);
 		hook_arg1 = "message";
 	} else if (use_message) {
 		buffer = strstr(use_message_buffer, "\n\n");
@@ -450,16 +450,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg2 = use_message;
 	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
-			die("could not read MERGE_MSG: %s", strerror(errno));
+			die_errno("could not read MERGE_MSG");
 		hook_arg1 = "merge";
 	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
-			die("could not read SQUASH_MSG: %s", strerror(errno));
+			die_errno("could not read SQUASH_MSG");
 		hook_arg1 = "squash";
 	} else if (template_file && !stat(template_file, &statbuf)) {
 		if (strbuf_read_file(&sb, template_file, 0) < 0)
-			die("could not read %s: %s",
-			    template_file, strerror(errno));
+			die_errno("could not read '%s'", template_file);
 		hook_arg1 = "template";
 	}
 
@@ -472,8 +471,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
 	fp = fopen(git_path(commit_editmsg), "w");
 	if (fp == NULL)
-		die("could not open %s: %s",
-		    git_path(commit_editmsg), strerror(errno));
+		die_errno("could not open '%s'", git_path(commit_editmsg));
 
 	if (cleanup_mode != CLEANUP_NONE)
 		stripspace(&sb, 0);
@@ -497,7 +495,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 	}
 
 	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
-		die("could not write commit template: %s", strerror(errno));
+		die_errno("could not write commit template");
 
 	strbuf_release(&sb);
 
@@ -940,8 +938,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
 		if (fp == NULL)
-			die("could not open %s for reading: %s",
-			    git_path("MERGE_HEAD"), strerror(errno));
+			die_errno("could not open %s for reading",
+				  git_path("MERGE_HEAD"));
 		while (strbuf_getline(&m, fp, '\n') != EOF) {
 			unsigned char sha1[20];
 			if (get_sha1_hex(m.buf, sha1) < 0)
@@ -952,8 +950,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		strbuf_release(&m);
 		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
 			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
-				die("could not read MERGE_MODE: %s",
-						strerror(errno));
+				die_errno("could not read MERGE_MODE");
 			if (!strcmp(sb.buf, "no-ff"))
 				allow_fast_forward = 0;
 		}
diff --git a/builtin-config.c b/builtin-config.c
index 60915f9..6858433 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -383,8 +383,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix)
 		check_argc(argc, 0, 0);
 		if (git_config(show_all_config, NULL) < 0) {
 			if (config_exclusive_filename)
-				die("unable to read config file %s: %s",
-				    config_exclusive_filename, strerror(errno));
+				die_errno("unable to read config file %s",
+					  config_exclusive_filename);
 			else
 				die("error processing config file(s)");
 		}
diff --git a/builtin-diff.c b/builtin-diff.c
index d75d69b..2e51f40 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -70,7 +70,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
 		usage(builtin_diff_usage);
 
 	if (lstat(path, &st))
-		die("'%s': %s", path, strerror(errno));
+		die_errno("failed to stat '%s'", path);
 	if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
 		die("'%s': not a regular file or symlink", path);
 
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 6cef810..333d438 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -451,7 +451,7 @@ static void import_marks(char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 
 	while (fgets(line, sizeof(line), f)) {
 		uint32_t mark;
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 29356d2..3dbdf7a 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -8,7 +8,7 @@
 {
 	struct strbuf buf = STRBUF_INIT;
 	if (strbuf_read(&buf, 0, 1024) < 0) {
-		die("error reading standard input: %s", strerror(errno));
+		die_errno("error reading standard input");
 	}
 	return strbuf_detach(&buf, NULL);
 }
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index fbf9582..1248d5e 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -372,8 +372,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
-		die("could not read input file %s", strerror(errno));
-
+		die_errno("could not read input file");
 	ret = fmt_merge_msg(merge_summary, &input, &output);
 	if (ret)
 		return ret;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 7da706c..a49dbe1 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -225,15 +225,15 @@ static void check_unreachable_object(struct object *obj)
 						&type, &size);
 				if (buf) {
 					if (fwrite(buf, size, 1, f) != 1)
-						die("Could not write %s: %s",
-						    filename, strerror(errno));
+						die_errno("Could not write '%s'",
+							  filename);
 					free(buf);
 				}
 			} else
 				fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
 			if (fclose(f))
-				die("Could not finish %s: %s",
-				    filename, strerror(errno));
+				die_errno("Could not finish '%s'",
+					  filename);
 		}
 		return;
 	}
diff --git a/builtin-grep.c b/builtin-grep.c
index 73fc922..e558368 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -594,7 +594,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
 
 	patterns = fopen(arg, "r");
 	if (!patterns)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("cannot open '%s'", arg);
 	while (strbuf_getline(&sb, patterns, '\n') == 0) {
 		/* ignore empty line like grep does */
 		if (sb.len == 0)
diff --git a/builtin-merge.c b/builtin-merge.c
index 8d101ef..a7e03ce 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -294,9 +294,9 @@ static void squash_message(void)
 			NULL, NULL, rev.date_mode, 0);
 	}
 	if (write(fd, out.buf, out.len) < 0)
-		die("Writing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Writing SQUASH_MSG");
 	if (close(fd))
-		die("Finishing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Finishing SQUASH_MSG");
 	strbuf_release(&out);
 }
 
@@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct strbuf *msg)
 
 		fp = fopen(git_path("FETCH_HEAD"), "r");
 		if (!fp)
-			die("could not open %s for reading: %s",
-				git_path("FETCH_HEAD"), strerror(errno));
+			die_errno("could not open %s for reading",
+				  git_path("FETCH_HEAD"));
 		strbuf_getline(&line, fp, '\n');
 		fclose(fp);
 		ptr = strstr(line.buf, "\tnot-for-merge\t");
diff --git a/builtin-mv.c b/builtin-mv.c
index 8b81d4b..e82ed20 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -209,7 +209,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 			printf("Renaming %s to %s\n", src, dst);
 		if (!show_only && mode != INDEX &&
 				rename(src, dst) < 0 && !ignore_errors)
-			die ("renaming %s failed: %s", src, strerror(errno));
+			die_errno ("renaming %s failed", src);
 
 		if (mode == WORKING_DIRECTORY)
 			continue;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 9742b45..60355d4 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -536,11 +536,9 @@ static void write_pack_file(void)
 				 base_name, sha1_to_hex(sha1));
 			free_pack_by_name(tmpname);
 			if (adjust_perm(pack_tmp_name, mode))
-				die("unable to make temporary pack file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary pack file readable");
 			if (rename(pack_tmp_name, tmpname))
-				die("unable to rename temporary pack file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary pack file");
 
 			/*
 			 * Packs are runtime accessed in their mtime
@@ -566,11 +564,9 @@ static void write_pack_file(void)
 			snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
 				 base_name, sha1_to_hex(sha1));
 			if (adjust_perm(idx_tmp_name, mode))
-				die("unable to make temporary index file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary index file readable");
 			if (rename(idx_tmp_name, tmpname))
-				die("unable to rename temporary index file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary index file");
 
 			free(idx_tmp_name);
 			free(pack_tmp_name);
@@ -1880,7 +1876,7 @@ static void read_object_list_from_stdin(void)
 			if (!ferror(stdin))
 				die("fgets returned NULL, not EOF, not error!");
 			if (errno != EINTR)
-				die("fgets: %s", strerror(errno));
+				die_errno("fgets");
 			clearerr(stdin);
 			continue;
 		}
diff --git a/builtin-rm.c b/builtin-rm.c
index 0cc4912..d632ef4 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -257,7 +257,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 				continue;
 			}
 			if (!removed)
-				die("git rm: %s: %s", path, strerror(errno));
+				die_errno("git rm: %s", path);
 		}
 	}
 
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index be3b092..8fe5ab9 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -59,7 +59,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
 	po.out = fd;
 	po.git_cmd = 1;
 	if (start_command(&po))
-		die("git pack-objects failed (%s)", strerror(errno));
+		die_errno("git pack-objects failed");
 
 	/*
 	 * We feed the pack-objects we just spawned with revision
diff --git a/builtin-tag.c b/builtin-tag.c
index dc3db62..7b51095 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -308,8 +308,7 @@ static void create_tag(const unsigned char *object, const char *tag,
 		path = git_pathdup("TAG_EDITMSG");
 		fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 		if (fd < 0)
-			die("could not create file '%s': %s",
-						path, strerror(errno));
+			die_errno("could not create file '%s'", path);
 
 		if (!is_null_sha1(prev))
 			write_tag_body(fd, prev);
@@ -446,8 +445,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 					die("cannot read %s", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
-					die("could not open or read '%s': %s",
-						msgfile, strerror(errno));
+					die_errno("could not open or read '%s'",
+						msgfile);
 			}
 		}
 	}
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 9a77323..41e9ac5 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -68,7 +68,7 @@ static void add_object_buffer(struct object *object, char *buffer, unsigned long
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		len += ret;
 	} while (len < min);
diff --git a/connect.c b/connect.c
index f6b8ba6..fd2f9b6 100644
--- a/connect.c
+++ b/connect.c
@@ -256,7 +256,7 @@ static int git_tcp_connect_sock(char *host, int flags)
 	freeaddrinfo(ai0);
 
 	if (sockfd < 0)
-		die("unable to connect a socket (%s)", strerror(saved_errno));
+		die_errno("unable to connect a socket");
 
 	if (flags & CONNECT_VERBOSE)
 		fprintf(stderr, "done.\n");
@@ -345,7 +345,7 @@ static int git_tcp_connect_sock(char *host, int flags)
 	}
 
 	if (sockfd < 0)
-		die("unable to connect a socket (%s)", strerror(saved_errno));
+		die_errno("unable to connect a socket");
 
 	if (flags & CONNECT_VERBOSE)
 		fprintf(stderr, "done.\n");
diff --git a/csum-file.c b/csum-file.c
index 2ddb12a..9cc93ba 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -26,7 +26,7 @@ static void flush(struct sha1file *f, void * buf, unsigned int count)
 		}
 		if (!ret)
 			die("sha1 file '%s' write error. Out of diskspace", f->name);
-		die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
+		die_errno("sha1 file '%s' write error", f->name);
 	}
 }
 
@@ -55,8 +55,8 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 		if (flags & CSUM_FSYNC)
 			fsync_or_die(f->fd, f->name);
 		if (close(f->fd))
-			die("%s: sha1 file error on close (%s)",
-			    f->name, strerror(errno));
+			die_errno("%s: sha1 file error on close",
+			    f->name);
 		fd = 0;
 	} else
 		fd = f->fd;
diff --git a/daemon.c b/daemon.c
index daa4c8e..5657661 100644
--- a/daemon.c
+++ b/daemon.c
@@ -860,7 +860,7 @@ static int service_loop(int socknum, int *socklist)
 					case ECONNABORTED:
 						continue;
 					default:
-						die("accept returned %s", strerror(errno));
+						die_errno("accept returned");
 					}
 				}
 				handle(incoming, (struct sockaddr *)&ss, sslen);
@@ -876,7 +876,7 @@ static void sanitize_stdfds(void)
 	while (fd != -1 && fd < 2)
 		fd = dup(fd);
 	if (fd == -1)
-		die("open /dev/null or dup failed: %s", strerror(errno));
+		die_errno("open /dev/null or dup failed");
 	if (fd > 2)
 		close(fd);
 }
@@ -887,12 +887,12 @@ static void daemonize(void)
 		case 0:
 			break;
 		case -1:
-			die("fork failed: %s", strerror(errno));
+			die_errno("fork failed");
 		default:
 			exit(0);
 	}
 	if (setsid() == -1)
-		die("setsid failed: %s", strerror(errno));
+		die_errno("setsid failed");
 	close(0);
 	close(1);
 	close(2);
@@ -903,9 +903,9 @@ static void store_pid(const char *path)
 {
 	FILE *f = fopen(path, "w");
 	if (!f)
-		die("cannot open pid file %s: %s", path, strerror(errno));
+		die_errno("cannot open pid file %s", path);
 	if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
-		die("failed to write pid file %s: %s", path, strerror(errno));
+		die_errno("failed to write pid file %s", path);
 }
 
 static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
@@ -1105,8 +1105,7 @@ int main(int argc, char **argv)
 		socklen_t slen = sizeof(ss);
 
 		if (!freopen("/dev/null", "w", stderr))
-			die("failed to redirect stderr to /dev/null: %s",
-			    strerror(errno));
+			die_errno("failed to redirect stderr to /dev/null");
 
 		if (getpeername(0, peer, &slen))
 			peer = NULL;
diff --git a/diff.c b/diff.c
index 4d0a5b9..48043f5 100644
--- a/diff.c
+++ b/diff.c
@@ -1975,7 +1975,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 	fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,
 			strlen(base) + 1);
 	if (fd < 0)
-		die("unable to create temp-file: %s", strerror(errno));
+		die_errno("unable to create temp-file");
 	if (convert_to_working_tree(path,
 			(const char *)blob, (size_t)size, &buf)) {
 		blob = buf.buf;
@@ -2021,7 +2021,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (lstat(name, &st) < 0) {
 			if (errno == ENOENT)
 				goto not_a_valid_file;
-			die("stat(%s): %s", name, strerror(errno));
+			die_errno("stat(%s)", name);
 		}
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
diff --git a/dir.c b/dir.c
index bbfcb56..74b3bbf 100644
--- a/dir.c
+++ b/dir.c
@@ -759,7 +759,7 @@ int file_exists(const char *f)
 	if (!dir)
 		return NULL;
 	if (!getcwd(buffer, size))
-		die("can't find the current directory: %s", strerror(errno));
+		die_errno("can't find the current directory");
 
 	if (!is_absolute_path(dir))
 		dir = make_absolute_path(dir);
diff --git a/entry.c b/entry.c
index cc841ed..099eaf4 100644
--- a/entry.c
+++ b/entry.c
@@ -51,7 +51,7 @@ static void remove_subtree(const char *path)
 	char *name;
 
 	if (!dir)
-		die("cannot opendir %s (%s)", path, strerror(errno));
+		die_errno("cannot opendir '%s'", path);
 	strcpy(pathbuf, path);
 	name = pathbuf + strlen(path);
 	*name++ = '/';
@@ -61,15 +61,15 @@ static void remove_subtree(const char *path)
 			continue;
 		strcpy(name, de->d_name);
 		if (lstat(pathbuf, &st))
-			die("cannot lstat %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot lstat %s", pathbuf);
 		if (S_ISDIR(st.st_mode))
 			remove_subtree(pathbuf);
 		else if (unlink(pathbuf))
-			die("cannot unlink %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot unlink %s", pathbuf);
 	}
 	closedir(dir);
 	if (rmdir(path))
-		die("cannot rmdir %s (%s)", path, strerror(errno));
+		die_errno("cannot rmdir %s", path);
 }
 
 static int create_file(const char *path, unsigned int mode)
diff --git a/fast-import.c b/fast-import.c
index a2a2458..d31a4e8 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2342,7 +2342,7 @@ static void import_marks(const char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 	while (fgets(line, sizeof(line), f)) {
 		uintmax_t mark;
 		char *end;
@@ -2448,7 +2448,7 @@ int main(int argc, const char **argv)
 				fclose(pack_edges);
 			pack_edges = fopen(a + 20, "a");
 			if (!pack_edges)
-				die("Cannot open %s: %s", a + 20, strerror(errno));
+				die_errno("Cannot open '%s'", a + 20);
 		} else if (!strcmp(a, "--force"))
 			force_update = 1;
 		else if (!strcmp(a, "--quiet"))
diff --git a/git.c b/git.c
index 7d7f949..b035676 100644
--- a/git.c
+++ b/git.c
@@ -200,7 +200,7 @@ static int handle_alias(int *argcp, const char ***argv)
 	}
 
 	if (subdir && chdir(subdir))
-		die("Cannot change to %s: %s", subdir, strerror(errno));
+		die_errno("Cannot change to '%s'", subdir);
 
 	errno = saved_errno;
 
@@ -257,11 +257,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 
 	/* Check for ENOSPC and EIO errors.. */
 	if (fflush(stdout))
-		die("write failure on standard output: %s", strerror(errno));
+		die_errno("write failure on standard output");
 	if (ferror(stdout))
 		die("unknown write failure on standard output");
 	if (fclose(stdout))
-		die("close failed on standard output: %s", strerror(errno));
+		die_errno("close failed on standard output");
 	return 0;
 }
 
diff --git a/index-pack.c b/index-pack.c
index 6e93ee6..cf6446f 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -143,7 +143,7 @@ static void flush(void)
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		input_len += ret;
 		if (from_stdin)
@@ -178,13 +178,12 @@ static void use(int bytes)
 		} else
 			output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
 		if (output_fd < 0)
-			die("unable to create %s: %s", pack_name, strerror(errno));
+			die_errno("unable to create '%s'", pack_name);
 		pack_fd = output_fd;
 	} else {
 		input_fd = open(pack_name, O_RDONLY);
 		if (input_fd < 0)
-			die("cannot open packfile '%s': %s",
-			    pack_name, strerror(errno));
+			die_errno("cannot open packfile '%s'", pack_name);
 		output_fd = -1;
 		pack_fd = input_fd;
 	}
@@ -370,7 +369,7 @@ static void unlink_base_data(struct base_data *c)
 	do {
 		ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
 		if (n < 0)
-			die("cannot pread pack file: %s", strerror(errno));
+			die_errno("cannot pread pack file");
 		if (!n)
 			die("premature end of pack file, %lu bytes missing",
 			    len - rdy);
@@ -631,7 +630,7 @@ static void parse_pack_objects(unsigned char *sha1)
 
 	/* If input_fd is a file, we should have reached its end now. */
 	if (fstat(input_fd, &st))
-		die("cannot fstat packfile: %s", strerror(errno));
+		die_errno("cannot fstat packfile");
 	if (S_ISREG(st.st_mode) &&
 			lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
 		die("pack has junk at the end");
@@ -788,7 +787,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 		fsync_or_die(output_fd, curr_pack_name);
 		err = close(output_fd);
 		if (err)
-			die("error while closing pack file: %s", strerror(errno));
+			die_errno("error while closing pack file");
 	}
 
 	if (keep_msg) {
@@ -801,16 +800,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 
 		if (keep_fd < 0) {
 			if (errno != EEXIST)
-				die("cannot write keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot write keep file '%s'",
+					  keep_name);
 		} else {
 			if (keep_msg_len > 0) {
 				write_or_die(keep_fd, keep_msg, keep_msg_len);
 				write_or_die(keep_fd, "\n", 1);
 			}
 			if (close(keep_fd) != 0)
-				die("cannot close written keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot close written keep file '%s'",
+				    keep_name);
 			report = "keep";
 		}
 	}
diff --git a/merge-recursive.c b/merge-recursive.c
index f5df9b9..5d9140b 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -438,7 +438,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
 			/* Ignore epipe */
 			if (errno == EPIPE)
 				break;
-			die("merge-recursive: %s", strerror(errno));
+			die_errno("merge-recursive");
 		} else if (!ret) {
 			die("merge-recursive: disk full?");
 		}
@@ -554,7 +554,7 @@ static void update_file_flags(struct merge_options *o,
 				mode = 0666;
 			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
 			if (fd < 0)
-				die("failed to open %s: %s", path, strerror(errno));
+				die_errno("failed to open '%s'", path);
 			flush_buffer(fd, buf, size);
 			close(fd);
 		} else if (S_ISLNK(mode)) {
@@ -562,7 +562,7 @@ static void update_file_flags(struct merge_options *o,
 			safe_create_leading_directories_const(path);
 			unlink(path);
 			if (symlink(lnk, path))
-				die("failed to symlink %s: %s", path, strerror(errno));
+				die_errno("failed to symlink '%s'", path);
 			free(lnk);
 		} else
 			die("do not know what to do with %06o %s '%s'",
diff --git a/pack-refs.c b/pack-refs.c
index 301fc60..7f43f8a 100644
--- a/pack-refs.c
+++ b/pack-refs.c
@@ -93,8 +93,7 @@ int pack_refs(unsigned int flags)
 				       LOCK_DIE_ON_ERROR);
 	cbdata.refs_file = fdopen(fd, "w");
 	if (!cbdata.refs_file)
-		die("unable to create ref-pack file structure (%s)",
-		    strerror(errno));
+		die_errno("unable to create ref-pack file structure");
 
 	/* perhaps other traits later as well */
 	fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
@@ -103,7 +102,7 @@ int pack_refs(unsigned int flags)
 	if (ferror(cbdata.refs_file))
 		die("failed to write ref-pack file");
 	if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
-		die("failed to write ref-pack file (%s)", strerror(errno));
+		die_errno("failed to write ref-pack file");
 	/*
 	 * Since the lock file was fdopen()'ed and then fclose()'ed above,
 	 * assign -1 to the lock file descriptor so that commit_lock_file()
@@ -111,7 +110,7 @@ int pack_refs(unsigned int flags)
 	 */
 	packed.fd = -1;
 	if (commit_lock_file(&packed) < 0)
-		die("unable to overwrite old ref-pack file (%s)", strerror(errno));
+		die_errno("unable to overwrite old ref-pack file");
 	if (cbdata.flags & PACK_REFS_PRUNE)
 		prune_refs(cbdata.ref_to_prune);
 	return 0;
diff --git a/pack-write.c b/pack-write.c
index 7053538..0117037 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -51,7 +51,7 @@ static int sha1_compare(const void *_a, const void *_b)
 		fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
 	}
 	if (fd < 0)
-		die("unable to create %s: %s", index_name, strerror(errno));
+		die_errno("unable to create %s", index_name);
 	f = sha1fd(fd, index_name);
 
 	/* if last object's offset is >= 2^31 we should use index V2 */
@@ -174,11 +174,11 @@ void fixup_pack_header_footer(int pack_fd,
 	git_SHA1_Init(&new_sha1_ctx);
 
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
-		die("Unable to reread header of %s: %s", pack_name, strerror(errno));
+		die_errno("Unable to reread header of '%s'", pack_name);
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	git_SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));
 	hdr.hdr_entries = htonl(object_count);
 	git_SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));
@@ -195,7 +195,7 @@ void fixup_pack_header_footer(int pack_fd,
 		if (!n)
 			break;
 		if (n < 0)
-			die("Failed to checksum %s: %s", pack_name, strerror(errno));
+			die_errno("Failed to checksum '%s'", pack_name);
 		git_SHA1_Update(&new_sha1_ctx, buf, n);
 
 		aligned_sz -= n;
diff --git a/pkt-line.c b/pkt-line.c
index f5d0086..b691abe 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -28,7 +28,7 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
 		}
 		if (!ret)
 			die("write error (disk full?)");
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 	return nn;
 }
@@ -67,7 +67,7 @@ static void safe_read(int fd, void *buffer, unsigned size)
 {
 	ssize_t ret = read_in_full(fd, buffer, size);
 	if (ret < 0)
-		die("read error (%s)", strerror(errno));
+		die_errno("read error");
 	else if (ret < size)
 		die("The remote end hung up unexpectedly");
 }
diff --git a/read-cache.c b/read-cache.c
index 3f58711..f76b5bb 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -638,7 +638,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
 {
 	struct stat st;
 	if (lstat(path, &st))
-		die("%s: unable to stat (%s)", path, strerror(errno));
+		die_errno("unable to stat '%s'", path);
 	return add_to_index(istate, path, &st, flags);
 }
 
@@ -1251,11 +1251,11 @@ int read_index_from(struct index_state *istate, const char *path)
 	if (fd < 0) {
 		if (errno == ENOENT)
 			return 0;
-		die("index file open failed (%s)", strerror(errno));
+		die_errno("index file open failed");
 	}
 
 	if (fstat(fd, &st))
-		die("cannot stat the open index (%s)", strerror(errno));
+		die_errno("cannot stat the open index");
 
 	errno = EINVAL;
 	mmap_size = xsize_t(st.st_size);
diff --git a/refs.c b/refs.c
index 24438c6..dffe395 100644
--- a/refs.c
+++ b/refs.c
@@ -1418,7 +1418,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
 	logfile = git_path("logs/%s", ref);
 	logfd = open(logfile, O_RDONLY, 0);
 	if (logfd < 0)
-		die("Unable to read log %s: %s", logfile, strerror(errno));
+		die_errno("Unable to read log '%s'", logfile);
 	fstat(logfd, &st);
 	if (!st.st_size)
 		die("Log %s is empty.", logfile);
diff --git a/run-command.c b/run-command.c
index eb2efc3..79bdfd4 100644
--- a/run-command.c
+++ b/run-command.c
@@ -101,8 +101,8 @@ int start_command(struct child_process *cmd)
 		}
 
 		if (cmd->dir && chdir(cmd->dir))
-			die("exec %s: cd to %s failed (%s)", cmd->argv[0],
-			    cmd->dir, strerror(errno));
+			die_errno("exec %s: cd to '%s' failed", cmd->argv[0],
+			    cmd->dir);
 		if (cmd->env) {
 			for (; *cmd->env; cmd->env++) {
 				if (strchr(*cmd->env, '='))
diff --git a/setup.c b/setup.c
index ebd60de..4d27f28 100644
--- a/setup.c
+++ b/setup.c
@@ -81,7 +81,7 @@ void verify_filename(const char *prefix, const char *arg)
 	if (errno == ENOENT)
 		die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
 		    "Use '--' to separate paths from revisions", arg);
-	die("'%s': %s", arg, strerror(errno));
+	die_errno("failed to stat '%s'", arg);
 }
 
 /*
@@ -103,7 +103,7 @@ void verify_non_filename(const char *prefix, const char *arg)
 		die("ambiguous argument '%s': both revision and filename\n"
 		    "Use '--' to separate filenames from revisions", arg);
 	if (errno != ENOENT && errno != ENOTDIR)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("failed to stat '%s'", arg);
 }
 
 const char **get_pathspec(const char *prefix, const char **pathspec)
@@ -257,7 +257,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		return NULL;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Error opening %s: %s", path, strerror(errno));
+		die_errno("Error opening '%s'", path);
 	buf = xmalloc(st.st_size + 1);
 	len = read_in_full(fd, buf, st.st_size);
 	close(fd);
@@ -389,7 +389,7 @@ static int check_repository_format_gently(int *nongit_ok)
 			die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
 		}
 		if (chdir(".."))
-			die("Cannot change to %s/..: %s", cwd, strerror(errno));
+			die_errno("Cannot change to '%s/..'", cwd);
 	}
 
 	inside_git_dir = 0;
diff --git a/sha1_file.c b/sha1_file.c
index e73cd4f..1964a6d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2287,7 +2287,7 @@ static void close_sha1_file(int fd)
 	if (fsync_object_files)
 		fsync_or_die(fd, "sha1 file");
 	if (close(fd) != 0)
-		die("error when closing sha1 file (%s)", strerror(errno));
+		die_errno("error when closing sha1 file");
 }
 
 /* Size of directory component, including the ending '/' */
diff --git a/shell.c b/shell.c
index b968be7..e4864e0 100644
--- a/shell.c
+++ b/shell.c
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
 	while (devnull_fd >= 0 && devnull_fd <= 2)
 		devnull_fd = dup(devnull_fd);
 	if (devnull_fd == -1)
-		die("opening /dev/null failed (%s)", strerror(errno));
+		die_errno("opening /dev/null failed");
 	close (devnull_fd);
 
 	/*
diff --git a/test-sha1.c b/test-sha1.c
index 9b98d07..80daba9 100644
--- a/test-sha1.c
+++ b/test-sha1.c
@@ -32,7 +32,7 @@ int main(int ac, char **av)
 			if (sz == 0)
 				break;
 			if (sz < 0)
-				die("test-sha1: %s", strerror(errno));
+				die_errno("test-sha1");
 			this_sz += sz;
 			cp += sz;
 			room -= sz;
diff --git a/wrapper.c b/wrapper.c
index 7eb3218..c9be140 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -96,7 +96,7 @@
 		release_pack_memory(length, fd);
 		ret = mmap(start, length, prot, flags, fd, offset);
 		if (ret == MAP_FAILED)
-			die("Out of memory? mmap failed: %s", strerror(errno));
+			die_errno("Out of memory? mmap failed");
 	}
 	return ret;
 }
@@ -175,7 +175,7 @@ int xdup(int fd)
 {
 	int ret = dup(fd);
 	if (ret < 0)
-		die("dup failed: %s", strerror(errno));
+		die_errno("dup failed");
 	return ret;
 }
 
@@ -183,7 +183,7 @@ int xdup(int fd)
 {
 	FILE *stream = fdopen(fd, mode);
 	if (stream == NULL)
-		die("Out of memory? fdopen failed: %s", strerror(errno));
+		die_errno("Out of memory? fdopen failed");
 	return stream;
 }
 
@@ -193,7 +193,7 @@ int xmkstemp(char *template)
 
 	fd = mkstemp(template);
 	if (fd < 0)
-		die("Unable to create temporary file: %s", strerror(errno));
+		die_errno("Unable to create temporary file");
 	return fd;
 }
 
diff --git a/write_or_die.c b/write_or_die.c
index 4c29255..d45b536 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -41,14 +41,14 @@ void maybe_flush_or_die(FILE *f, const char *desc)
 		 */
 		if (errno == EPIPE || errno == EINVAL)
 			exit(0);
-		die("write failure on %s: %s", desc, strerror(errno));
+		die_errno("write failure on '%s'", desc);
 	}
 }
 
 void fsync_or_die(int fd, const char *msg)
 {
 	if (fsync(fd) < 0) {
-		die("%s: fsync error (%s)", msg, strerror(errno));
+		die_errno("fsync error on '%s'", msg);
 	}
 }
 
@@ -57,7 +57,7 @@ void write_or_die(int fd, const void *buf, size_t count)
 	if (write_in_full(fd, buf, count) < 0) {
 		if (errno == EPIPE)
 			exit(0);
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 }
 
-- 
1.6.3.2.288.g40844

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls
  2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
                       ` (2 preceding siblings ...)
  2009-06-06 14:44     ` [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
@ 2009-06-06 14:44     ` Thomas Rast
  2009-06-06 21:02       ` Johannes Sixt
  3 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 14:44 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

Lots of die() calls did not actually report the kind of error, which
can leave the user confused as to the real problem.  Use die_errno()
where we check a system/library call that sets errno on failure, or
one of the following that wrap such calls:

  Function              Passes on error from
  --------              --------------------
  odb_pack_keep         open
  read_ancestry         fopen
  read_in_full          xread
  strbuf_read           xread
  strbuf_read_file      open or strbuf_read_file
  strbuf_readlink       readlink
  write_in_full         xwrite

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 abspath.c               |   12 ++++++------
 builtin-add.c           |    2 +-
 builtin-apply.c         |    6 +++---
 builtin-archive.c       |    4 ++--
 builtin-blame.c         |    9 ++++-----
 builtin-clone.c         |   11 +++++------
 builtin-commit-tree.c   |    1 -
 builtin-commit.c        |   13 +++++++------
 builtin-fast-export.c   |    3 +--
 builtin-fmt-merge-msg.c |    2 +-
 builtin-fsck.c          |    2 +-
 builtin-init-db.c       |   22 +++++++++++-----------
 builtin-log.c           |    4 ++--
 builtin-mailsplit.c     |    7 +++----
 builtin-merge.c         |   25 +++++++++++++++----------
 builtin-rev-parse.c     |    2 +-
 builtin-revert.c        |    2 +-
 builtin-stripspace.c    |    2 +-
 builtin-tag.c           |    2 +-
 builtin-tar-tree.c      |    2 +-
 combine-diff.c          |    2 +-
 csum-file.c             |    3 +--
 diff.c                  |    6 +++---
 entry.c                 |    2 +-
 fast-import.c           |    4 ++--
 hash-object.c           |    2 +-
 ll-merge.c              |    2 +-
 mktag.c                 |    2 +-
 read-cache.c            |    2 +-
 setup.c                 |   10 +++++-----
 transport.c             |    4 ++--
 unpack-file.c           |    2 +-
 32 files changed, 87 insertions(+), 87 deletions(-)

diff --git a/abspath.c b/abspath.c
index 649f34f..4bee0ba 100644
--- a/abspath.c
+++ b/abspath.c
@@ -41,13 +41,13 @@ int is_directory(const char *path)
 
 		if (*buf) {
 			if (!*cwd && !getcwd(cwd, sizeof(cwd)))
-				die ("Could not get current working directory");
+				die_errno ("Could not get current working directory");
 
 			if (chdir(buf))
-				die ("Could not switch to '%s'", buf);
+				die_errno ("Could not switch to '%s'", buf);
 		}
 		if (!getcwd(buf, PATH_MAX))
-			die ("Could not get current working directory");
+			die_errno ("Could not get current working directory");
 
 		if (last_elem) {
 			int len = strlen(buf);
@@ -63,7 +63,7 @@ int is_directory(const char *path)
 		if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
 			len = readlink(buf, next_buf, PATH_MAX);
 			if (len < 0)
-				die ("Invalid symlink: %s", buf);
+				die_errno ("Invalid symlink '%s'", buf);
 			if (PATH_MAX <= len)
 				die("symbolic link too long: %s", buf);
 			next_buf[len] = '\0';
@@ -75,7 +75,7 @@ int is_directory(const char *path)
 	}
 
 	if (*cwd && chdir(cwd))
-		die ("Could not change back to '%s'", cwd);
+		die_errno ("Could not change back to '%s'", cwd);
 
 	return buf;
 }
@@ -109,7 +109,7 @@ int is_directory(const char *path)
 	} else {
 		const char *cwd = get_pwd_cwd();
 		if (!cwd)
-			die("Cannot determine the current working directory");
+			die_errno("Cannot determine the current working directory");
 		if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
 			die("Too long path: %.*s", 60, path);
 	}
diff --git a/builtin-add.c b/builtin-add.c
index c1b229a..8f651c1 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -220,7 +220,7 @@ int edit_patch(int argc, const char **argv, const char *prefix)
 	launch_editor(file, NULL, NULL);
 
 	if (stat(file, &st))
-		die("Could not stat '%s'", file);
+		die_errno("Could not stat '%s'", file);
 	if (!st.st_size)
 		die("Empty patch. Aborted.");
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 6526c08..dbc7f21 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned 
 	} else {
 		if (!cached) {
 			if (lstat(path, &st) < 0)
-				die("unable to stat newly created file %s",
-				    path);
+				die_errno("unable to stat newly created file '%s'",
+					  path);
 			fill_stat_cache_info(ce, &st);
 		}
 		if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
 			++nr;
 		}
 	}
-	die("unable to write file %s mode %o", path, mode);
+	die_errno("unable to write file '%s' mode %o", path, mode);
 }
 
 static void create_file(struct patch *patch)
diff --git a/builtin-archive.c b/builtin-archive.c
index 3c5a5a7..f9a4bea 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -13,10 +13,10 @@ static void create_output_file(const char *output_file)
 {
 	int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 	if (output_fd < 0)
-		die("could not create archive file: %s ", output_file);
+		die_errno("could not create archive file '%s'", output_file);
 	if (output_fd != 1) {
 		if (dup2(output_fd, 1) < 0)
-			die("could not redirect output");
+			die_errno("could not redirect output");
 		else
 			close(output_fd);
 	}
diff --git a/builtin-blame.c b/builtin-blame.c
index 7d8fbd5..7c23d49 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2008,23 +2008,23 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 
 		if (contents_from) {
 			if (stat(contents_from, &st) < 0)
-				die("Cannot stat %s", contents_from);
+				die_errno("Cannot stat '%s'", contents_from);
 			read_from = contents_from;
 		}
 		else {
 			if (lstat(path, &st) < 0)
-				die("Cannot lstat %s", path);
+				die_errno("Cannot lstat '%s'", path);
 			read_from = path;
 		}
 		mode = canon_mode(st.st_mode);
 		switch (st.st_mode & S_IFMT) {
 		case S_IFREG:
 			if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
-				die("cannot open or read %s", read_from);
+				die_errno("cannot open or read '%s'", read_from);
 			break;
 		case S_IFLNK:
 			if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
-				die("cannot readlink %s", read_from);
+				die_errno("cannot readlink '%s'", read_from);
 			break;
 		default:
 			die("unsupported file type %s", read_from);
@@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 
 	if (revs_file && read_ancestry(revs_file))
 		die_errno("reading graft file '%s' failed", revs_file);
-
 	if (cmd_is_annotate) {
 		output_option |= OUTPUT_ANNOTATE_COMPAT;
 		blame_date_mode = DATE_ISO8601;
diff --git a/builtin-clone.c b/builtin-clone.c
index 5f34414..03b691b 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -220,13 +220,12 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 
 	dir = opendir(src->buf);
 	if (!dir)
-		die("failed to open %s", src->buf);
-
+		die_errno("failed to open '%s'", src->buf);
 	if (mkdir(dest->buf, 0777)) {
 		if (errno != EEXIST)
-			die("failed to create directory %s", dest->buf);
+			die_errno("failed to create directory '%s'", dest->buf);
 		else if (stat(dest->buf, &buf))
-			die("failed to stat %s", dest->buf);
+			die_errno("failed to stat '%s'", dest->buf);
 		else if (!S_ISDIR(buf.st_mode))
 			die("%s exists and is not a directory", dest->buf);
 	}
@@ -257,11 +256,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 			if (!link(src->buf, dest->buf))
 				continue;
 			if (option_local)
-				die("failed to create link %s", dest->buf);
+				die_errno("failed to create link '%s'", dest->buf);
 			option_no_hardlinks = 1;
 		}
 		if (copy_file(dest->buf, src->buf, 0666))
-			die("failed to copy file to %s", dest->buf);
+			die_errno("failed to copy file to '%s'", dest->buf);
 	}
 	closedir(dir);
 }
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 6467077..3ce8e82 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -125,7 +125,6 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 
 	if (strbuf_read(&buffer, 0, 0) < 0)
 		die_errno("git commit-tree: failed to read");
-
 	if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
 		printf("%s\n", sha1_to_hex(commit_sha1));
 		return 0;
diff --git a/builtin-commit.c b/builtin-commit.c
index cce25b5..77298e9 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -434,7 +434,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		if (isatty(0))
 			fprintf(stderr, "(reading log message from standard input)\n");
 		if (strbuf_read(&sb, 0, 0) < 0)
-			die("could not read log from standard input");
+			die_errno("could not read log from standard input");
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
@@ -472,7 +472,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 	fp = fopen(git_path(commit_editmsg), "w");
 	if (fp == NULL)
 		die_errno("could not open '%s'", git_path(commit_editmsg));
-
 	if (cleanup_mode != CLEANUP_NONE)
 		stripspace(&sb, 0);
 
@@ -496,7 +495,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
 	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
 		die_errno("could not write commit template");
-
 	strbuf_release(&sb);
 
 	determine_author_info();
@@ -964,8 +962,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	/* Finally, get the commit message */
 	strbuf_reset(&sb);
 	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
+		int saved_errno = errno;
 		rollback_index_files();
-		die("could not read commit message");
+		die("could not read commit message: %s", strerror(saved_errno));
 	}
 
 	/* Truncate the message just before the diff, if any. */
@@ -1018,8 +1017,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 
 	if (commit_index_files())
 		die ("Repository has been updated, but unable to write\n"
-		     "new_index file. Check that disk is not full or quota is\n"
-		     "not exceeded, and then \"git reset HEAD\" to recover.");
+		     "new_index file: %s.\n"
+		     "Check that disk is not full or quota is not exceeded,\n"
+		     "and then \"git reset HEAD\" to recover.",
+		     strerror(errno));
 
 	rerere();
 	run_hook(get_index_file(), "post-commit", NULL);
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 333d438..3199d8a 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -119,7 +119,7 @@ static void handle_object(const unsigned char *sha1)
 
 	printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
 	if (size && fwrite(buf, size, 1, stdout) != 1)
-		die ("Could not write blob %s", sha1_to_hex(sha1));
+		die_errno ("Could not write blob '%s'", sha1_to_hex(sha1));
 	printf("\n");
 
 	show_progress();
@@ -452,7 +452,6 @@ static void import_marks(char *input_file)
 	FILE *f = fopen(input_file, "r");
 	if (!f)
 		die_errno("cannot read '%s'", input_file);
-
 	while (fgets(line, sizeof(line), f)) {
 		uint32_t mark;
 		char *line_end, *mark_end;
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index 1248d5e..9d52400 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	if (inpath && strcmp(inpath, "-")) {
 		in = fopen(inpath, "r");
 		if (!in)
-			die("cannot open %s", inpath);
+			die_errno("cannot open '%s'", inpath);
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index a49dbe1..d0f48cd 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -217,7 +217,7 @@ static void check_unreachable_object(struct object *obj)
 				return;
 			}
 			if (!(f = fopen(filename, "w")))
-				die("Could not open %s", filename);
+				die_errno("Could not open '%s'", filename);
 			if (obj->type == OBJ_BLOB) {
 				enum object_type type;
 				unsigned long size;
diff --git a/builtin-init-db.c b/builtin-init-db.c
index d1fa12a..50418cd 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -61,20 +61,19 @@ static void copy_templates_1(char *path, int baselen,
 		memcpy(template + template_baselen, de->d_name, namelen+1);
 		if (lstat(path, &st_git)) {
 			if (errno != ENOENT)
-				die("cannot stat %s", path);
+				die_errno("cannot stat '%s'", path);
 		}
 		else
 			exists = 1;
 
 		if (lstat(template, &st_template))
-			die("cannot stat template %s", template);
-
+			die_errno("cannot stat template '%s'", template);
 		if (S_ISDIR(st_template.st_mode)) {
 			DIR *subdir = opendir(template);
 			int baselen_sub = baselen + namelen;
 			int template_baselen_sub = template_baselen + namelen;
 			if (!subdir)
-				die("cannot opendir %s", template);
+				die_errno("cannot opendir '%s'", template);
 			path[baselen_sub++] =
 				template[template_baselen_sub++] = '/';
 			path[baselen_sub] =
@@ -91,16 +90,17 @@ static void copy_templates_1(char *path, int baselen,
 			int len;
 			len = readlink(template, lnk, sizeof(lnk));
 			if (len < 0)
-				die("cannot readlink %s", template);
+				die_errno("cannot readlink '%s'", template);
 			if (sizeof(lnk) <= len)
 				die("insanely long symlink %s", template);
 			lnk[len] = 0;
 			if (symlink(lnk, path))
-				die("cannot symlink %s %s", lnk, path);
+				die_errno("cannot symlink '%s' '%s'", lnk, path);
 		}
 		else if (S_ISREG(st_template.st_mode)) {
 			if (copy_file(path, template, st_template.st_mode))
-				die("cannot copy %s to %s", template, path);
+				die_errno("cannot copy '%s' to '%s'", template,
+					  path);
 		}
 		else
 			error("ignoring template %s", template);
@@ -350,7 +350,7 @@ static int guess_repository_type(const char *git_dir)
 	if (!strcmp(".", git_dir))
 		return 1;
 	if (!getcwd(cwd, sizeof(cwd)))
-		die("cannot tell cwd");
+		die_errno("cannot tell cwd");
 	if (!strcmp(git_dir, cwd))
 		return 1;
 	/*
@@ -440,11 +440,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		if (!git_work_tree_cfg) {
 			git_work_tree_cfg = xcalloc(PATH_MAX, 1);
 			if (!getcwd(git_work_tree_cfg, PATH_MAX))
-				die ("Cannot access current working directory.");
+				die_errno ("Cannot access current working directory");
 		}
 		if (access(get_git_work_tree(), X_OK))
-			die ("Cannot access work tree '%s'",
-			     get_git_work_tree());
+			die_errno ("Cannot access work tree '%s'",
+				   get_git_work_tree());
 	}
 
 	set_git_dir(make_absolute_path(git_dir));
diff --git a/builtin-log.c b/builtin-log.c
index 0d34050..750957c 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		if (use_stdout)
 			die("standard output, or directory, which one?");
 		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
-			die("Could not create directory %s",
-			    output_directory);
+			die_errno("Could not create directory '%s'",
+				  output_directory);
 	}
 
 	if (rev.pending.nr == 1) {
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c
index 71f3b3b..f549234 100644
--- a/builtin-mailsplit.c
+++ b/builtin-mailsplit.c
@@ -81,7 +81,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 
 	fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
 	if (fd < 0)
-		die("cannot open output file %s", name);
+		die_errno("cannot open output file '%s'", name);
 	output = fdopen(fd, "w");
 
 	/* Copy it out, while searching for a line that begins with
@@ -91,15 +91,14 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 		int is_partial = len && buf[len-1] != '\n';
 
 		if (fwrite(buf, 1, len, output) != len)
-			die("cannot write output");
-
+			die_errno("cannot write output");
 		len = read_line_with_nul(buf, sizeof(buf), mbox);
 		if (len == 0) {
 			if (feof(mbox)) {
 				status = 1;
 				break;
 			}
-			die("cannot read mbox");
+			die_errno("cannot read mbox");
 		}
 		if (!is_partial && !is_bare && is_from_line(buf, len))
 			break; /* done with one message */
diff --git a/builtin-merge.c b/builtin-merge.c
index a7e03ce..35f4520 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -268,8 +268,7 @@ static void squash_message(void)
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
 	if (fd < 0)
-		die("Could not write to %s", git_path("SQUASH_MSG"));
-
+		die_errno("Could not write to '%s'", git_path("SQUASH_MSG"));
 	init_revisions(&rev, NULL);
 	rev.ignore_merges = 1;
 	rev.commit_format = CMIT_FMT_MEDIUM;
@@ -764,7 +763,8 @@ static int suggest_conflicts(void)
 
 	fp = fopen(git_path("MERGE_MSG"), "a");
 	if (!fp)
-		die("Could not open %s for writing", git_path("MERGE_MSG"));
+		die_errno("Could not open '%s' for writing",
+			  git_path("MERGE_MSG"));
 	fprintf(fp, "\nConflicts:\n");
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
@@ -1186,27 +1186,32 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 				sha1_to_hex(j->item->object.sha1));
 		fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing",
-				git_path("MERGE_HEAD"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_HEAD"));
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_HEAD"));
+			die_errno("Could not write to '%s'",
+				  git_path("MERGE_HEAD"));
 		close(fd);
 		strbuf_addch(&merge_msg, '\n');
 		fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MSG"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MSG"));
 		if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
 			merge_msg.len)
-			die("Could not write to %s", git_path("MERGE_MSG"));
+			die_errno("Could not write to '%s'",
+				  git_path("MERGE_MSG"));
 		close(fd);
 		fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MODE"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MODE"));
 		strbuf_reset(&buf);
 		if (!allow_fast_forward)
 			strbuf_addf(&buf, "no-ff");
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_MODE"));
+			die_errno("Could not write to '%s'",
+			    git_path("MERGE_MODE"));
 		close(fd);
 	}
 
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 112d622..da26dbc 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -592,7 +592,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 					continue;
 				}
 				if (!getcwd(cwd, PATH_MAX))
-					die("unable to get current working directory");
+					die_errno("unable to get current working directory");
 				printf("%s/.git\n", cwd);
 				continue;
 			}
diff --git a/builtin-revert.c b/builtin-revert.c
index c87115a..151aa6a 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)
 {
 	int len = strlen(string);
 	if (write_in_full(msg_fd, string, len) < 0)
-		die ("Could not write to MERGE_MSG");
+		die_errno ("Could not write to MERGE_MSG");
 }
 
 static void add_message_to_msg(const char *message)
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index d6e3896..1fd2205 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
 		strip_comments = 1;
 
 	if (strbuf_read(&buf, 0, 1024) < 0)
-		die("could not read the input");
+		die_errno("could not read the input");
 
 	stripspace(&buf, strip_comments);
 
diff --git a/builtin-tag.c b/builtin-tag.c
index 7b51095..165bec3 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -442,7 +442,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		else {
 			if (!strcmp(msgfile, "-")) {
 				if (strbuf_read(&buf, 0, 1024) < 0)
-					die("cannot read %s", msgfile);
+					die_errno("cannot read '%s'", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
 					die_errno("could not open or read '%s'",
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index f88e721..8b3a35e 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
 
 	n = write_in_full(1, content + 11, 41);
 	if (n < 41)
-		die("git get-tar-commit-id: write error");
+		die_errno("git get-tar-commit-id: write error");
 
 	return 0;
 }
diff --git a/combine-diff.c b/combine-diff.c
index 60d0367..bbf74fc 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -746,7 +746,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 
 			done = read_in_full(fd, result, len);
 			if (done < 0)
-				die("read error '%s'", elem->path);
+				die_errno("read error '%s'", elem->path);
 			else if (done < len)
 				die("early EOF '%s'", elem->path);
 
diff --git a/csum-file.c b/csum-file.c
index 9cc93ba..4d50cc5 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 		if (flags & CSUM_FSYNC)
 			fsync_or_die(f->fd, f->name);
 		if (close(f->fd))
-			die_errno("%s: sha1 file error on close",
-			    f->name);
+			die_errno("%s: sha1 file error on close", f->name);
 		fd = 0;
 	} else
 		fd = f->fd;
diff --git a/diff.c b/diff.c
index 48043f5..aec613f 100644
--- a/diff.c
+++ b/diff.c
@@ -1982,7 +1982,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		size = buf.len;
 	}
 	if (write_in_full(fd, blob, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	temp->name = temp->tmp_path;
 	strcpy(temp->hex, sha1_to_hex(sha1));
@@ -2026,7 +2026,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
 			if (strbuf_readlink(&sb, name, st.st_size) < 0)
-				die("readlink(%s)", name);
+				die_errno("readlink(%s)", name);
 			prep_temp_blob(name, temp, sb.buf, sb.len,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
@@ -2219,7 +2219,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
 				return;
 			}
 			if (lstat(one->path, &st) < 0)
-				die("stat %s", one->path);
+				die_errno("stat '%s'", one->path);
 			if (index_path(one->sha1, one->path, &st, 0))
 				die("cannot hash %s", one->path);
 		}
diff --git a/entry.c b/entry.c
index 099eaf4..e9e396b 100644
--- a/entry.c
+++ b/entry.c
@@ -37,7 +37,7 @@ static void create_directories(const char *path, int path_len,
 			if (errno == EEXIST && state->force &&
 			    !unlink_or_warn(buf) && !mkdir(buf, 0777))
 				continue;
-			die("cannot create directory at %s", buf);
+			die_errno("cannot create directory at '%s'", buf);
 		}
 	}
 	free(buf);
diff --git a/fast-import.c b/fast-import.c
index d31a4e8..7ef9865 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)
 
 	keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
 	if (keep_fd < 0)
-		die("cannot create keep file");
+		die_errno("cannot create keep file");
 	write_or_die(keep_fd, keep_msg, strlen(keep_msg));
 	if (close(keep_fd))
-		die("failed to write keep file");
+		die_errno("failed to write keep file");
 
 	snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
 		 get_object_directory(), sha1_to_hex(pack_data->sha1));
diff --git a/hash-object.c b/hash-object.c
index 47cf43c..9455dd0 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,
 	int fd;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Cannot open %s", path);
+		die_errno("Cannot open '%s'", path);
 	hash_fd(fd, type, write_object, vpath);
 }
 
diff --git a/ll-merge.c b/ll-merge.c
index 81c02ad..caf22be 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, src->ptr, src->size) != src->size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 }
 
diff --git a/mktag.c b/mktag.c
index 99a356e..a609e3e 100644
--- a/mktag.c
+++ b/mktag.c
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
 	setup_git_directory();
 
 	if (strbuf_read(&buf, 0, 4096) < 0) {
-		die("could not read from stdin");
+		die_errno("could not read from stdin");
 	}
 
 	/* Verify it for some basic sanity: it needs to start with
diff --git a/read-cache.c b/read-cache.c
index f76b5bb..4e3e272 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)
 	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	close(fd);
 	if (mmap == MAP_FAILED)
-		die("unable to map index file");
+		die_errno("unable to map index file");
 
 	hdr = mmap;
 	if (verify_hdr(hdr, mmap_size) < 0)
diff --git a/setup.c b/setup.c
index 4d27f28..e3781b6 100644
--- a/setup.c
+++ b/setup.c
@@ -327,7 +327,7 @@ static int check_repository_format_gently(int *nongit_ok)
 				return NULL;
 			set_git_dir(make_absolute_path(gitdirenv));
 			if (chdir(work_tree_env) < 0)
-				die ("Could not chdir to %s", work_tree_env);
+				die_errno ("Could not chdir to '%s'", work_tree_env);
 			strcat(buffer, "/");
 			return retval;
 		}
@@ -339,7 +339,7 @@ static int check_repository_format_gently(int *nongit_ok)
 	}
 
 	if (!getcwd(cwd, sizeof(cwd)-1))
-		die("Unable to read current working directory");
+		die_errno("Unable to read current working directory");
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -382,7 +382,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		if (offset <= ceil_offset) {
 			if (nongit_ok) {
 				if (chdir(cwd))
-					die("Cannot come back to cwd");
+					die_errno("Cannot come back to cwd");
 				*nongit_ok = 1;
 				return NULL;
 			}
@@ -493,10 +493,10 @@ int check_repository_format(void)
 		static char buffer[PATH_MAX + 1];
 		char *rel;
 		if (retval && chdir(retval))
-			die ("Could not jump back into original cwd");
+			die_errno ("Could not jump back into original cwd");
 		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
 		if (rel && *rel && chdir(get_git_work_tree()))
-			die ("Could not jump to working directory");
+			die_errno ("Could not jump to working directory");
 		return rel && *rel ? strcat(rel, "/") : NULL;
 	}
 
diff --git a/transport.c b/transport.c
index 17891d5..8decd66 100644
--- a/transport.c
+++ b/transport.c
@@ -158,7 +158,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	temp_dir_len = temp_dir.len;
 
 	strbuf_addstr(&buf, rsync_url(transport->url));
@@ -321,7 +321,7 @@ static int rsync_transport_push(struct transport *transport,
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	strbuf_addch(&temp_dir, '/');
 
 	if (flags & TRANSPORT_PUSH_ALL) {
diff --git a/unpack-file.c b/unpack-file.c
index 75cd2f1..ac9cbf7 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -17,7 +17,7 @@
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, buf, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	return path;
 }
-- 
1.6.3.2.288.g40844

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno()
  2009-06-06 14:44     ` [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
@ 2009-06-06 20:31       ` Johannes Sixt
  0 siblings, 0 replies; 42+ messages in thread
From: Johannes Sixt @ 2009-06-06 20:31 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

On Samstag, 6. Juni 2009, Thomas Rast wrote:
> Change calls to die(..., strerror(errno)) to use the new die_errno().
>
> In the process, also make slight style adjustments: at least state
> _something_ about the function that failed (instead of just printing
> the pathname), and put paths in single quotes.

> @@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct
> strbuf *msg)
>
>  		fp = fopen(git_path("FETCH_HEAD"), "r");
>  		if (!fp)
> -			die("could not open %s for reading: %s",
> -				git_path("FETCH_HEAD"), strerror(errno));
> +			die_errno("could not open %s for reading",
> +				  git_path("FETCH_HEAD"));

You said you added quotes, but you didn't do that here and in quite a few more 
other cases.

IMHO, the quotes are not an improvement anyway, but that's really only my 
personal taste.

> --- a/connect.c
> +++ b/connect.c
> @@ -256,7 +256,7 @@ static int git_tcp_connect_sock(char *host, int flags)
>  	freeaddrinfo(ai0);
>
>  	if (sockfd < 0)
> -		die("unable to connect a socket (%s)", strerror(saved_errno));
> +		die_errno("unable to connect a socket");

You cannot convert this: We want strerror(saved_errno), but die_errno would 
print strerror(errno).

> @@ -345,7 +345,7 @@ static int git_tcp_connect_sock(char *host, int flags)
>  	}
>
>  	if (sockfd < 0)
> -		die("unable to connect a socket (%s)", strerror(saved_errno));
> +		die_errno("unable to connect a socket");

Same here.

-- Hannes

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 14:44     ` [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
@ 2009-06-06 20:36       ` Johannes Sixt
  2009-06-06 20:56         ` Thomas Rast
  2009-06-06 22:13       ` Jeff King
  1 sibling, 1 reply; 42+ messages in thread
From: Johannes Sixt @ 2009-06-06 20:36 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

On Samstag, 6. Juni 2009, Thomas Rast wrote:
> +void die_errno(const char *err, ...)
> +{
> +	va_list params;
> +	char msg[1024];
> +
> +	va_start(params, err);
> +
> +	vsnprintf(msg, sizeof(msg), err, params);
> +	die("%s: %s", msg, strerror(errno));

Cannot vsnprintf potentially modify errno?

> +
> +	va_end(params);

This va_end should better be before die().

-- Hannes

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 20:36       ` Johannes Sixt
@ 2009-06-06 20:56         ` Thomas Rast
  2009-06-06 21:17           ` Johannes Sixt
  2009-06-06 22:47           ` Jeff King
  0 siblings, 2 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 20:56 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

Johannes Sixt wrote:
> On Samstag, 6. Juni 2009, Thomas Rast wrote:
> > +void die_errno(const char *err, ...)
> > +{
> > +	va_list params;
> > +	char msg[1024];
> > +
> > +	va_start(params, err);
> > +
> > +	vsnprintf(msg, sizeof(msg), err, params);
> > +	die("%s: %s", msg, strerror(errno));
> 
> Cannot vsnprintf potentially modify errno?

Manpage turns up nothing, so AFAICT, no.

> > +
> > +	va_end(params);
> 
> This va_end should better be before die().

Not that I object to changing it, but out of curiosity, what do I
break by putting it after?

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls
  2009-06-06 14:44     ` [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
@ 2009-06-06 21:02       ` Johannes Sixt
  2009-06-06 22:27         ` Thomas Rast
  0 siblings, 1 reply; 42+ messages in thread
From: Johannes Sixt @ 2009-06-06 21:02 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

On Samstag, 6. Juni 2009, Thomas Rast wrote:
> Lots of die() calls did not actually report the kind of error, which
> can leave the user confused as to the real problem.  Use die_errno()
> where we check a system/library call that sets errno on failure, or
> one of the following that wrap such calls:
>
>   Function              Passes on error from
>   --------              --------------------
>   odb_pack_keep         open
>   read_ancestry         fopen
>   read_in_full          xread
>   strbuf_read           xread
>   strbuf_read_file      open or strbuf_read_file
>   strbuf_readlink       readlink
>   write_in_full         xwrite
>
> Signed-off-by: Thomas Rast <trast@student.ethz.ch>
> ---

> @@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char
> *prefix)
>
>  	if (revs_file && read_ancestry(revs_file))
>  		die_errno("reading graft file '%s' failed", revs_file);
> -
>  	if (cmd_is_annotate) {
>  		output_option |= OUTPUT_ANNOTATE_COMPAT;
>  		blame_date_mode = DATE_ISO8601;

Unrelated and not an improvement.

> @@ -220,13 +220,12 @@ static void copy_or_link_directory(struct strbuf
> *src, struct strbuf *dest)
>
>  	dir = opendir(src->buf);
>  	if (!dir)
> -		die("failed to open %s", src->buf);
> -
> +		die_errno("failed to open '%s'", src->buf);

Here (and in other cases) you remote an empty line. I don't think that is an 
improvement.

> @@ -472,7 +472,6 @@ static int prepare_to_commit(const char *index_file,
> const char *prefix) fp = fopen(git_path(commit_editmsg), "w");
>  	if (fp == NULL)
>  		die_errno("could not open '%s'", git_path(commit_editmsg));
> -
>  	if (cleanup_mode != CLEANUP_NONE)
>  		stripspace(&sb, 0);
>

Unrelated.

> @@ -496,7 +495,6 @@ static int prepare_to_commit(const char *index_file,
> const char *prefix)
>
>  	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
>  		die_errno("could not write commit template");
> -
>  	strbuf_release(&sb);
>
>  	determine_author_info();

Ditto.

> @@ -1018,8 +1017,10 @@ int cmd_commit(int argc, const char **argv, const
> char *prefix)
>
>  	if (commit_index_files())
>  		die ("Repository has been updated, but unable to write\n"
> -		     "new_index file. Check that disk is not full or quota is\n"
> -		     "not exceeded, and then \"git reset HEAD\" to recover.");
> +		     "new_index file: %s.\n"
> +		     "Check that disk is not full or quota is not exceeded,\n"
> +		     "and then \"git reset HEAD\" to recover.",
> +		     strerror(errno));

This change should probably not be in this patch.

> @@ -452,7 +452,6 @@ static void import_marks(char *input_file)
>  	FILE *f = fopen(input_file, "r");
>  	if (!f)
>  		die_errno("cannot read '%s'", input_file);
> -
>  	while (fgets(line, sizeof(line), f)) {
>  		uint32_t mark;
>  		char *line_end, *mark_end;

Unrelated.

> diff --git a/csum-file.c b/csum-file.c
> index 9cc93ba..4d50cc5 100644
> --- a/csum-file.c
> +++ b/csum-file.c
> @@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result,
> unsigned int flags) if (flags & CSUM_FSYNC)
>  			fsync_or_die(f->fd, f->name);
>  		if (close(f->fd))
> -			die_errno("%s: sha1 file error on close",
> -			    f->name);
> +			die_errno("%s: sha1 file error on close", f->name);

This should be in 2/3.

-- Hannes

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 20:56         ` Thomas Rast
@ 2009-06-06 21:17           ` Johannes Sixt
  2009-06-06 22:47           ` Jeff King
  1 sibling, 0 replies; 42+ messages in thread
From: Johannes Sixt @ 2009-06-06 21:17 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

On Samstag, 6. Juni 2009, Thomas Rast wrote:
> Johannes Sixt wrote:
> > On Samstag, 6. Juni 2009, Thomas Rast wrote:
> > > +
> > > +	va_end(params);
> >
> > This va_end should better be before die().
>
> Not that I object to changing it, but out of curiosity, what do I
> break by putting it after?

I don't know, and I suspect that in practice nothing breaks. It's just a 
matter of style: va_start acquires a "resource", and va_end releases it, and 
you should do that as soon as possible after the "resource" is no longer 
needed.

-- Hannes

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH] diesys calls die and also reports strerror(errno)
  2009-06-05  7:12         ` Junio C Hamano
@ 2009-06-06 22:09           ` Jeff King
  0 siblings, 0 replies; 42+ messages in thread
From: Jeff King @ 2009-06-06 22:09 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Johannes Sixt, Alexander Potashev, Git Mailing List, Thomas Rast

On Fri, Jun 05, 2009 at 12:12:34AM -0700, Junio C Hamano wrote:

> > Am I the only one who thinks that 'die_errno' would be a better name for
> > this function?
> 
> You are not alone.  I did find diesys() unreadable, but simply did not
> think of an obviously better alternative like you did.

It was meant to be "die with system error code". But given two votes
(and an implicit one from Thomas in his code), I am fine with die_errno.

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 14:44     ` [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
  2009-06-06 20:36       ` Johannes Sixt
@ 2009-06-06 22:13       ` Jeff King
  2009-06-07 11:12         ` Alexander Potashev
  1 sibling, 1 reply; 42+ messages in thread
From: Jeff King @ 2009-06-06 22:13 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Johannes Sixt, Alexander Potashev

On Sat, Jun 06, 2009 at 04:44:51PM +0200, Thomas Rast wrote:

> Code by Jeff King and Alexander Potashev, name by Johannes Sixt.
> [...]
> +void die_errno(const char *err, ...)
> +{
> +	va_list params;
> +	char msg[1024];
> +
> +	va_start(params, err);
> +
> +	vsnprintf(msg, sizeof(msg), err, params);
> +	die("%s: %s", msg, strerror(errno));
> +
> +	va_end(params);
> +}
> +

No, this approach is much more elegant than what I posted, so no need to
credit me, at least. ;)

I do agree with Johannes, though. Style-wise, it reads much better as:

  va_start(params, err);
  vsnprintf(msg, sizeof(msg), err, params);
  va_end(params);

  die("%s: %s", msg, strerror(errno));

since you can more easily see that params isn't leaked (and that die,
which doesn't return, is the _last_ thing called).

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls
  2009-06-06 21:02       ` Johannes Sixt
@ 2009-06-06 22:27         ` Thomas Rast
  0 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-06 22:27 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Junio C Hamano, git, Jeff King, Alexander Potashev

Johannes Sixt wrote:
> > @@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char
> > *prefix)
> >
> >  	if (revs_file && read_ancestry(revs_file))
> >  		die_errno("reading graft file '%s' failed", revs_file);
> > -
> >  	if (cmd_is_annotate) {
> >  		output_option |= OUTPUT_ANNOTATE_COMPAT;
> >  		blame_date_mode = DATE_ISO8601;
> 
> Unrelated and not an improvement.

I used an Emacs macro to turn the die(..., strerror(errno)) [that I
had from v1] into die_errno, and obviously something went terribly
wrong _and_ I missed it.  Sorry :-(

I'll make a new version tomorrow.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 20:56         ` Thomas Rast
  2009-06-06 21:17           ` Johannes Sixt
@ 2009-06-06 22:47           ` Jeff King
  1 sibling, 0 replies; 42+ messages in thread
From: Jeff King @ 2009-06-06 22:47 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Johannes Sixt, Junio C Hamano, git, Alexander Potashev

On Sat, Jun 06, 2009 at 10:56:31PM +0200, Thomas Rast wrote:

> > Cannot vsnprintf potentially modify errno?
> 
> Manpage turns up nothing, so AFAICT, no.

POSIX seems to imply that it can:

  http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html

though it looks like the conditions are fairly unlikely.

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno)  to die()
  2009-06-06 22:13       ` Jeff King
@ 2009-06-07 11:12         ` Alexander Potashev
  2009-06-07 16:57           ` Junio C Hamano
  0 siblings, 1 reply; 42+ messages in thread
From: Alexander Potashev @ 2009-06-07 11:12 UTC (permalink / raw)
  To: Jeff King; +Cc: Thomas Rast, Junio C Hamano, git, Johannes Sixt, Petr Baudis

2009/6/7 Jeff King <peff@peff.net>:
> On Sat, Jun 06, 2009 at 04:44:51PM +0200, Thomas Rast wrote:
>
>> Code by Jeff King and Alexander Potashev, name by Johannes Sixt.
>> [...]
>> +void die_errno(const char *err, ...)
>> +{
>> +     va_list params;
>> +     char msg[1024];
>> +
>> +     va_start(params, err);
>> +
>> +     vsnprintf(msg, sizeof(msg), err, params);
>> +     die("%s: %s", msg, strerror(errno));
>> +
>> +     va_end(params);
>> +}
>> +

This breaks theoretical usage of custom format string in custom die
routines:
        1. A custom die routine might not support %s.
        2. If the die routine adds a custom format specifier, vsnprintf
                will fail.

But I'm not sure that passing a format string and a va_list to
die_routine/error_routine/warn_routine is really necessary. If there
is no much external code depending on them, I would convert them to the
style of usage_routine:
        void (*usage_routine)(const char *err)

CC'ing Petr Baudis <pasky@suse.cz>, see commit 39a3f5ea


>
> No, this approach is much more elegant than what I posted, so no need to
> credit me, at least. ;)

It was your idea of using 1024-character buffer here ;)


                                        Alexander

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno)  to die()
  2009-06-07 11:12         ` Alexander Potashev
@ 2009-06-07 16:57           ` Junio C Hamano
  2009-06-08 12:36             ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Junio C Hamano @ 2009-06-07 16:57 UTC (permalink / raw)
  To: Alexander Potashev
  Cc: Jeff King, Thomas Rast, Junio C Hamano, git, Johannes Sixt, Petr Baudis

Alexander Potashev <aspotashev@gmail.com> writes:

> This breaks theoretical usage of custom format string in custom die
> routines:
>         1. A custom die routine might not support %s.
>         2. If the die routine adds a custom format specifier, vsnprintf
>                 will fail.

I do not think that flies even as a theory.  The "custom" 39a3f5ea talks
about is more about "Instead of sending it to stderr, let's pop up an info
window and give the message there" kind of customization.

Existing die() that prints errno does so by giving strerror() to "%s", so
no matter how custom your die routine is, you must support '%s' for its
output to make sense to humans.  If you "not support %s", then you will
ignore (or choke at) such strerror() result without this patch anyway.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno)  to die()
  2009-06-07 16:57           ` Junio C Hamano
@ 2009-06-08 12:36             ` Jeff King
  2009-06-08 15:35               ` Alexander Potashev
  0 siblings, 1 reply; 42+ messages in thread
From: Jeff King @ 2009-06-08 12:36 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: Alexander Potashev, Thomas Rast, git, Johannes Sixt, Petr Baudis

On Sun, Jun 07, 2009 at 09:57:04AM -0700, Junio C Hamano wrote:

> > This breaks theoretical usage of custom format string in custom die
> > routines:
> >         1. A custom die routine might not support %s.
> >         2. If the die routine adds a custom format specifier, vsnprintf
> >                 will fail.
> 
> I do not think that flies even as a theory.  The "custom" 39a3f5ea talks
> about is more about "Instead of sending it to stderr, let's pop up an info
> window and give the message there" kind of customization.
> 
> Existing die() that prints errno does so by giving strerror() to "%s", so
> no matter how custom your die routine is, you must support '%s' for its
> output to make sense to humans.  If you "not support %s", then you will
> ignore (or choke at) such strerror() result without this patch anyway.

More than that, you must support arbitrary printf format strings,
because the die routine is passed whatever goes to die() (a quick grep
revealed that we use at least %u and %c at various points). So it is an
undocumented requirement that the die routine process its parameters as
if it were from the printf family.

I think what Thomas posted is fine.

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno)  to die()
  2009-06-08 12:36             ` Jeff King
@ 2009-06-08 15:35               ` Alexander Potashev
  2009-06-08 22:04                 ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Alexander Potashev @ 2009-06-08 15:35 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Thomas Rast, git, Johannes Sixt, Petr Baudis

2009/6/8 Jeff King <peff@peff.net>:
> On Sun, Jun 07, 2009 at 09:57:04AM -0700, Junio C Hamano wrote:
>
>> > This breaks theoretical usage of custom format string in custom die
>> > routines:
>> >         1. A custom die routine might not support %s.
>> >         2. If the die routine adds a custom format specifier, vsnprintf
>> >                 will fail.
>>
>> I do not think that flies even as a theory.  The "custom" 39a3f5ea talks
>> about is more about "Instead of sending it to stderr, let's pop up an info
>> window and give the message there" kind of customization.
>>
>> Existing die() that prints errno does so by giving strerror() to "%s", so
>> no matter how custom your die routine is, you must support '%s' for its
>> output to make sense to humans.  If you "not support %s", then you will
>> ignore (or choke at) such strerror() result without this patch anyway.
>
> More than that, you must support arbitrary printf format strings,
> because the die routine is passed whatever goes to die() (a quick grep
> revealed that we use at least %u and %c at various points). So it is an
> undocumented requirement that the die routine process its parameters as
> if it were from the printf family.

Your last statement is not quite true. A custom die routine may
support all printf specifiers and some additional ones, but Thomas'
die_errno passes the format string (and arguments list) to vsnprintf
anyway, so the additional specifiers would be lost.

>
> I think what Thomas posted is fine.
>
> -Peff
>

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v3 0/3] die_errno()
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
@ 2009-06-08 21:02       ` Thomas Rast
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-08 21:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

First off, thanks for the extensive review and discussion...

[1/3] I changed the snprintf handling to tack the error onto the
  format and pass that to die_routine().  I still think it's crazy to
  invent new format characters, but who knows.

[2/3] Fixed as per Johannes Sixt's comments.

[3/3] Removed the terrible empty-lines mess caused by pilot error.

  Johannes Sixt wrote:
  > > @@ -1018,8 +1017,10 @@ int cmd_commit(int argc, const char **argv, const
  > > char *prefix)
  > >
  > >  	if (commit_index_files())
  > >  		die ("Repository has been updated, but unable to write\n"
  > > -		     "new_index file. Check that disk is not full or quota is\n"
  > > -		     "not exceeded, and then \"git reset HEAD\" to recover.");
  > > +		     "new_index file: %s.\n"
  > > +		     "Check that disk is not full or quota is not exceeded,\n"
  > > +		     "and then \"git reset HEAD\" to recover.",
  > > +		     strerror(errno));
  > 
  > This change should probably not be in this patch.

  Removed...  I'm not enough of an expert to say if
  commit_index_files() can only fail because the disk is full, so I
  figured it would still be an improvement to show the real error.

  If you just meant that it should go in a separate patch because it's
  not a die->die_errno change, I can do that, it just feels like
  overkill because it is morally the same change, but in a case where
  I cannot apply the die_errno shortcut.


Thomas Rast (3):
  Introduce die_errno() that appends strerror(errno) to die()
  Convert existing die(..., strerror(errno)) to die_errno()
  Use die_errno() instead of die() when checking syscalls

 abspath.c                |   12 ++++++------
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-add.c            |    2 +-
 builtin-apply.c          |   12 ++++++------
 builtin-archive.c        |    4 ++--
 builtin-blame.c          |   15 +++++++--------
 builtin-clone.c          |   21 ++++++++++-----------
 builtin-commit-tree.c    |    2 +-
 builtin-commit.c         |   28 +++++++++++++---------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    4 ++--
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    5 ++---
 builtin-fsck.c           |   10 +++++-----
 builtin-grep.c           |    2 +-
 builtin-init-db.c        |   21 +++++++++++----------
 builtin-log.c            |    4 ++--
 builtin-mailsplit.c      |    6 +++---
 builtin-merge.c          |   29 ++++++++++++++++-------------
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rev-parse.c      |    2 +-
 builtin-revert.c         |    2 +-
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-stripspace.c     |    2 +-
 builtin-tag.c            |    9 ++++-----
 builtin-tar-tree.c       |    2 +-
 builtin-unpack-objects.c |    2 +-
 combine-diff.c           |    2 +-
 csum-file.c              |    5 ++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |   10 +++++-----
 dir.c                    |    2 +-
 entry.c                  |   10 +++++-----
 fast-import.c            |    8 ++++----
 git-compat-util.h        |    1 +
 git.c                    |    6 +++---
 hash-object.c            |    2 +-
 index-pack.c             |   21 ++++++++++-----------
 ll-merge.c               |    2 +-
 merge-recursive.c        |    6 +++---
 mktag.c                  |    2 +-
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    8 ++++----
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |   18 +++++++++---------
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 transport.c              |    4 ++--
 unpack-file.c            |    2 +-
 usage.c                  |   12 ++++++++++++
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 60 files changed, 209 insertions(+), 207 deletions(-)

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 0/3] die_errno() Thomas Rast
@ 2009-06-08 21:02       ` Thomas Rast
  2009-06-08 22:07         ` Jeff King
  2009-06-08 21:02       ` [PATCH v3 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
  3 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-08 21:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

There are many calls to die() that do, or should, report
strerror(errno) to indicate how the syscall they guard failed.
Introduce a small helper function for this case.

Note:

- POSIX says vsnprintf can modify errno in some unlikely cases, so we
  have to use errno early.

- We take some care to pass the original format to die_routine(), in
  case someone wants to call die_errno() with custom format
  characters.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 git-compat-util.h |    1 +
 usage.c           |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index f25f7f1..0366cde 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -162,6 +162,7 @@
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
diff --git a/usage.c b/usage.c
index 820d09f..fd936a1 100644
--- a/usage.c
+++ b/usage.c
@@ -60,6 +60,18 @@ void die(const char *err, ...)
 	va_end(params);
 }
 
+void die_errno(const char *fmt, ...)
+{
+	va_list params;
+	char fmt_with_err[1024];
+
+	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, strerror(errno));
+
+	va_start(params, fmt);
+	die_routine(fmt_with_err, params);
+	va_end(params);
+}
+
 int error(const char *err, ...)
 {
 	va_list params;
-- 
1.6.3.2.333.g27636

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v3 2/3] Convert existing die(..., strerror(errno)) to die_errno()
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 0/3] die_errno() Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
@ 2009-06-08 21:02       ` Thomas Rast
  2009-06-08 21:02       ` [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
  3 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-08 21:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

Change calls to die(..., strerror(errno)) to use the new die_errno().

In the process, also make slight style adjustments: at least state
_something_ about the function that failed (instead of just printing
the pathname), and put paths in single quotes.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-apply.c          |    6 +++---
 builtin-blame.c          |    7 +++----
 builtin-clone.c          |   11 +++++------
 builtin-commit-tree.c    |    2 +-
 builtin-commit.c         |   23 ++++++++++-------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    2 +-
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    3 +--
 builtin-fsck.c           |    8 ++++----
 builtin-grep.c           |    2 +-
 builtin-merge.c          |    8 ++++----
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-tag.c            |    7 +++----
 builtin-unpack-objects.c |    2 +-
 csum-file.c              |    5 ++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |    4 ++--
 dir.c                    |    2 +-
 entry.c                  |    8 ++++----
 fast-import.c            |    4 ++--
 git.c                    |    6 +++---
 index-pack.c             |   21 ++++++++++-----------
 merge-recursive.c        |    6 +++---
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    6 +++---
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |    8 ++++----
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 42 files changed, 117 insertions(+), 133 deletions(-)

diff --git a/bisect.c b/bisect.c
index c43c120..281e16a 100644
--- a/bisect.c
+++ b/bisect.c
@@ -461,7 +461,7 @@ void read_bisect_paths(struct argv_array *array)
 	FILE *fp = fopen(filename, "r");
 
 	if (!fp)
-		die("Could not open file '%s': %s", filename, strerror(errno));
+		die_errno("Could not open file '%s'", filename);
 
 	while (strbuf_getline(&str, fp, '\n') != EOF) {
 		char *quoted;
@@ -632,8 +632,7 @@ static void mark_expected_rev(char *bisect_rev_hex)
 	int fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 
 	if (fd < 0)
-		die("could not create file '%s': %s",
-		    filename, strerror(errno));
+		die_errno("could not create file '%s'", filename);
 
 	bisect_rev_hex[len] = '\n';
 	write_or_die(fd, bisect_rev_hex, len + 1);
diff --git a/branch.c b/branch.c
index 62030af..05ef3f5 100644
--- a/branch.c
+++ b/branch.c
@@ -172,7 +172,7 @@ void create_branch(const char *head,
 
 	lock = lock_any_ref_for_update(ref.buf, NULL, 0);
 	if (!lock)
-		die("Failed to lock ref for update: %s.", strerror(errno));
+		die_errno("Failed to lock ref for update");
 
 	if (reflog)
 		log_all_ref_updates = 1;
@@ -188,7 +188,7 @@ void create_branch(const char *head,
 		setup_tracking(name, real_ref, track);
 
 	if (write_ref_sha1(lock, sha1, msg) < 0)
-		die("Failed to write ref: %s.", strerror(errno));
+		die_errno("Failed to write ref");
 
 	strbuf_release(&ref);
 	free(real_ref);
diff --git a/builtin-apply.c b/builtin-apply.c
index 94ba2bd..6526c08 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,
 static void read_patch_file(struct strbuf *sb, int fd)
 {
 	if (strbuf_read(sb, fd, 0) < 0)
-		die("git apply: read returned %s", strerror(errno));
+		die_errno("git apply: failed to read");
 
 	/*
 	 * Make sure that we have some slop in the buffer
@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 	strbuf_release(&nbuf);
 
 	if (close(fd) < 0)
-		die("closing file %s: %s", path, strerror(errno));
+		die_errno("closing file '%s'", path);
 	return 0;
 }
 
@@ -3354,7 +3354,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 
 		fd = open(arg, O_RDONLY);
 		if (fd < 0)
-			die("can't open patch '%s': %s", arg, strerror(errno));
+			die_errno("can't open patch '%s'", arg);
 		read_stdin = 0;
 		set_default_whitespace_mode(whitespace_option);
 		errs |= apply_patch(fd, arg, options);
diff --git a/builtin-blame.c b/builtin-blame.c
index 0c2d29a..7d8fbd5 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2035,7 +2035,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 		contents_from = "standard input";
 		mode = 0;
 		if (strbuf_read(&buf, 0, 0) < 0)
-			die("read error %s from stdin", strerror(errno));
+			die_errno("failed to read from stdin");
 	}
 	convert_to_git(path, buf.buf, buf.len, &buf, 0);
 	origin->file.ptr = buf.buf;
@@ -2261,8 +2261,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 	argc = parse_options_end(&ctx);
 
 	if (revs_file && read_ancestry(revs_file))
-		die("reading graft file %s failed: %s",
-		    revs_file, strerror(errno));
+		die_errno("reading graft file '%s' failed", revs_file);
 
 	if (cmd_is_annotate) {
 		output_option |= OUTPUT_ANNOTATE_COMPAT;
@@ -2350,7 +2349,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 
 		setup_work_tree();
 		if (!has_string_in_work_tree(path))
-			die("cannot stat path %s: %s", path, strerror(errno));
+			die_errno("cannot stat path '%s'", path);
 	}
 
 	setup_revisions(argc, argv, &revs, NULL);
diff --git a/builtin-clone.c b/builtin-clone.c
index 5c46496..5f34414 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -252,8 +252,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 		}
 
 		if (unlink(dest->buf) && errno != ENOENT)
-			die("failed to unlink %s: %s",
-			    dest->buf, strerror(errno));
+			die_errno("failed to unlink '%s'", dest->buf);
 		if (!option_no_hardlinks) {
 			if (!link(src->buf, dest->buf))
 				continue;
@@ -420,11 +419,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (!option_bare) {
 		junk_work_tree = work_tree;
 		if (safe_create_leading_directories_const(work_tree) < 0)
-			die("could not create leading directories of '%s': %s",
-					work_tree, strerror(errno));
+			die_errno("could not create leading directories of '%s'",
+				  work_tree);
 		if (!dest_exists && mkdir(work_tree, 0755))
-			die("could not create work tree dir '%s': %s.",
-					work_tree, strerror(errno));
+			die_errno("could not create work tree dir '%s'.",
+				  work_tree);
 		set_git_work_tree(work_tree);
 	}
 	junk_git_dir = git_dir;
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 0453425..6467077 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -124,7 +124,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&buffer, 0, 0) < 0)
-		die("git commit-tree: read returned %s", strerror(errno));
+		die_errno("git commit-tree: failed to read");
 
 	if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
 		printf("%s\n", sha1_to_hex(commit_sha1));
diff --git a/builtin-commit.c b/builtin-commit.c
index 41e222d..88c51bd 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -438,8 +438,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
-			die("could not read log file '%s': %s",
-			    logfile, strerror(errno));
+			die_errno("could not read log file '%s'",
+				  logfile);
 		hook_arg1 = "message";
 	} else if (use_message) {
 		buffer = strstr(use_message_buffer, "\n\n");
@@ -450,16 +450,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg2 = use_message;
 	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
-			die("could not read MERGE_MSG: %s", strerror(errno));
+			die_errno("could not read MERGE_MSG");
 		hook_arg1 = "merge";
 	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
-			die("could not read SQUASH_MSG: %s", strerror(errno));
+			die_errno("could not read SQUASH_MSG");
 		hook_arg1 = "squash";
 	} else if (template_file && !stat(template_file, &statbuf)) {
 		if (strbuf_read_file(&sb, template_file, 0) < 0)
-			die("could not read %s: %s",
-			    template_file, strerror(errno));
+			die_errno("could not read '%s'", template_file);
 		hook_arg1 = "template";
 	}
 
@@ -472,8 +471,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
 	fp = fopen(git_path(commit_editmsg), "w");
 	if (fp == NULL)
-		die("could not open %s: %s",
-		    git_path(commit_editmsg), strerror(errno));
+		die_errno("could not open '%s'", git_path(commit_editmsg));
 
 	if (cleanup_mode != CLEANUP_NONE)
 		stripspace(&sb, 0);
@@ -497,7 +495,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 	}
 
 	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
-		die("could not write commit template: %s", strerror(errno));
+		die_errno("could not write commit template");
 
 	strbuf_release(&sb);
 
@@ -940,8 +938,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
 		if (fp == NULL)
-			die("could not open %s for reading: %s",
-			    git_path("MERGE_HEAD"), strerror(errno));
+			die_errno("could not open '%s' for reading",
+				  git_path("MERGE_HEAD"));
 		while (strbuf_getline(&m, fp, '\n') != EOF) {
 			unsigned char sha1[20];
 			if (get_sha1_hex(m.buf, sha1) < 0)
@@ -952,8 +950,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		strbuf_release(&m);
 		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
 			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
-				die("could not read MERGE_MODE: %s",
-						strerror(errno));
+				die_errno("could not read MERGE_MODE");
 			if (!strcmp(sb.buf, "no-ff"))
 				allow_fast_forward = 0;
 		}
diff --git a/builtin-config.c b/builtin-config.c
index 60915f9..a2d656e 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -383,8 +383,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix)
 		check_argc(argc, 0, 0);
 		if (git_config(show_all_config, NULL) < 0) {
 			if (config_exclusive_filename)
-				die("unable to read config file %s: %s",
-				    config_exclusive_filename, strerror(errno));
+				die_errno("unable to read config file '%s'",
+					  config_exclusive_filename);
 			else
 				die("error processing config file(s)");
 		}
diff --git a/builtin-diff.c b/builtin-diff.c
index d75d69b..2e51f40 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -70,7 +70,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
 		usage(builtin_diff_usage);
 
 	if (lstat(path, &st))
-		die("'%s': %s", path, strerror(errno));
+		die_errno("failed to stat '%s'", path);
 	if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
 		die("'%s': not a regular file or symlink", path);
 
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 6cef810..333d438 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -451,7 +451,7 @@ static void import_marks(char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 
 	while (fgets(line, sizeof(line), f)) {
 		uint32_t mark;
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 29356d2..3dbdf7a 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -8,7 +8,7 @@
 {
 	struct strbuf buf = STRBUF_INIT;
 	if (strbuf_read(&buf, 0, 1024) < 0) {
-		die("error reading standard input: %s", strerror(errno));
+		die_errno("error reading standard input");
 	}
 	return strbuf_detach(&buf, NULL);
 }
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index fbf9582..1248d5e 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -372,8 +372,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
-		die("could not read input file %s", strerror(errno));
-
+		die_errno("could not read input file");
 	ret = fmt_merge_msg(merge_summary, &input, &output);
 	if (ret)
 		return ret;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 7da706c..a49dbe1 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -225,15 +225,15 @@ static void check_unreachable_object(struct object *obj)
 						&type, &size);
 				if (buf) {
 					if (fwrite(buf, size, 1, f) != 1)
-						die("Could not write %s: %s",
-						    filename, strerror(errno));
+						die_errno("Could not write '%s'",
+							  filename);
 					free(buf);
 				}
 			} else
 				fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
 			if (fclose(f))
-				die("Could not finish %s: %s",
-				    filename, strerror(errno));
+				die_errno("Could not finish '%s'",
+					  filename);
 		}
 		return;
 	}
diff --git a/builtin-grep.c b/builtin-grep.c
index 73fc922..e558368 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -594,7 +594,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
 
 	patterns = fopen(arg, "r");
 	if (!patterns)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("cannot open '%s'", arg);
 	while (strbuf_getline(&sb, patterns, '\n') == 0) {
 		/* ignore empty line like grep does */
 		if (sb.len == 0)
diff --git a/builtin-merge.c b/builtin-merge.c
index 8d101ef..436263b 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -294,9 +294,9 @@ static void squash_message(void)
 			NULL, NULL, rev.date_mode, 0);
 	}
 	if (write(fd, out.buf, out.len) < 0)
-		die("Writing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Writing SQUASH_MSG");
 	if (close(fd))
-		die("Finishing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Finishing SQUASH_MSG");
 	strbuf_release(&out);
 }
 
@@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct strbuf *msg)
 
 		fp = fopen(git_path("FETCH_HEAD"), "r");
 		if (!fp)
-			die("could not open %s for reading: %s",
-				git_path("FETCH_HEAD"), strerror(errno));
+			die_errno("could not open '%s' for reading",
+				  git_path("FETCH_HEAD"));
 		strbuf_getline(&line, fp, '\n');
 		fclose(fp);
 		ptr = strstr(line.buf, "\tnot-for-merge\t");
diff --git a/builtin-mv.c b/builtin-mv.c
index 8b81d4b..024dfeb 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -209,7 +209,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 			printf("Renaming %s to %s\n", src, dst);
 		if (!show_only && mode != INDEX &&
 				rename(src, dst) < 0 && !ignore_errors)
-			die ("renaming %s failed: %s", src, strerror(errno));
+			die_errno ("renaming '%s' failed", src);
 
 		if (mode == WORKING_DIRECTORY)
 			continue;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 9742b45..60355d4 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -536,11 +536,9 @@ static void write_pack_file(void)
 				 base_name, sha1_to_hex(sha1));
 			free_pack_by_name(tmpname);
 			if (adjust_perm(pack_tmp_name, mode))
-				die("unable to make temporary pack file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary pack file readable");
 			if (rename(pack_tmp_name, tmpname))
-				die("unable to rename temporary pack file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary pack file");
 
 			/*
 			 * Packs are runtime accessed in their mtime
@@ -566,11 +564,9 @@ static void write_pack_file(void)
 			snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
 				 base_name, sha1_to_hex(sha1));
 			if (adjust_perm(idx_tmp_name, mode))
-				die("unable to make temporary index file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary index file readable");
 			if (rename(idx_tmp_name, tmpname))
-				die("unable to rename temporary index file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary index file");
 
 			free(idx_tmp_name);
 			free(pack_tmp_name);
@@ -1880,7 +1876,7 @@ static void read_object_list_from_stdin(void)
 			if (!ferror(stdin))
 				die("fgets returned NULL, not EOF, not error!");
 			if (errno != EINTR)
-				die("fgets: %s", strerror(errno));
+				die_errno("fgets");
 			clearerr(stdin);
 			continue;
 		}
diff --git a/builtin-rm.c b/builtin-rm.c
index 0cc4912..57975db 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -257,7 +257,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 				continue;
 			}
 			if (!removed)
-				die("git rm: %s: %s", path, strerror(errno));
+				die_errno("git rm: '%s'", path);
 		}
 	}
 
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index be3b092..8fe5ab9 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -59,7 +59,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
 	po.out = fd;
 	po.git_cmd = 1;
 	if (start_command(&po))
-		die("git pack-objects failed (%s)", strerror(errno));
+		die_errno("git pack-objects failed");
 
 	/*
 	 * We feed the pack-objects we just spawned with revision
diff --git a/builtin-tag.c b/builtin-tag.c
index dc3db62..7b51095 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -308,8 +308,7 @@ static void create_tag(const unsigned char *object, const char *tag,
 		path = git_pathdup("TAG_EDITMSG");
 		fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 		if (fd < 0)
-			die("could not create file '%s': %s",
-						path, strerror(errno));
+			die_errno("could not create file '%s'", path);
 
 		if (!is_null_sha1(prev))
 			write_tag_body(fd, prev);
@@ -446,8 +445,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 					die("cannot read %s", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
-					die("could not open or read '%s': %s",
-						msgfile, strerror(errno));
+					die_errno("could not open or read '%s'",
+						msgfile);
 			}
 		}
 	}
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 9a77323..41e9ac5 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -68,7 +68,7 @@ static void add_object_buffer(struct object *object, char *buffer, unsigned long
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		len += ret;
 	} while (len < min);
diff --git a/csum-file.c b/csum-file.c
index 2ddb12a..4d50cc5 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -26,7 +26,7 @@ static void flush(struct sha1file *f, void * buf, unsigned int count)
 		}
 		if (!ret)
 			die("sha1 file '%s' write error. Out of diskspace", f->name);
-		die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
+		die_errno("sha1 file '%s' write error", f->name);
 	}
 }
 
@@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 		if (flags & CSUM_FSYNC)
 			fsync_or_die(f->fd, f->name);
 		if (close(f->fd))
-			die("%s: sha1 file error on close (%s)",
-			    f->name, strerror(errno));
+			die_errno("%s: sha1 file error on close", f->name);
 		fd = 0;
 	} else
 		fd = f->fd;
diff --git a/daemon.c b/daemon.c
index b2babcc..0c2f326 100644
--- a/daemon.c
+++ b/daemon.c
@@ -862,7 +862,7 @@ static int service_loop(int socknum, int *socklist)
 					case ECONNABORTED:
 						continue;
 					default:
-						die("accept returned %s", strerror(errno));
+						die_errno("accept returned");
 					}
 				}
 				handle(incoming, (struct sockaddr *)&ss, sslen);
@@ -878,7 +878,7 @@ static void sanitize_stdfds(void)
 	while (fd != -1 && fd < 2)
 		fd = dup(fd);
 	if (fd == -1)
-		die("open /dev/null or dup failed: %s", strerror(errno));
+		die_errno("open /dev/null or dup failed");
 	if (fd > 2)
 		close(fd);
 }
@@ -889,12 +889,12 @@ static void daemonize(void)
 		case 0:
 			break;
 		case -1:
-			die("fork failed: %s", strerror(errno));
+			die_errno("fork failed");
 		default:
 			exit(0);
 	}
 	if (setsid() == -1)
-		die("setsid failed: %s", strerror(errno));
+		die_errno("setsid failed");
 	close(0);
 	close(1);
 	close(2);
@@ -905,9 +905,9 @@ static void store_pid(const char *path)
 {
 	FILE *f = fopen(path, "w");
 	if (!f)
-		die("cannot open pid file %s: %s", path, strerror(errno));
+		die_errno("cannot open pid file '%s'", path);
 	if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
-		die("failed to write pid file %s: %s", path, strerror(errno));
+		die_errno("failed to write pid file '%s'", path);
 }
 
 static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
@@ -1107,8 +1107,7 @@ int main(int argc, char **argv)
 		socklen_t slen = sizeof(ss);
 
 		if (!freopen("/dev/null", "w", stderr))
-			die("failed to redirect stderr to /dev/null: %s",
-			    strerror(errno));
+			die_errno("failed to redirect stderr to /dev/null");
 
 		if (getpeername(0, peer, &slen))
 			peer = NULL;
diff --git a/diff.c b/diff.c
index 4d0a5b9..48043f5 100644
--- a/diff.c
+++ b/diff.c
@@ -1975,7 +1975,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 	fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,
 			strlen(base) + 1);
 	if (fd < 0)
-		die("unable to create temp-file: %s", strerror(errno));
+		die_errno("unable to create temp-file");
 	if (convert_to_working_tree(path,
 			(const char *)blob, (size_t)size, &buf)) {
 		blob = buf.buf;
@@ -2021,7 +2021,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (lstat(name, &st) < 0) {
 			if (errno == ENOENT)
 				goto not_a_valid_file;
-			die("stat(%s): %s", name, strerror(errno));
+			die_errno("stat(%s)", name);
 		}
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
diff --git a/dir.c b/dir.c
index bbfcb56..74b3bbf 100644
--- a/dir.c
+++ b/dir.c
@@ -759,7 +759,7 @@ int file_exists(const char *f)
 	if (!dir)
 		return NULL;
 	if (!getcwd(buffer, size))
-		die("can't find the current directory: %s", strerror(errno));
+		die_errno("can't find the current directory");
 
 	if (!is_absolute_path(dir))
 		dir = make_absolute_path(dir);
diff --git a/entry.c b/entry.c
index cc841ed..8ec880b 100644
--- a/entry.c
+++ b/entry.c
@@ -51,7 +51,7 @@ static void remove_subtree(const char *path)
 	char *name;
 
 	if (!dir)
-		die("cannot opendir %s (%s)", path, strerror(errno));
+		die_errno("cannot opendir '%s'", path);
 	strcpy(pathbuf, path);
 	name = pathbuf + strlen(path);
 	*name++ = '/';
@@ -61,15 +61,15 @@ static void remove_subtree(const char *path)
 			continue;
 		strcpy(name, de->d_name);
 		if (lstat(pathbuf, &st))
-			die("cannot lstat %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot lstat '%s'", pathbuf);
 		if (S_ISDIR(st.st_mode))
 			remove_subtree(pathbuf);
 		else if (unlink(pathbuf))
-			die("cannot unlink %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot unlink '%s'", pathbuf);
 	}
 	closedir(dir);
 	if (rmdir(path))
-		die("cannot rmdir %s (%s)", path, strerror(errno));
+		die_errno("cannot rmdir '%s'", path);
 }
 
 static int create_file(const char *path, unsigned int mode)
diff --git a/fast-import.c b/fast-import.c
index a2a2458..d31a4e8 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2342,7 +2342,7 @@ static void import_marks(const char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 	while (fgets(line, sizeof(line), f)) {
 		uintmax_t mark;
 		char *end;
@@ -2448,7 +2448,7 @@ int main(int argc, const char **argv)
 				fclose(pack_edges);
 			pack_edges = fopen(a + 20, "a");
 			if (!pack_edges)
-				die("Cannot open %s: %s", a + 20, strerror(errno));
+				die_errno("Cannot open '%s'", a + 20);
 		} else if (!strcmp(a, "--force"))
 			force_update = 1;
 		else if (!strcmp(a, "--quiet"))
diff --git a/git.c b/git.c
index 7d7f949..b035676 100644
--- a/git.c
+++ b/git.c
@@ -200,7 +200,7 @@ static int handle_alias(int *argcp, const char ***argv)
 	}
 
 	if (subdir && chdir(subdir))
-		die("Cannot change to %s: %s", subdir, strerror(errno));
+		die_errno("Cannot change to '%s'", subdir);
 
 	errno = saved_errno;
 
@@ -257,11 +257,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 
 	/* Check for ENOSPC and EIO errors.. */
 	if (fflush(stdout))
-		die("write failure on standard output: %s", strerror(errno));
+		die_errno("write failure on standard output");
 	if (ferror(stdout))
 		die("unknown write failure on standard output");
 	if (fclose(stdout))
-		die("close failed on standard output: %s", strerror(errno));
+		die_errno("close failed on standard output");
 	return 0;
 }
 
diff --git a/index-pack.c b/index-pack.c
index 6e93ee6..cf6446f 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -143,7 +143,7 @@ static void flush(void)
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		input_len += ret;
 		if (from_stdin)
@@ -178,13 +178,12 @@ static void use(int bytes)
 		} else
 			output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
 		if (output_fd < 0)
-			die("unable to create %s: %s", pack_name, strerror(errno));
+			die_errno("unable to create '%s'", pack_name);
 		pack_fd = output_fd;
 	} else {
 		input_fd = open(pack_name, O_RDONLY);
 		if (input_fd < 0)
-			die("cannot open packfile '%s': %s",
-			    pack_name, strerror(errno));
+			die_errno("cannot open packfile '%s'", pack_name);
 		output_fd = -1;
 		pack_fd = input_fd;
 	}
@@ -370,7 +369,7 @@ static void unlink_base_data(struct base_data *c)
 	do {
 		ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
 		if (n < 0)
-			die("cannot pread pack file: %s", strerror(errno));
+			die_errno("cannot pread pack file");
 		if (!n)
 			die("premature end of pack file, %lu bytes missing",
 			    len - rdy);
@@ -631,7 +630,7 @@ static void parse_pack_objects(unsigned char *sha1)
 
 	/* If input_fd is a file, we should have reached its end now. */
 	if (fstat(input_fd, &st))
-		die("cannot fstat packfile: %s", strerror(errno));
+		die_errno("cannot fstat packfile");
 	if (S_ISREG(st.st_mode) &&
 			lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
 		die("pack has junk at the end");
@@ -788,7 +787,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 		fsync_or_die(output_fd, curr_pack_name);
 		err = close(output_fd);
 		if (err)
-			die("error while closing pack file: %s", strerror(errno));
+			die_errno("error while closing pack file");
 	}
 
 	if (keep_msg) {
@@ -801,16 +800,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 
 		if (keep_fd < 0) {
 			if (errno != EEXIST)
-				die("cannot write keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot write keep file '%s'",
+					  keep_name);
 		} else {
 			if (keep_msg_len > 0) {
 				write_or_die(keep_fd, keep_msg, keep_msg_len);
 				write_or_die(keep_fd, "\n", 1);
 			}
 			if (close(keep_fd) != 0)
-				die("cannot close written keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot close written keep file '%s'",
+				    keep_name);
 			report = "keep";
 		}
 	}
diff --git a/merge-recursive.c b/merge-recursive.c
index f5df9b9..5d9140b 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -438,7 +438,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
 			/* Ignore epipe */
 			if (errno == EPIPE)
 				break;
-			die("merge-recursive: %s", strerror(errno));
+			die_errno("merge-recursive");
 		} else if (!ret) {
 			die("merge-recursive: disk full?");
 		}
@@ -554,7 +554,7 @@ static void update_file_flags(struct merge_options *o,
 				mode = 0666;
 			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
 			if (fd < 0)
-				die("failed to open %s: %s", path, strerror(errno));
+				die_errno("failed to open '%s'", path);
 			flush_buffer(fd, buf, size);
 			close(fd);
 		} else if (S_ISLNK(mode)) {
@@ -562,7 +562,7 @@ static void update_file_flags(struct merge_options *o,
 			safe_create_leading_directories_const(path);
 			unlink(path);
 			if (symlink(lnk, path))
-				die("failed to symlink %s: %s", path, strerror(errno));
+				die_errno("failed to symlink '%s'", path);
 			free(lnk);
 		} else
 			die("do not know what to do with %06o %s '%s'",
diff --git a/pack-refs.c b/pack-refs.c
index 301fc60..7f43f8a 100644
--- a/pack-refs.c
+++ b/pack-refs.c
@@ -93,8 +93,7 @@ int pack_refs(unsigned int flags)
 				       LOCK_DIE_ON_ERROR);
 	cbdata.refs_file = fdopen(fd, "w");
 	if (!cbdata.refs_file)
-		die("unable to create ref-pack file structure (%s)",
-		    strerror(errno));
+		die_errno("unable to create ref-pack file structure");
 
 	/* perhaps other traits later as well */
 	fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
@@ -103,7 +102,7 @@ int pack_refs(unsigned int flags)
 	if (ferror(cbdata.refs_file))
 		die("failed to write ref-pack file");
 	if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
-		die("failed to write ref-pack file (%s)", strerror(errno));
+		die_errno("failed to write ref-pack file");
 	/*
 	 * Since the lock file was fdopen()'ed and then fclose()'ed above,
 	 * assign -1 to the lock file descriptor so that commit_lock_file()
@@ -111,7 +110,7 @@ int pack_refs(unsigned int flags)
 	 */
 	packed.fd = -1;
 	if (commit_lock_file(&packed) < 0)
-		die("unable to overwrite old ref-pack file (%s)", strerror(errno));
+		die_errno("unable to overwrite old ref-pack file");
 	if (cbdata.flags & PACK_REFS_PRUNE)
 		prune_refs(cbdata.ref_to_prune);
 	return 0;
diff --git a/pack-write.c b/pack-write.c
index 7053538..741efcd 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -51,7 +51,7 @@ static int sha1_compare(const void *_a, const void *_b)
 		fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
 	}
 	if (fd < 0)
-		die("unable to create %s: %s", index_name, strerror(errno));
+		die_errno("unable to create '%s'", index_name);
 	f = sha1fd(fd, index_name);
 
 	/* if last object's offset is >= 2^31 we should use index V2 */
@@ -174,11 +174,11 @@ void fixup_pack_header_footer(int pack_fd,
 	git_SHA1_Init(&new_sha1_ctx);
 
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
-		die("Unable to reread header of %s: %s", pack_name, strerror(errno));
+		die_errno("Unable to reread header of '%s'", pack_name);
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	git_SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));
 	hdr.hdr_entries = htonl(object_count);
 	git_SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));
@@ -195,7 +195,7 @@ void fixup_pack_header_footer(int pack_fd,
 		if (!n)
 			break;
 		if (n < 0)
-			die("Failed to checksum %s: %s", pack_name, strerror(errno));
+			die_errno("Failed to checksum '%s'", pack_name);
 		git_SHA1_Update(&new_sha1_ctx, buf, n);
 
 		aligned_sz -= n;
diff --git a/pkt-line.c b/pkt-line.c
index f5d0086..b691abe 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -28,7 +28,7 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
 		}
 		if (!ret)
 			die("write error (disk full?)");
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 	return nn;
 }
@@ -67,7 +67,7 @@ static void safe_read(int fd, void *buffer, unsigned size)
 {
 	ssize_t ret = read_in_full(fd, buffer, size);
 	if (ret < 0)
-		die("read error (%s)", strerror(errno));
+		die_errno("read error");
 	else if (ret < size)
 		die("The remote end hung up unexpectedly");
 }
diff --git a/read-cache.c b/read-cache.c
index 3f58711..f76b5bb 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -638,7 +638,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
 {
 	struct stat st;
 	if (lstat(path, &st))
-		die("%s: unable to stat (%s)", path, strerror(errno));
+		die_errno("unable to stat '%s'", path);
 	return add_to_index(istate, path, &st, flags);
 }
 
@@ -1251,11 +1251,11 @@ int read_index_from(struct index_state *istate, const char *path)
 	if (fd < 0) {
 		if (errno == ENOENT)
 			return 0;
-		die("index file open failed (%s)", strerror(errno));
+		die_errno("index file open failed");
 	}
 
 	if (fstat(fd, &st))
-		die("cannot stat the open index (%s)", strerror(errno));
+		die_errno("cannot stat the open index");
 
 	errno = EINVAL;
 	mmap_size = xsize_t(st.st_size);
diff --git a/refs.c b/refs.c
index 24438c6..dffe395 100644
--- a/refs.c
+++ b/refs.c
@@ -1418,7 +1418,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
 	logfile = git_path("logs/%s", ref);
 	logfd = open(logfile, O_RDONLY, 0);
 	if (logfd < 0)
-		die("Unable to read log %s: %s", logfile, strerror(errno));
+		die_errno("Unable to read log '%s'", logfile);
 	fstat(logfd, &st);
 	if (!st.st_size)
 		die("Log %s is empty.", logfile);
diff --git a/run-command.c b/run-command.c
index eb2efc3..ff3d8e2 100644
--- a/run-command.c
+++ b/run-command.c
@@ -101,8 +101,8 @@ int start_command(struct child_process *cmd)
 		}
 
 		if (cmd->dir && chdir(cmd->dir))
-			die("exec %s: cd to %s failed (%s)", cmd->argv[0],
-			    cmd->dir, strerror(errno));
+			die_errno("exec '%s': cd to '%s' failed", cmd->argv[0],
+			    cmd->dir);
 		if (cmd->env) {
 			for (; *cmd->env; cmd->env++) {
 				if (strchr(*cmd->env, '='))
diff --git a/setup.c b/setup.c
index ebd60de..4d27f28 100644
--- a/setup.c
+++ b/setup.c
@@ -81,7 +81,7 @@ void verify_filename(const char *prefix, const char *arg)
 	if (errno == ENOENT)
 		die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
 		    "Use '--' to separate paths from revisions", arg);
-	die("'%s': %s", arg, strerror(errno));
+	die_errno("failed to stat '%s'", arg);
 }
 
 /*
@@ -103,7 +103,7 @@ void verify_non_filename(const char *prefix, const char *arg)
 		die("ambiguous argument '%s': both revision and filename\n"
 		    "Use '--' to separate filenames from revisions", arg);
 	if (errno != ENOENT && errno != ENOTDIR)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("failed to stat '%s'", arg);
 }
 
 const char **get_pathspec(const char *prefix, const char **pathspec)
@@ -257,7 +257,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		return NULL;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Error opening %s: %s", path, strerror(errno));
+		die_errno("Error opening '%s'", path);
 	buf = xmalloc(st.st_size + 1);
 	len = read_in_full(fd, buf, st.st_size);
 	close(fd);
@@ -389,7 +389,7 @@ static int check_repository_format_gently(int *nongit_ok)
 			die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
 		}
 		if (chdir(".."))
-			die("Cannot change to %s/..: %s", cwd, strerror(errno));
+			die_errno("Cannot change to '%s/..'", cwd);
 	}
 
 	inside_git_dir = 0;
diff --git a/sha1_file.c b/sha1_file.c
index e73cd4f..1964a6d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2287,7 +2287,7 @@ static void close_sha1_file(int fd)
 	if (fsync_object_files)
 		fsync_or_die(fd, "sha1 file");
 	if (close(fd) != 0)
-		die("error when closing sha1 file (%s)", strerror(errno));
+		die_errno("error when closing sha1 file");
 }
 
 /* Size of directory component, including the ending '/' */
diff --git a/shell.c b/shell.c
index b968be7..e4864e0 100644
--- a/shell.c
+++ b/shell.c
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
 	while (devnull_fd >= 0 && devnull_fd <= 2)
 		devnull_fd = dup(devnull_fd);
 	if (devnull_fd == -1)
-		die("opening /dev/null failed (%s)", strerror(errno));
+		die_errno("opening /dev/null failed");
 	close (devnull_fd);
 
 	/*
diff --git a/test-sha1.c b/test-sha1.c
index 9b98d07..80daba9 100644
--- a/test-sha1.c
+++ b/test-sha1.c
@@ -32,7 +32,7 @@ int main(int ac, char **av)
 			if (sz == 0)
 				break;
 			if (sz < 0)
-				die("test-sha1: %s", strerror(errno));
+				die_errno("test-sha1");
 			this_sz += sz;
 			cp += sz;
 			room -= sz;
diff --git a/wrapper.c b/wrapper.c
index 7eb3218..c9be140 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -96,7 +96,7 @@
 		release_pack_memory(length, fd);
 		ret = mmap(start, length, prot, flags, fd, offset);
 		if (ret == MAP_FAILED)
-			die("Out of memory? mmap failed: %s", strerror(errno));
+			die_errno("Out of memory? mmap failed");
 	}
 	return ret;
 }
@@ -175,7 +175,7 @@ int xdup(int fd)
 {
 	int ret = dup(fd);
 	if (ret < 0)
-		die("dup failed: %s", strerror(errno));
+		die_errno("dup failed");
 	return ret;
 }
 
@@ -183,7 +183,7 @@ int xdup(int fd)
 {
 	FILE *stream = fdopen(fd, mode);
 	if (stream == NULL)
-		die("Out of memory? fdopen failed: %s", strerror(errno));
+		die_errno("Out of memory? fdopen failed");
 	return stream;
 }
 
@@ -193,7 +193,7 @@ int xmkstemp(char *template)
 
 	fd = mkstemp(template);
 	if (fd < 0)
-		die("Unable to create temporary file: %s", strerror(errno));
+		die_errno("Unable to create temporary file");
 	return fd;
 }
 
diff --git a/write_or_die.c b/write_or_die.c
index 4c29255..d45b536 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -41,14 +41,14 @@ void maybe_flush_or_die(FILE *f, const char *desc)
 		 */
 		if (errno == EPIPE || errno == EINVAL)
 			exit(0);
-		die("write failure on %s: %s", desc, strerror(errno));
+		die_errno("write failure on '%s'", desc);
 	}
 }
 
 void fsync_or_die(int fd, const char *msg)
 {
 	if (fsync(fd) < 0) {
-		die("%s: fsync error (%s)", msg, strerror(errno));
+		die_errno("fsync error on '%s'", msg);
 	}
 }
 
@@ -57,7 +57,7 @@ void write_or_die(int fd, const void *buf, size_t count)
 	if (write_in_full(fd, buf, count) < 0) {
 		if (errno == EPIPE)
 			exit(0);
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 }
 
-- 
1.6.3.2.333.g27636

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls
  2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
                         ` (2 preceding siblings ...)
  2009-06-08 21:02       ` [PATCH v3 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
@ 2009-06-08 21:02       ` Thomas Rast
  3 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-08 21:02 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

Lots of die() calls did not actually report the kind of error, which
can leave the user confused as to the real problem.  Use die_errno()
where we check a system/library call that sets errno on failure, or
one of the following that wrap such calls:

  Function              Passes on error from
  --------              --------------------
  odb_pack_keep         open
  read_ancestry         fopen
  read_in_full          xread
  strbuf_read           xread
  strbuf_read_file      open or strbuf_read_file
  strbuf_readlink       readlink
  write_in_full         xwrite

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 abspath.c               |   12 ++++++------
 builtin-add.c           |    2 +-
 builtin-apply.c         |    6 +++---
 builtin-archive.c       |    4 ++--
 builtin-blame.c         |    8 ++++----
 builtin-clone.c         |   10 +++++-----
 builtin-commit.c        |    5 +++--
 builtin-fast-export.c   |    2 +-
 builtin-fmt-merge-msg.c |    2 +-
 builtin-fsck.c          |    2 +-
 builtin-init-db.c       |   21 +++++++++++----------
 builtin-log.c           |    4 ++--
 builtin-mailsplit.c     |    6 +++---
 builtin-merge.c         |   21 ++++++++++++---------
 builtin-rev-parse.c     |    2 +-
 builtin-revert.c        |    2 +-
 builtin-stripspace.c    |    2 +-
 builtin-tag.c           |    2 +-
 builtin-tar-tree.c      |    2 +-
 combine-diff.c          |    2 +-
 diff.c                  |    6 +++---
 entry.c                 |    2 +-
 fast-import.c           |    4 ++--
 hash-object.c           |    2 +-
 ll-merge.c              |    2 +-
 mktag.c                 |    2 +-
 read-cache.c            |    2 +-
 setup.c                 |   10 +++++-----
 transport.c             |    4 ++--
 unpack-file.c           |    2 +-
 30 files changed, 79 insertions(+), 74 deletions(-)

diff --git a/abspath.c b/abspath.c
index 649f34f..4bee0ba 100644
--- a/abspath.c
+++ b/abspath.c
@@ -41,13 +41,13 @@ int is_directory(const char *path)
 
 		if (*buf) {
 			if (!*cwd && !getcwd(cwd, sizeof(cwd)))
-				die ("Could not get current working directory");
+				die_errno ("Could not get current working directory");
 
 			if (chdir(buf))
-				die ("Could not switch to '%s'", buf);
+				die_errno ("Could not switch to '%s'", buf);
 		}
 		if (!getcwd(buf, PATH_MAX))
-			die ("Could not get current working directory");
+			die_errno ("Could not get current working directory");
 
 		if (last_elem) {
 			int len = strlen(buf);
@@ -63,7 +63,7 @@ int is_directory(const char *path)
 		if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
 			len = readlink(buf, next_buf, PATH_MAX);
 			if (len < 0)
-				die ("Invalid symlink: %s", buf);
+				die_errno ("Invalid symlink '%s'", buf);
 			if (PATH_MAX <= len)
 				die("symbolic link too long: %s", buf);
 			next_buf[len] = '\0';
@@ -75,7 +75,7 @@ int is_directory(const char *path)
 	}
 
 	if (*cwd && chdir(cwd))
-		die ("Could not change back to '%s'", cwd);
+		die_errno ("Could not change back to '%s'", cwd);
 
 	return buf;
 }
@@ -109,7 +109,7 @@ int is_directory(const char *path)
 	} else {
 		const char *cwd = get_pwd_cwd();
 		if (!cwd)
-			die("Cannot determine the current working directory");
+			die_errno("Cannot determine the current working directory");
 		if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
 			die("Too long path: %.*s", 60, path);
 	}
diff --git a/builtin-add.c b/builtin-add.c
index c1b229a..8f651c1 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -220,7 +220,7 @@ int edit_patch(int argc, const char **argv, const char *prefix)
 	launch_editor(file, NULL, NULL);
 
 	if (stat(file, &st))
-		die("Could not stat '%s'", file);
+		die_errno("Could not stat '%s'", file);
 	if (!st.st_size)
 		die("Empty patch. Aborted.");
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 6526c08..dbc7f21 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned 
 	} else {
 		if (!cached) {
 			if (lstat(path, &st) < 0)
-				die("unable to stat newly created file %s",
-				    path);
+				die_errno("unable to stat newly created file '%s'",
+					  path);
 			fill_stat_cache_info(ce, &st);
 		}
 		if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
 			++nr;
 		}
 	}
-	die("unable to write file %s mode %o", path, mode);
+	die_errno("unable to write file '%s' mode %o", path, mode);
 }
 
 static void create_file(struct patch *patch)
diff --git a/builtin-archive.c b/builtin-archive.c
index 3c5a5a7..f9a4bea 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -13,10 +13,10 @@ static void create_output_file(const char *output_file)
 {
 	int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 	if (output_fd < 0)
-		die("could not create archive file: %s ", output_file);
+		die_errno("could not create archive file '%s'", output_file);
 	if (output_fd != 1) {
 		if (dup2(output_fd, 1) < 0)
-			die("could not redirect output");
+			die_errno("could not redirect output");
 		else
 			close(output_fd);
 	}
diff --git a/builtin-blame.c b/builtin-blame.c
index 7d8fbd5..fd6ca51 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2008,23 +2008,23 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 
 		if (contents_from) {
 			if (stat(contents_from, &st) < 0)
-				die("Cannot stat %s", contents_from);
+				die_errno("Cannot stat '%s'", contents_from);
 			read_from = contents_from;
 		}
 		else {
 			if (lstat(path, &st) < 0)
-				die("Cannot lstat %s", path);
+				die_errno("Cannot lstat '%s'", path);
 			read_from = path;
 		}
 		mode = canon_mode(st.st_mode);
 		switch (st.st_mode & S_IFMT) {
 		case S_IFREG:
 			if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
-				die("cannot open or read %s", read_from);
+				die_errno("cannot open or read '%s'", read_from);
 			break;
 		case S_IFLNK:
 			if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
-				die("cannot readlink %s", read_from);
+				die_errno("cannot readlink '%s'", read_from);
 			break;
 		default:
 			die("unsupported file type %s", read_from);
diff --git a/builtin-clone.c b/builtin-clone.c
index 5f34414..d2b0757 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -220,13 +220,13 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 
 	dir = opendir(src->buf);
 	if (!dir)
-		die("failed to open %s", src->buf);
+		die_errno("failed to open '%s'", src->buf);
 
 	if (mkdir(dest->buf, 0777)) {
 		if (errno != EEXIST)
-			die("failed to create directory %s", dest->buf);
+			die_errno("failed to create directory '%s'", dest->buf);
 		else if (stat(dest->buf, &buf))
-			die("failed to stat %s", dest->buf);
+			die_errno("failed to stat '%s'", dest->buf);
 		else if (!S_ISDIR(buf.st_mode))
 			die("%s exists and is not a directory", dest->buf);
 	}
@@ -257,11 +257,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 			if (!link(src->buf, dest->buf))
 				continue;
 			if (option_local)
-				die("failed to create link %s", dest->buf);
+				die_errno("failed to create link '%s'", dest->buf);
 			option_no_hardlinks = 1;
 		}
 		if (copy_file(dest->buf, src->buf, 0666))
-			die("failed to copy file to %s", dest->buf);
+			die_errno("failed to copy file to '%s'", dest->buf);
 	}
 	closedir(dir);
 }
diff --git a/builtin-commit.c b/builtin-commit.c
index 88c51bd..4bcce06 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -434,7 +434,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		if (isatty(0))
 			fprintf(stderr, "(reading log message from standard input)\n");
 		if (strbuf_read(&sb, 0, 0) < 0)
-			die("could not read log from standard input");
+			die_errno("could not read log from standard input");
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
@@ -964,8 +964,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	/* Finally, get the commit message */
 	strbuf_reset(&sb);
 	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
+		int saved_errno = errno;
 		rollback_index_files();
-		die("could not read commit message");
+		die("could not read commit message: %s", strerror(saved_errno));
 	}
 
 	/* Truncate the message just before the diff, if any. */
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 333d438..9a8a6fc 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -119,7 +119,7 @@ static void handle_object(const unsigned char *sha1)
 
 	printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
 	if (size && fwrite(buf, size, 1, stdout) != 1)
-		die ("Could not write blob %s", sha1_to_hex(sha1));
+		die_errno ("Could not write blob '%s'", sha1_to_hex(sha1));
 	printf("\n");
 
 	show_progress();
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index 1248d5e..9d52400 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	if (inpath && strcmp(inpath, "-")) {
 		in = fopen(inpath, "r");
 		if (!in)
-			die("cannot open %s", inpath);
+			die_errno("cannot open '%s'", inpath);
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index a49dbe1..d0f48cd 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -217,7 +217,7 @@ static void check_unreachable_object(struct object *obj)
 				return;
 			}
 			if (!(f = fopen(filename, "w")))
-				die("Could not open %s", filename);
+				die_errno("Could not open '%s'", filename);
 			if (obj->type == OBJ_BLOB) {
 				enum object_type type;
 				unsigned long size;
diff --git a/builtin-init-db.c b/builtin-init-db.c
index d1fa12a..4a56006 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -61,20 +61,20 @@ static void copy_templates_1(char *path, int baselen,
 		memcpy(template + template_baselen, de->d_name, namelen+1);
 		if (lstat(path, &st_git)) {
 			if (errno != ENOENT)
-				die("cannot stat %s", path);
+				die_errno("cannot stat '%s'", path);
 		}
 		else
 			exists = 1;
 
 		if (lstat(template, &st_template))
-			die("cannot stat template %s", template);
+			die_errno("cannot stat template '%s'", template);
 
 		if (S_ISDIR(st_template.st_mode)) {
 			DIR *subdir = opendir(template);
 			int baselen_sub = baselen + namelen;
 			int template_baselen_sub = template_baselen + namelen;
 			if (!subdir)
-				die("cannot opendir %s", template);
+				die_errno("cannot opendir '%s'", template);
 			path[baselen_sub++] =
 				template[template_baselen_sub++] = '/';
 			path[baselen_sub] =
@@ -91,16 +91,17 @@ static void copy_templates_1(char *path, int baselen,
 			int len;
 			len = readlink(template, lnk, sizeof(lnk));
 			if (len < 0)
-				die("cannot readlink %s", template);
+				die_errno("cannot readlink '%s'", template);
 			if (sizeof(lnk) <= len)
 				die("insanely long symlink %s", template);
 			lnk[len] = 0;
 			if (symlink(lnk, path))
-				die("cannot symlink %s %s", lnk, path);
+				die_errno("cannot symlink '%s' '%s'", lnk, path);
 		}
 		else if (S_ISREG(st_template.st_mode)) {
 			if (copy_file(path, template, st_template.st_mode))
-				die("cannot copy %s to %s", template, path);
+				die_errno("cannot copy '%s' to '%s'", template,
+					  path);
 		}
 		else
 			error("ignoring template %s", template);
@@ -350,7 +351,7 @@ static int guess_repository_type(const char *git_dir)
 	if (!strcmp(".", git_dir))
 		return 1;
 	if (!getcwd(cwd, sizeof(cwd)))
-		die("cannot tell cwd");
+		die_errno("cannot tell cwd");
 	if (!strcmp(git_dir, cwd))
 		return 1;
 	/*
@@ -440,11 +441,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		if (!git_work_tree_cfg) {
 			git_work_tree_cfg = xcalloc(PATH_MAX, 1);
 			if (!getcwd(git_work_tree_cfg, PATH_MAX))
-				die ("Cannot access current working directory.");
+				die_errno ("Cannot access current working directory");
 		}
 		if (access(get_git_work_tree(), X_OK))
-			die ("Cannot access work tree '%s'",
-			     get_git_work_tree());
+			die_errno ("Cannot access work tree '%s'",
+				   get_git_work_tree());
 	}
 
 	set_git_dir(make_absolute_path(git_dir));
diff --git a/builtin-log.c b/builtin-log.c
index 0d34050..750957c 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		if (use_stdout)
 			die("standard output, or directory, which one?");
 		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
-			die("Could not create directory %s",
-			    output_directory);
+			die_errno("Could not create directory '%s'",
+				  output_directory);
 	}
 
 	if (rev.pending.nr == 1) {
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c
index 71f3b3b..ad5f6b5 100644
--- a/builtin-mailsplit.c
+++ b/builtin-mailsplit.c
@@ -81,7 +81,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 
 	fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
 	if (fd < 0)
-		die("cannot open output file %s", name);
+		die_errno("cannot open output file '%s'", name);
 	output = fdopen(fd, "w");
 
 	/* Copy it out, while searching for a line that begins with
@@ -91,7 +91,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 		int is_partial = len && buf[len-1] != '\n';
 
 		if (fwrite(buf, 1, len, output) != len)
-			die("cannot write output");
+			die_errno("cannot write output");
 
 		len = read_line_with_nul(buf, sizeof(buf), mbox);
 		if (len == 0) {
@@ -99,7 +99,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 				status = 1;
 				break;
 			}
-			die("cannot read mbox");
+			die_errno("cannot read mbox");
 		}
 		if (!is_partial && !is_bare && is_from_line(buf, len))
 			break; /* done with one message */
diff --git a/builtin-merge.c b/builtin-merge.c
index 436263b..82335b0 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -268,7 +268,7 @@ static void squash_message(void)
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
 	if (fd < 0)
-		die("Could not write to %s", git_path("SQUASH_MSG"));
+		die_errno("Could not write to '%s'", git_path("SQUASH_MSG"));
 
 	init_revisions(&rev, NULL);
 	rev.ignore_merges = 1;
@@ -764,7 +764,8 @@ static int suggest_conflicts(void)
 
 	fp = fopen(git_path("MERGE_MSG"), "a");
 	if (!fp)
-		die("Could not open %s for writing", git_path("MERGE_MSG"));
+		die_errno("Could not open '%s' for writing",
+			  git_path("MERGE_MSG"));
 	fprintf(fp, "\nConflicts:\n");
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
@@ -1186,27 +1187,29 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 				sha1_to_hex(j->item->object.sha1));
 		fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing",
-				git_path("MERGE_HEAD"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_HEAD"));
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_HEAD"));
+			die_errno("Could not write to '%s'", git_path("MERGE_HEAD"));
 		close(fd);
 		strbuf_addch(&merge_msg, '\n');
 		fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MSG"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MSG"));
 		if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
 			merge_msg.len)
-			die("Could not write to %s", git_path("MERGE_MSG"));
+			die_errno("Could not write to '%s'", git_path("MERGE_MSG"));
 		close(fd);
 		fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MODE"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MODE"));
 		strbuf_reset(&buf);
 		if (!allow_fast_forward)
 			strbuf_addf(&buf, "no-ff");
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_MODE"));
+			die_errno("Could not write to '%s'", git_path("MERGE_MODE"));
 		close(fd);
 	}
 
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 112d622..da26dbc 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -592,7 +592,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 					continue;
 				}
 				if (!getcwd(cwd, PATH_MAX))
-					die("unable to get current working directory");
+					die_errno("unable to get current working directory");
 				printf("%s/.git\n", cwd);
 				continue;
 			}
diff --git a/builtin-revert.c b/builtin-revert.c
index c87115a..151aa6a 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)
 {
 	int len = strlen(string);
 	if (write_in_full(msg_fd, string, len) < 0)
-		die ("Could not write to MERGE_MSG");
+		die_errno ("Could not write to MERGE_MSG");
 }
 
 static void add_message_to_msg(const char *message)
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index d6e3896..1fd2205 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
 		strip_comments = 1;
 
 	if (strbuf_read(&buf, 0, 1024) < 0)
-		die("could not read the input");
+		die_errno("could not read the input");
 
 	stripspace(&buf, strip_comments);
 
diff --git a/builtin-tag.c b/builtin-tag.c
index 7b51095..165bec3 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -442,7 +442,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		else {
 			if (!strcmp(msgfile, "-")) {
 				if (strbuf_read(&buf, 0, 1024) < 0)
-					die("cannot read %s", msgfile);
+					die_errno("cannot read '%s'", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
 					die_errno("could not open or read '%s'",
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index f88e721..8b3a35e 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
 
 	n = write_in_full(1, content + 11, 41);
 	if (n < 41)
-		die("git get-tar-commit-id: write error");
+		die_errno("git get-tar-commit-id: write error");
 
 	return 0;
 }
diff --git a/combine-diff.c b/combine-diff.c
index 60d0367..bbf74fc 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -746,7 +746,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 
 			done = read_in_full(fd, result, len);
 			if (done < 0)
-				die("read error '%s'", elem->path);
+				die_errno("read error '%s'", elem->path);
 			else if (done < len)
 				die("early EOF '%s'", elem->path);
 
diff --git a/diff.c b/diff.c
index 48043f5..aec613f 100644
--- a/diff.c
+++ b/diff.c
@@ -1982,7 +1982,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		size = buf.len;
 	}
 	if (write_in_full(fd, blob, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	temp->name = temp->tmp_path;
 	strcpy(temp->hex, sha1_to_hex(sha1));
@@ -2026,7 +2026,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
 			if (strbuf_readlink(&sb, name, st.st_size) < 0)
-				die("readlink(%s)", name);
+				die_errno("readlink(%s)", name);
 			prep_temp_blob(name, temp, sb.buf, sb.len,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
@@ -2219,7 +2219,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
 				return;
 			}
 			if (lstat(one->path, &st) < 0)
-				die("stat %s", one->path);
+				die_errno("stat '%s'", one->path);
 			if (index_path(one->sha1, one->path, &st, 0))
 				die("cannot hash %s", one->path);
 		}
diff --git a/entry.c b/entry.c
index 8ec880b..d3e86c7 100644
--- a/entry.c
+++ b/entry.c
@@ -37,7 +37,7 @@ static void create_directories(const char *path, int path_len,
 			if (errno == EEXIST && state->force &&
 			    !unlink_or_warn(buf) && !mkdir(buf, 0777))
 				continue;
-			die("cannot create directory at %s", buf);
+			die_errno("cannot create directory at '%s'", buf);
 		}
 	}
 	free(buf);
diff --git a/fast-import.c b/fast-import.c
index d31a4e8..7ef9865 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)
 
 	keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
 	if (keep_fd < 0)
-		die("cannot create keep file");
+		die_errno("cannot create keep file");
 	write_or_die(keep_fd, keep_msg, strlen(keep_msg));
 	if (close(keep_fd))
-		die("failed to write keep file");
+		die_errno("failed to write keep file");
 
 	snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
 		 get_object_directory(), sha1_to_hex(pack_data->sha1));
diff --git a/hash-object.c b/hash-object.c
index 47cf43c..9455dd0 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,
 	int fd;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Cannot open %s", path);
+		die_errno("Cannot open '%s'", path);
 	hash_fd(fd, type, write_object, vpath);
 }
 
diff --git a/ll-merge.c b/ll-merge.c
index 81c02ad..caf22be 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, src->ptr, src->size) != src->size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 }
 
diff --git a/mktag.c b/mktag.c
index 99a356e..a609e3e 100644
--- a/mktag.c
+++ b/mktag.c
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
 	setup_git_directory();
 
 	if (strbuf_read(&buf, 0, 4096) < 0) {
-		die("could not read from stdin");
+		die_errno("could not read from stdin");
 	}
 
 	/* Verify it for some basic sanity: it needs to start with
diff --git a/read-cache.c b/read-cache.c
index f76b5bb..4e3e272 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)
 	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	close(fd);
 	if (mmap == MAP_FAILED)
-		die("unable to map index file");
+		die_errno("unable to map index file");
 
 	hdr = mmap;
 	if (verify_hdr(hdr, mmap_size) < 0)
diff --git a/setup.c b/setup.c
index 4d27f28..e3781b6 100644
--- a/setup.c
+++ b/setup.c
@@ -327,7 +327,7 @@ static int check_repository_format_gently(int *nongit_ok)
 				return NULL;
 			set_git_dir(make_absolute_path(gitdirenv));
 			if (chdir(work_tree_env) < 0)
-				die ("Could not chdir to %s", work_tree_env);
+				die_errno ("Could not chdir to '%s'", work_tree_env);
 			strcat(buffer, "/");
 			return retval;
 		}
@@ -339,7 +339,7 @@ static int check_repository_format_gently(int *nongit_ok)
 	}
 
 	if (!getcwd(cwd, sizeof(cwd)-1))
-		die("Unable to read current working directory");
+		die_errno("Unable to read current working directory");
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -382,7 +382,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		if (offset <= ceil_offset) {
 			if (nongit_ok) {
 				if (chdir(cwd))
-					die("Cannot come back to cwd");
+					die_errno("Cannot come back to cwd");
 				*nongit_ok = 1;
 				return NULL;
 			}
@@ -493,10 +493,10 @@ int check_repository_format(void)
 		static char buffer[PATH_MAX + 1];
 		char *rel;
 		if (retval && chdir(retval))
-			die ("Could not jump back into original cwd");
+			die_errno ("Could not jump back into original cwd");
 		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
 		if (rel && *rel && chdir(get_git_work_tree()))
-			die ("Could not jump to working directory");
+			die_errno ("Could not jump to working directory");
 		return rel && *rel ? strcat(rel, "/") : NULL;
 	}
 
diff --git a/transport.c b/transport.c
index 17891d5..8decd66 100644
--- a/transport.c
+++ b/transport.c
@@ -158,7 +158,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	temp_dir_len = temp_dir.len;
 
 	strbuf_addstr(&buf, rsync_url(transport->url));
@@ -321,7 +321,7 @@ static int rsync_transport_push(struct transport *transport,
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	strbuf_addch(&temp_dir, '/');
 
 	if (flags & TRANSPORT_PUSH_ALL) {
diff --git a/unpack-file.c b/unpack-file.c
index 75cd2f1..ac9cbf7 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -17,7 +17,7 @@
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, buf, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	return path;
 }
-- 
1.6.3.2.333.g27636

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-08 15:35               ` Alexander Potashev
@ 2009-06-08 22:04                 ` Jeff King
  0 siblings, 0 replies; 42+ messages in thread
From: Jeff King @ 2009-06-08 22:04 UTC (permalink / raw)
  To: Alexander Potashev
  Cc: Junio C Hamano, Thomas Rast, git, Johannes Sixt, Petr Baudis

On Mon, Jun 08, 2009 at 07:35:55PM +0400, Alexander Potashev wrote:

> > More than that, you must support arbitrary printf format strings,
> > because the die routine is passed whatever goes to die() (a quick grep
> > revealed that we use at least %u and %c at various points). So it is an
> > undocumented requirement that the die routine process its parameters as
> > if it were from the printf family.
> 
> Your last statement is not quite true. A custom die routine may
> support all printf specifiers and some additional ones, but Thomas'
> die_errno passes the format string (and arguments list) to vsnprintf
> anyway, so the additional specifiers would be lost.

But if die() is called (_not_ die_errno), then the format is passed
unchanged. So what I am saying is that anyone supplying a die_routine
_already_ has to handle all printf format specifiers. So asking them to
handle just "%s" via die_errno is not introducing any additional
requirements.

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-08 21:02       ` [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
@ 2009-06-08 22:07         ` Jeff King
  2009-06-09  8:22           ` Thomas Rast
  0 siblings, 1 reply; 42+ messages in thread
From: Jeff King @ 2009-06-08 22:07 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Johannes Sixt, Alexander Potashev

On Mon, Jun 08, 2009 at 11:02:18PM +0200, Thomas Rast wrote:

> +void die_errno(const char *fmt, ...)
> +{
> +	va_list params;
> +	char fmt_with_err[1024];
> +
> +	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, strerror(errno));
> +
> +	va_start(params, fmt);
> +	die_routine(fmt_with_err, params);
> +	va_end(params);
> +}

Aren't you assuming that strerror(errno) has no '%'-signs here, which is
what kicked off the whole discussion?

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-08 22:07         ` Jeff King
@ 2009-06-09  8:22           ` Thomas Rast
  2009-06-09  8:53             ` Jeff King
  0 siblings, 1 reply; 42+ messages in thread
From: Thomas Rast @ 2009-06-09  8:22 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, git, Johannes Sixt, Alexander Potashev

Jeff King wrote:
> On Mon, Jun 08, 2009 at 11:02:18PM +0200, Thomas Rast wrote:
> 
> > +void die_errno(const char *fmt, ...)
> > +{
> > +	va_list params;
> > +	char fmt_with_err[1024];
> > +
> > +	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, strerror(errno));
> > +
> > +	va_start(params, fmt);
> > +	die_routine(fmt_with_err, params);
> > +	va_end(params);
> > +}
> 
> Aren't you assuming that strerror(errno) has no '%'-signs here, which is
> what kicked off the whole discussion?

True, of course.  Hrm.

So do we go back to v2 (for 1/3) and ask future callers to never use
custom formats with die_errno, or should I write a version that
doubles the % characters while tacking the error message onto the
format?

[It's a pity that it seems impossible to add an extra argument to the
va_args...]

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-09  8:22           ` Thomas Rast
@ 2009-06-09  8:53             ` Jeff King
  2009-06-09  9:29               ` Andreas Ericsson
  0 siblings, 1 reply; 42+ messages in thread
From: Jeff King @ 2009-06-09  8:53 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, git, Johannes Sixt, Alexander Potashev

On Tue, Jun 09, 2009 at 10:22:30AM +0200, Thomas Rast wrote:

> > Aren't you assuming that strerror(errno) has no '%'-signs here, which is
> > what kicked off the whole discussion?
> 
> True, of course.  Hrm.
> 
> So do we go back to v2 (for 1/3) and ask future callers to never use
> custom formats with die_errno, or should I write a version that
> doubles the % characters while tacking the error message onto the
> format?

Personally, I think it is fine to assume that the format and arguments
to die(), die_errno(), and to the die_routine() are all
printf-compatible. That is how it has always been until now, and I don't
see any callers who would want to change that.

This is all internal to git.  It's not as if we are talking about a
library being called by arbitrary code, and we want to leave doors open
for arbitrary clients. libgit2 would probably take a different approach
(though I imagine their general strategy is never to die(), but to
always return an error condition, anyway).

> [It's a pity that it seems impossible to add an extra argument to the
> va_args...]

Agreed, but I think we are out of luck short of variadic macros (which
are a C99-ism, and even then have some issues).

-Peff

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-09  8:53             ` Jeff King
@ 2009-06-09  9:29               ` Andreas Ericsson
  0 siblings, 0 replies; 42+ messages in thread
From: Andreas Ericsson @ 2009-06-09  9:29 UTC (permalink / raw)
  To: Jeff King
  Cc: Thomas Rast, Junio C Hamano, git, Johannes Sixt, Alexander Potashev

Jeff King wrote:
> On Tue, Jun 09, 2009 at 10:22:30AM +0200, Thomas Rast wrote:
> 
>>> Aren't you assuming that strerror(errno) has no '%'-signs here, which is
>>> what kicked off the whole discussion?
>> True, of course.  Hrm.
>>
>> So do we go back to v2 (for 1/3) and ask future callers to never use
>> custom formats with die_errno, or should I write a version that
>> doubles the % characters while tacking the error message onto the
>> format?
> 
> Personally, I think it is fine to assume that the format and arguments
> to die(), die_errno(), and to the die_routine() are all
> printf-compatible. That is how it has always been until now, and I don't
> see any callers who would want to change that.
> 
> This is all internal to git.  It's not as if we are talking about a
> library being called by arbitrary code, and we want to leave doors open
> for arbitrary clients. libgit2 would probably take a different approach
> (though I imagine their general strategy is never to die(), but to
> always return an error condition, anyway).
> 

Yup. libgit2 sets an internal git_errno variable and returns an error
code for each error it encounters, and we're referring callers to
regular "errno" to find out more about *why* a particular git_errno
condition was encountered.

We might want to give applications an easy way to die with a sensible
error message, but that's so far in the future that it's not worth
bothering with.

-- 
Andreas Ericsson                   andreas.ericsson@op5.se
OP5 AB                             www.op5.se
Tel: +46 8-230225                  Fax: +46 8-230231

Considering the successes of the wars on alcohol, poverty, drugs and
terror, I think we should give some serious thought to declaring war
on peace.

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 0/4] die_errno()
  2009-06-08 21:02       ` [PATCH v3 0/3] die_errno() Thomas Rast
@ 2009-06-27 15:58         ` Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
                             ` (4 more replies)
  0 siblings, 5 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-27 15:58 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git, Johannes Sixt, Jeff King, Alexander Potashev

Sorry for taking so long to come up with another iteration; I was on
holiday last week and rather busy otherwise.

This just picks up Junio's %-doubling patch from pu, with the extra
change I suggested in <200906121204.37752.trast@student.ethz.ch> to
handle the border case where a lone % would end up at the end of the
buffer.  The rest is the same as v3.


Junio C Hamano (1):
  die_errno(): double % in strerror() output just in case

Thomas Rast (3):
  Introduce die_errno() that appends strerror(errno) to die()
  Convert existing die(..., strerror(errno)) to die_errno()
  Use die_errno() instead of die() when checking syscalls

 abspath.c                |   12 ++++++------
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-add.c            |    2 +-
 builtin-apply.c          |   12 ++++++------
 builtin-archive.c        |    4 ++--
 builtin-blame.c          |   15 +++++++--------
 builtin-clone.c          |   21 ++++++++++-----------
 builtin-commit-tree.c    |    2 +-
 builtin-commit.c         |   28 +++++++++++++---------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    4 ++--
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    5 ++---
 builtin-fsck.c           |   10 +++++-----
 builtin-grep.c           |    2 +-
 builtin-init-db.c        |   21 +++++++++++----------
 builtin-log.c            |    4 ++--
 builtin-mailsplit.c      |    6 +++---
 builtin-merge.c          |   29 ++++++++++++++++-------------
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rev-parse.c      |    2 +-
 builtin-revert.c         |    2 +-
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-stripspace.c     |    2 +-
 builtin-tag.c            |    9 ++++-----
 builtin-tar-tree.c       |    2 +-
 builtin-unpack-objects.c |    2 +-
 combine-diff.c           |    2 +-
 csum-file.c              |    5 ++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |   10 +++++-----
 dir.c                    |    2 +-
 entry.c                  |   10 +++++-----
 fast-import.c            |    8 ++++----
 git-compat-util.h        |    1 +
 git.c                    |    6 +++---
 hash-object.c            |    2 +-
 index-pack.c             |   21 ++++++++++-----------
 ll-merge.c               |    2 +-
 merge-recursive.c        |    6 +++---
 mktag.c                  |    2 +-
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    8 ++++----
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |   18 +++++++++---------
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 transport.c              |    4 ++--
 unpack-file.c            |    2 +-
 usage.c                  |   28 ++++++++++++++++++++++++++++
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 60 files changed, 225 insertions(+), 207 deletions(-)

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die()
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
@ 2009-06-27 15:58           ` Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 2/4] die_errno(): double % in strerror() output just in case Thomas Rast
                             ` (3 subsequent siblings)
  4 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-27 15:58 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Sixt, Jeff King, Alexander Potashev, Junio C Hamano

There are many calls to die() that do, or should, report
strerror(errno) to indicate how the syscall they guard failed.
Introduce a small helper function for this case.

Note:

- POSIX says vsnprintf can modify errno in some unlikely cases, so we
  have to use errno early.

- We take some care to pass the original format to die_routine(), in
  case someone wants to call die_errno() with custom format
  characters.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 git-compat-util.h |    1 +
 usage.c           |   12 ++++++++++++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/git-compat-util.h b/git-compat-util.h
index 919b7f1..9609eaa 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -175,6 +175,7 @@
 /* General helper functions */
 extern void usage(const char *err) NORETURN;
 extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
+extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));
 extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));
 extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));
 
diff --git a/usage.c b/usage.c
index 820d09f..fd936a1 100644
--- a/usage.c
+++ b/usage.c
@@ -60,6 +60,18 @@ void die(const char *err, ...)
 	va_end(params);
 }
 
+void die_errno(const char *fmt, ...)
+{
+	va_list params;
+	char fmt_with_err[1024];
+
+	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, strerror(errno));
+
+	va_start(params, fmt);
+	die_routine(fmt_with_err, params);
+	va_end(params);
+}
+
 int error(const char *err, ...)
 {
 	va_list params;
-- 
1.6.3.3.433.gc91b

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 2/4] die_errno(): double % in strerror() output just in case
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
@ 2009-06-27 15:58           ` Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 3/4] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
                             ` (2 subsequent siblings)
  4 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-27 15:58 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Sixt, Jeff King, Alexander Potashev, Junio C Hamano

From: Junio C Hamano <gitster@pobox.com>

[tr: handle border case where % is placed at end of buffer]

Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---
 usage.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/usage.c b/usage.c
index fd936a1..b6aea45 100644
--- a/usage.c
+++ b/usage.c
@@ -64,8 +64,24 @@ void die_errno(const char *fmt, ...)
 {
 	va_list params;
 	char fmt_with_err[1024];
-
-	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, strerror(errno));
+	char str_error[256], *err;
+	int i, j;
+
+	err = strerror(errno);
+	for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) {
+		if ((str_error[j++] = err[i++]) != '%')
+			continue;
+		if (j < sizeof(str_error) - 1) {
+			str_error[j++] = '%';
+		} else {
+			/* No room to double the '%', so we overwrite it with
+			 * '\0' below */
+			j--;
+			break;
+		}
+	}
+	str_error[j] = 0;
+	snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, str_error);
 
 	va_start(params, fmt);
 	die_routine(fmt_with_err, params);
-- 
1.6.3.3.433.gc91b

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 3/4] Convert existing die(..., strerror(errno)) to die_errno()
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 2/4] die_errno(): double % in strerror() output just in case Thomas Rast
@ 2009-06-27 15:58           ` Thomas Rast
  2009-06-27 15:58           ` [PATCH v4 4/4] Use die_errno() instead of die() when checking syscalls Thomas Rast
  2009-06-27 18:38           ` [PATCH v4 0/4] die_errno() Junio C Hamano
  4 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-27 15:58 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Sixt, Jeff King, Alexander Potashev, Junio C Hamano

Change calls to die(..., strerror(errno)) to use the new die_errno().

In the process, also make slight style adjustments: at least state
_something_ about the function that failed (instead of just printing
the pathname), and put paths in single quotes.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 bisect.c                 |    5 ++---
 branch.c                 |    4 ++--
 builtin-apply.c          |    6 +++---
 builtin-blame.c          |    7 +++----
 builtin-clone.c          |   11 +++++------
 builtin-commit-tree.c    |    2 +-
 builtin-commit.c         |   23 ++++++++++-------------
 builtin-config.c         |    4 ++--
 builtin-diff.c           |    2 +-
 builtin-fast-export.c    |    2 +-
 builtin-fetch--tool.c    |    2 +-
 builtin-fmt-merge-msg.c  |    3 +--
 builtin-fsck.c           |    8 ++++----
 builtin-grep.c           |    2 +-
 builtin-merge.c          |    8 ++++----
 builtin-mv.c             |    2 +-
 builtin-pack-objects.c   |   14 +++++---------
 builtin-rm.c             |    2 +-
 builtin-send-pack.c      |    2 +-
 builtin-tag.c            |    7 +++----
 builtin-unpack-objects.c |    2 +-
 csum-file.c              |    5 ++---
 daemon.c                 |   15 +++++++--------
 diff.c                   |    4 ++--
 dir.c                    |    2 +-
 entry.c                  |    8 ++++----
 fast-import.c            |    4 ++--
 git.c                    |    6 +++---
 index-pack.c             |   21 ++++++++++-----------
 merge-recursive.c        |    6 +++---
 pack-refs.c              |    7 +++----
 pack-write.c             |   10 +++++-----
 pkt-line.c               |    4 ++--
 read-cache.c             |    6 +++---
 refs.c                   |    2 +-
 run-command.c            |    4 ++--
 setup.c                  |    8 ++++----
 sha1_file.c              |    2 +-
 shell.c                  |    2 +-
 test-sha1.c              |    2 +-
 wrapper.c                |    8 ++++----
 write_or_die.c           |    6 +++---
 42 files changed, 117 insertions(+), 133 deletions(-)

diff --git a/bisect.c b/bisect.c
index dbeb287..20286cc 100644
--- a/bisect.c
+++ b/bisect.c
@@ -461,7 +461,7 @@ static void read_bisect_paths(struct argv_array *array)
 	FILE *fp = fopen(filename, "r");
 
 	if (!fp)
-		die("Could not open file '%s': %s", filename, strerror(errno));
+		die_errno("Could not open file '%s'", filename);
 
 	while (strbuf_getline(&str, fp, '\n') != EOF) {
 		char *quoted;
@@ -712,8 +712,7 @@ static void mark_expected_rev(char *bisect_rev_hex)
 	int fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 
 	if (fd < 0)
-		die("could not create file '%s': %s",
-		    filename, strerror(errno));
+		die_errno("could not create file '%s'", filename);
 
 	bisect_rev_hex[len] = '\n';
 	write_or_die(fd, bisect_rev_hex, len + 1);
diff --git a/branch.c b/branch.c
index 62030af..05ef3f5 100644
--- a/branch.c
+++ b/branch.c
@@ -172,7 +172,7 @@ void create_branch(const char *head,
 
 	lock = lock_any_ref_for_update(ref.buf, NULL, 0);
 	if (!lock)
-		die("Failed to lock ref for update: %s.", strerror(errno));
+		die_errno("Failed to lock ref for update");
 
 	if (reflog)
 		log_all_ref_updates = 1;
@@ -188,7 +188,7 @@ void create_branch(const char *head,
 		setup_tracking(name, real_ref, track);
 
 	if (write_ref_sha1(lock, sha1, msg) < 0)
-		die("Failed to write ref: %s.", strerror(errno));
+		die_errno("Failed to write ref");
 
 	strbuf_release(&ref);
 	free(real_ref);
diff --git a/builtin-apply.c b/builtin-apply.c
index 4cf819c..2df2cb9 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,
 static void read_patch_file(struct strbuf *sb, int fd)
 {
 	if (strbuf_read(sb, fd, 0) < 0)
-		die("git apply: read returned %s", strerror(errno));
+		die_errno("git apply: failed to read");
 
 	/*
 	 * Make sure that we have some slop in the buffer
@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,
 	strbuf_release(&nbuf);
 
 	if (close(fd) < 0)
-		die("closing file %s: %s", path, strerror(errno));
+		die_errno("closing file '%s'", path);
 	return 0;
 }
 
@@ -3356,7 +3356,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
 
 		fd = open(arg, O_RDONLY);
 		if (fd < 0)
-			die("can't open patch '%s': %s", arg, strerror(errno));
+			die_errno("can't open patch '%s'", arg);
 		read_stdin = 0;
 		set_default_whitespace_mode(whitespace_option);
 		errs |= apply_patch(fd, arg, options);
diff --git a/builtin-blame.c b/builtin-blame.c
index 0c2d29a..7d8fbd5 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2035,7 +2035,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 		contents_from = "standard input";
 		mode = 0;
 		if (strbuf_read(&buf, 0, 0) < 0)
-			die("read error %s from stdin", strerror(errno));
+			die_errno("failed to read from stdin");
 	}
 	convert_to_git(path, buf.buf, buf.len, &buf, 0);
 	origin->file.ptr = buf.buf;
@@ -2261,8 +2261,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 	argc = parse_options_end(&ctx);
 
 	if (revs_file && read_ancestry(revs_file))
-		die("reading graft file %s failed: %s",
-		    revs_file, strerror(errno));
+		die_errno("reading graft file '%s' failed", revs_file);
 
 	if (cmd_is_annotate) {
 		output_option |= OUTPUT_ANNOTATE_COMPAT;
@@ -2350,7 +2349,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
 
 		setup_work_tree();
 		if (!has_string_in_work_tree(path))
-			die("cannot stat path %s: %s", path, strerror(errno));
+			die_errno("cannot stat path '%s'", path);
 	}
 
 	setup_revisions(argc, argv, &revs, NULL);
diff --git a/builtin-clone.c b/builtin-clone.c
index 2ceacb7..ccb0480 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -252,8 +252,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 		}
 
 		if (unlink(dest->buf) && errno != ENOENT)
-			die("failed to unlink %s: %s",
-			    dest->buf, strerror(errno));
+			die_errno("failed to unlink '%s'", dest->buf);
 		if (!option_no_hardlinks) {
 			if (!link(src->buf, dest->buf))
 				continue;
@@ -420,11 +419,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
 	if (!option_bare) {
 		junk_work_tree = work_tree;
 		if (safe_create_leading_directories_const(work_tree) < 0)
-			die("could not create leading directories of '%s': %s",
-					work_tree, strerror(errno));
+			die_errno("could not create leading directories of '%s'",
+				  work_tree);
 		if (!dest_exists && mkdir(work_tree, 0755))
-			die("could not create work tree dir '%s': %s.",
-					work_tree, strerror(errno));
+			die_errno("could not create work tree dir '%s'.",
+				  work_tree);
 		set_git_work_tree(work_tree);
 	}
 	junk_git_dir = git_dir;
diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c
index 0453425..6467077 100644
--- a/builtin-commit-tree.c
+++ b/builtin-commit-tree.c
@@ -124,7 +124,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&buffer, 0, 0) < 0)
-		die("git commit-tree: read returned %s", strerror(errno));
+		die_errno("git commit-tree: failed to read");
 
 	if (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {
 		printf("%s\n", sha1_to_hex(commit_sha1));
diff --git a/builtin-commit.c b/builtin-commit.c
index 41e222d..88c51bd 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -438,8 +438,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
-			die("could not read log file '%s': %s",
-			    logfile, strerror(errno));
+			die_errno("could not read log file '%s'",
+				  logfile);
 		hook_arg1 = "message";
 	} else if (use_message) {
 		buffer = strstr(use_message_buffer, "\n\n");
@@ -450,16 +450,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		hook_arg2 = use_message;
 	} else if (!stat(git_path("MERGE_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0)
-			die("could not read MERGE_MSG: %s", strerror(errno));
+			die_errno("could not read MERGE_MSG");
 		hook_arg1 = "merge";
 	} else if (!stat(git_path("SQUASH_MSG"), &statbuf)) {
 		if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0)
-			die("could not read SQUASH_MSG: %s", strerror(errno));
+			die_errno("could not read SQUASH_MSG");
 		hook_arg1 = "squash";
 	} else if (template_file && !stat(template_file, &statbuf)) {
 		if (strbuf_read_file(&sb, template_file, 0) < 0)
-			die("could not read %s: %s",
-			    template_file, strerror(errno));
+			die_errno("could not read '%s'", template_file);
 		hook_arg1 = "template";
 	}
 
@@ -472,8 +471,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 
 	fp = fopen(git_path(commit_editmsg), "w");
 	if (fp == NULL)
-		die("could not open %s: %s",
-		    git_path(commit_editmsg), strerror(errno));
+		die_errno("could not open '%s'", git_path(commit_editmsg));
 
 	if (cleanup_mode != CLEANUP_NONE)
 		stripspace(&sb, 0);
@@ -497,7 +495,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 	}
 
 	if (fwrite(sb.buf, 1, sb.len, fp) < sb.len)
-		die("could not write commit template: %s", strerror(errno));
+		die_errno("could not write commit template");
 
 	strbuf_release(&sb);
 
@@ -940,8 +938,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		pptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;
 		fp = fopen(git_path("MERGE_HEAD"), "r");
 		if (fp == NULL)
-			die("could not open %s for reading: %s",
-			    git_path("MERGE_HEAD"), strerror(errno));
+			die_errno("could not open '%s' for reading",
+				  git_path("MERGE_HEAD"));
 		while (strbuf_getline(&m, fp, '\n') != EOF) {
 			unsigned char sha1[20];
 			if (get_sha1_hex(m.buf, sha1) < 0)
@@ -952,8 +950,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 		strbuf_release(&m);
 		if (!stat(git_path("MERGE_MODE"), &statbuf)) {
 			if (strbuf_read_file(&sb, git_path("MERGE_MODE"), 0) < 0)
-				die("could not read MERGE_MODE: %s",
-						strerror(errno));
+				die_errno("could not read MERGE_MODE");
 			if (!strcmp(sb.buf, "no-ff"))
 				allow_fast_forward = 0;
 		}
diff --git a/builtin-config.c b/builtin-config.c
index 60915f9..a2d656e 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -383,8 +383,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix)
 		check_argc(argc, 0, 0);
 		if (git_config(show_all_config, NULL) < 0) {
 			if (config_exclusive_filename)
-				die("unable to read config file %s: %s",
-				    config_exclusive_filename, strerror(errno));
+				die_errno("unable to read config file '%s'",
+					  config_exclusive_filename);
 			else
 				die("error processing config file(s)");
 		}
diff --git a/builtin-diff.c b/builtin-diff.c
index d75d69b..2e51f40 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -70,7 +70,7 @@ static int builtin_diff_b_f(struct rev_info *revs,
 		usage(builtin_diff_usage);
 
 	if (lstat(path, &st))
-		die("'%s': %s", path, strerror(errno));
+		die_errno("failed to stat '%s'", path);
 	if (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))
 		die("'%s': not a regular file or symlink", path);
 
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 6cef810..333d438 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -451,7 +451,7 @@ static void import_marks(char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 
 	while (fgets(line, sizeof(line), f)) {
 		uint32_t mark;
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 29356d2..3dbdf7a 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -8,7 +8,7 @@
 {
 	struct strbuf buf = STRBUF_INIT;
 	if (strbuf_read(&buf, 0, 1024) < 0) {
-		die("error reading standard input: %s", strerror(errno));
+		die_errno("error reading standard input");
 	}
 	return strbuf_detach(&buf, NULL);
 }
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index fbf9582..1248d5e 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -372,8 +372,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
-		die("could not read input file %s", strerror(errno));
-
+		die_errno("could not read input file");
 	ret = fmt_merge_msg(merge_summary, &input, &output);
 	if (ret)
 		return ret;
diff --git a/builtin-fsck.c b/builtin-fsck.c
index e077e72..32a1e41 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -225,15 +225,15 @@ static void check_unreachable_object(struct object *obj)
 						&type, &size);
 				if (buf) {
 					if (fwrite(buf, size, 1, f) != 1)
-						die("Could not write %s: %s",
-						    filename, strerror(errno));
+						die_errno("Could not write '%s'",
+							  filename);
 					free(buf);
 				}
 			} else
 				fprintf(f, "%s\n", sha1_to_hex(obj->sha1));
 			if (fclose(f))
-				die("Could not finish %s: %s",
-				    filename, strerror(errno));
+				die_errno("Could not finish '%s'",
+					  filename);
 		}
 		return;
 	}
diff --git a/builtin-grep.c b/builtin-grep.c
index 73fc922..e558368 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -594,7 +594,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)
 
 	patterns = fopen(arg, "r");
 	if (!patterns)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("cannot open '%s'", arg);
 	while (strbuf_getline(&sb, patterns, '\n') == 0) {
 		/* ignore empty line like grep does */
 		if (sb.len == 0)
diff --git a/builtin-merge.c b/builtin-merge.c
index af9adab..5ad2188 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -294,9 +294,9 @@ static void squash_message(void)
 			NULL, NULL, rev.date_mode, 0);
 	}
 	if (write(fd, out.buf, out.len) < 0)
-		die("Writing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Writing SQUASH_MSG");
 	if (close(fd))
-		die("Finishing SQUASH_MSG: %s", strerror(errno));
+		die_errno("Finishing SQUASH_MSG");
 	strbuf_release(&out);
 }
 
@@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct strbuf *msg)
 
 		fp = fopen(git_path("FETCH_HEAD"), "r");
 		if (!fp)
-			die("could not open %s for reading: %s",
-				git_path("FETCH_HEAD"), strerror(errno));
+			die_errno("could not open '%s' for reading",
+				  git_path("FETCH_HEAD"));
 		strbuf_getline(&line, fp, '\n');
 		fclose(fp);
 		ptr = strstr(line.buf, "\tnot-for-merge\t");
diff --git a/builtin-mv.c b/builtin-mv.c
index 8b81d4b..024dfeb 100644
--- a/builtin-mv.c
+++ b/builtin-mv.c
@@ -209,7 +209,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
 			printf("Renaming %s to %s\n", src, dst);
 		if (!show_only && mode != INDEX &&
 				rename(src, dst) < 0 && !ignore_errors)
-			die ("renaming %s failed: %s", src, strerror(errno));
+			die_errno ("renaming '%s' failed", src);
 
 		if (mode == WORKING_DIRECTORY)
 			continue;
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 941cc2d..a27c2f6 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -536,11 +536,9 @@ static void write_pack_file(void)
 				 base_name, sha1_to_hex(sha1));
 			free_pack_by_name(tmpname);
 			if (adjust_perm(pack_tmp_name, mode))
-				die("unable to make temporary pack file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary pack file readable");
 			if (rename(pack_tmp_name, tmpname))
-				die("unable to rename temporary pack file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary pack file");
 
 			/*
 			 * Packs are runtime accessed in their mtime
@@ -566,11 +564,9 @@ static void write_pack_file(void)
 			snprintf(tmpname, sizeof(tmpname), "%s-%s.idx",
 				 base_name, sha1_to_hex(sha1));
 			if (adjust_perm(idx_tmp_name, mode))
-				die("unable to make temporary index file readable: %s",
-				    strerror(errno));
+				die_errno("unable to make temporary index file readable");
 			if (rename(idx_tmp_name, tmpname))
-				die("unable to rename temporary index file: %s",
-				    strerror(errno));
+				die_errno("unable to rename temporary index file");
 
 			free(idx_tmp_name);
 			free(pack_tmp_name);
@@ -1879,7 +1875,7 @@ static void read_object_list_from_stdin(void)
 			if (!ferror(stdin))
 				die("fgets returned NULL, not EOF, not error!");
 			if (errno != EINTR)
-				die("fgets: %s", strerror(errno));
+				die_errno("fgets");
 			clearerr(stdin);
 			continue;
 		}
diff --git a/builtin-rm.c b/builtin-rm.c
index 0cc4912..57975db 100644
--- a/builtin-rm.c
+++ b/builtin-rm.c
@@ -257,7 +257,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 				continue;
 			}
 			if (!removed)
-				die("git rm: %s: %s", path, strerror(errno));
+				die_errno("git rm: '%s'", path);
 		}
 	}
 
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index c375a3d..47fb9f7 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -59,7 +59,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext
 	po.out = fd;
 	po.git_cmd = 1;
 	if (start_command(&po))
-		die("git pack-objects failed (%s)", strerror(errno));
+		die_errno("git pack-objects failed");
 
 	/*
 	 * We feed the pack-objects we just spawned with revision
diff --git a/builtin-tag.c b/builtin-tag.c
index 080e04a..4f6e414 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -308,8 +308,7 @@ static void create_tag(const unsigned char *object, const char *tag,
 		path = git_pathdup("TAG_EDITMSG");
 		fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
 		if (fd < 0)
-			die("could not create file '%s': %s",
-						path, strerror(errno));
+			die_errno("could not create file '%s'", path);
 
 		if (!is_null_sha1(prev))
 			write_tag_body(fd, prev);
@@ -446,8 +445,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 					die("cannot read %s", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
-					die("could not open or read '%s': %s",
-						msgfile, strerror(errno));
+					die_errno("could not open or read '%s'",
+						msgfile);
 			}
 		}
 	}
diff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c
index 7e3ea73..557148a 100644
--- a/builtin-unpack-objects.c
+++ b/builtin-unpack-objects.c
@@ -68,7 +68,7 @@ static void add_object_buffer(struct object *object, char *buffer, unsigned long
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		len += ret;
 	} while (len < min);
diff --git a/csum-file.c b/csum-file.c
index 2ddb12a..4d50cc5 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -26,7 +26,7 @@ static void flush(struct sha1file *f, void * buf, unsigned int count)
 		}
 		if (!ret)
 			die("sha1 file '%s' write error. Out of diskspace", f->name);
-		die("sha1 file '%s' write error (%s)", f->name, strerror(errno));
+		die_errno("sha1 file '%s' write error", f->name);
 	}
 }
 
@@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)
 		if (flags & CSUM_FSYNC)
 			fsync_or_die(f->fd, f->name);
 		if (close(f->fd))
-			die("%s: sha1 file error on close (%s)",
-			    f->name, strerror(errno));
+			die_errno("%s: sha1 file error on close", f->name);
 		fd = 0;
 	} else
 		fd = f->fd;
diff --git a/daemon.c b/daemon.c
index 366db37..fdbcf4f 100644
--- a/daemon.c
+++ b/daemon.c
@@ -862,7 +862,7 @@ static int service_loop(int socknum, int *socklist)
 					case ECONNABORTED:
 						continue;
 					default:
-						die("accept returned %s", strerror(errno));
+						die_errno("accept returned");
 					}
 				}
 				handle(incoming, (struct sockaddr *)&ss, sslen);
@@ -878,7 +878,7 @@ static void sanitize_stdfds(void)
 	while (fd != -1 && fd < 2)
 		fd = dup(fd);
 	if (fd == -1)
-		die("open /dev/null or dup failed: %s", strerror(errno));
+		die_errno("open /dev/null or dup failed");
 	if (fd > 2)
 		close(fd);
 }
@@ -889,12 +889,12 @@ static void daemonize(void)
 		case 0:
 			break;
 		case -1:
-			die("fork failed: %s", strerror(errno));
+			die_errno("fork failed");
 		default:
 			exit(0);
 	}
 	if (setsid() == -1)
-		die("setsid failed: %s", strerror(errno));
+		die_errno("setsid failed");
 	close(0);
 	close(1);
 	close(2);
@@ -905,9 +905,9 @@ static void store_pid(const char *path)
 {
 	FILE *f = fopen(path, "w");
 	if (!f)
-		die("cannot open pid file %s: %s", path, strerror(errno));
+		die_errno("cannot open pid file '%s'", path);
 	if (fprintf(f, "%"PRIuMAX"\n", (uintmax_t) getpid()) < 0 || fclose(f) != 0)
-		die("failed to write pid file %s: %s", path, strerror(errno));
+		die_errno("failed to write pid file '%s'", path);
 }
 
 static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)
@@ -1107,8 +1107,7 @@ int main(int argc, char **argv)
 		socklen_t slen = sizeof(ss);
 
 		if (!freopen("/dev/null", "w", stderr))
-			die("failed to redirect stderr to /dev/null: %s",
-			    strerror(errno));
+			die_errno("failed to redirect stderr to /dev/null");
 
 		if (getpeername(0, peer, &slen))
 			peer = NULL;
diff --git a/diff.c b/diff.c
index 43835d7..79aea7f 100644
--- a/diff.c
+++ b/diff.c
@@ -1975,7 +1975,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 	fd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,
 			strlen(base) + 1);
 	if (fd < 0)
-		die("unable to create temp-file: %s", strerror(errno));
+		die_errno("unable to create temp-file");
 	if (convert_to_working_tree(path,
 			(const char *)blob, (size_t)size, &buf)) {
 		blob = buf.buf;
@@ -2021,7 +2021,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (lstat(name, &st) < 0) {
 			if (errno == ENOENT)
 				goto not_a_valid_file;
-			die("stat(%s): %s", name, strerror(errno));
+			die_errno("stat(%s)", name);
 		}
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
diff --git a/dir.c b/dir.c
index bbfcb56..74b3bbf 100644
--- a/dir.c
+++ b/dir.c
@@ -759,7 +759,7 @@ int file_exists(const char *f)
 	if (!dir)
 		return NULL;
 	if (!getcwd(buffer, size))
-		die("can't find the current directory: %s", strerror(errno));
+		die_errno("can't find the current directory");
 
 	if (!is_absolute_path(dir))
 		dir = make_absolute_path(dir);
diff --git a/entry.c b/entry.c
index cc841ed..8ec880b 100644
--- a/entry.c
+++ b/entry.c
@@ -51,7 +51,7 @@ static void remove_subtree(const char *path)
 	char *name;
 
 	if (!dir)
-		die("cannot opendir %s (%s)", path, strerror(errno));
+		die_errno("cannot opendir '%s'", path);
 	strcpy(pathbuf, path);
 	name = pathbuf + strlen(path);
 	*name++ = '/';
@@ -61,15 +61,15 @@ static void remove_subtree(const char *path)
 			continue;
 		strcpy(name, de->d_name);
 		if (lstat(pathbuf, &st))
-			die("cannot lstat %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot lstat '%s'", pathbuf);
 		if (S_ISDIR(st.st_mode))
 			remove_subtree(pathbuf);
 		else if (unlink(pathbuf))
-			die("cannot unlink %s (%s)", pathbuf, strerror(errno));
+			die_errno("cannot unlink '%s'", pathbuf);
 	}
 	closedir(dir);
 	if (rmdir(path))
-		die("cannot rmdir %s (%s)", path, strerror(errno));
+		die_errno("cannot rmdir '%s'", path);
 }
 
 static int create_file(const char *path, unsigned int mode)
diff --git a/fast-import.c b/fast-import.c
index a2a2458..d31a4e8 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -2342,7 +2342,7 @@ static void import_marks(const char *input_file)
 	char line[512];
 	FILE *f = fopen(input_file, "r");
 	if (!f)
-		die("cannot read %s: %s", input_file, strerror(errno));
+		die_errno("cannot read '%s'", input_file);
 	while (fgets(line, sizeof(line), f)) {
 		uintmax_t mark;
 		char *end;
@@ -2448,7 +2448,7 @@ int main(int argc, const char **argv)
 				fclose(pack_edges);
 			pack_edges = fopen(a + 20, "a");
 			if (!pack_edges)
-				die("Cannot open %s: %s", a + 20, strerror(errno));
+				die_errno("Cannot open '%s'", a + 20);
 		} else if (!strcmp(a, "--force"))
 			force_update = 1;
 		else if (!strcmp(a, "--quiet"))
diff --git a/git.c b/git.c
index 7d7f949..b035676 100644
--- a/git.c
+++ b/git.c
@@ -200,7 +200,7 @@ static int handle_alias(int *argcp, const char ***argv)
 	}
 
 	if (subdir && chdir(subdir))
-		die("Cannot change to %s: %s", subdir, strerror(errno));
+		die_errno("Cannot change to '%s'", subdir);
 
 	errno = saved_errno;
 
@@ -257,11 +257,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 
 	/* Check for ENOSPC and EIO errors.. */
 	if (fflush(stdout))
-		die("write failure on standard output: %s", strerror(errno));
+		die_errno("write failure on standard output");
 	if (ferror(stdout))
 		die("unknown write failure on standard output");
 	if (fclose(stdout))
-		die("close failed on standard output: %s", strerror(errno));
+		die_errno("close failed on standard output");
 	return 0;
 }
 
diff --git a/index-pack.c b/index-pack.c
index c72cbd4..340074f 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -143,7 +143,7 @@ static void flush(void)
 		if (ret <= 0) {
 			if (!ret)
 				die("early EOF");
-			die("read error on input: %s", strerror(errno));
+			die_errno("read error on input");
 		}
 		input_len += ret;
 		if (from_stdin)
@@ -178,13 +178,12 @@ static void use(int bytes)
 		} else
 			output_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);
 		if (output_fd < 0)
-			die("unable to create %s: %s", pack_name, strerror(errno));
+			die_errno("unable to create '%s'", pack_name);
 		pack_fd = output_fd;
 	} else {
 		input_fd = open(pack_name, O_RDONLY);
 		if (input_fd < 0)
-			die("cannot open packfile '%s': %s",
-			    pack_name, strerror(errno));
+			die_errno("cannot open packfile '%s'", pack_name);
 		output_fd = -1;
 		pack_fd = input_fd;
 	}
@@ -370,7 +369,7 @@ static void unlink_base_data(struct base_data *c)
 	do {
 		ssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);
 		if (n < 0)
-			die("cannot pread pack file: %s", strerror(errno));
+			die_errno("cannot pread pack file");
 		if (!n)
 			die("premature end of pack file, %lu bytes missing",
 			    len - rdy);
@@ -631,7 +630,7 @@ static void parse_pack_objects(unsigned char *sha1)
 
 	/* If input_fd is a file, we should have reached its end now. */
 	if (fstat(input_fd, &st))
-		die("cannot fstat packfile: %s", strerror(errno));
+		die_errno("cannot fstat packfile");
 	if (S_ISREG(st.st_mode) &&
 			lseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)
 		die("pack has junk at the end");
@@ -788,7 +787,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 		fsync_or_die(output_fd, curr_pack_name);
 		err = close(output_fd);
 		if (err)
-			die("error while closing pack file: %s", strerror(errno));
+			die_errno("error while closing pack file");
 	}
 
 	if (keep_msg) {
@@ -801,16 +800,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
 
 		if (keep_fd < 0) {
 			if (errno != EEXIST)
-				die("cannot write keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot write keep file '%s'",
+					  keep_name);
 		} else {
 			if (keep_msg_len > 0) {
 				write_or_die(keep_fd, keep_msg, keep_msg_len);
 				write_or_die(keep_fd, "\n", 1);
 			}
 			if (close(keep_fd) != 0)
-				die("cannot close written keep file '%s' (%s)",
-				    keep_name, strerror(errno));
+				die_errno("cannot close written keep file '%s'",
+				    keep_name);
 			report = "keep";
 		}
 	}
diff --git a/merge-recursive.c b/merge-recursive.c
index c703445..efad149 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -438,7 +438,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)
 			/* Ignore epipe */
 			if (errno == EPIPE)
 				break;
-			die("merge-recursive: %s", strerror(errno));
+			die_errno("merge-recursive");
 		} else if (!ret) {
 			die("merge-recursive: disk full?");
 		}
@@ -554,7 +554,7 @@ static void update_file_flags(struct merge_options *o,
 				mode = 0666;
 			fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);
 			if (fd < 0)
-				die("failed to open %s: %s", path, strerror(errno));
+				die_errno("failed to open '%s'", path);
 			flush_buffer(fd, buf, size);
 			close(fd);
 		} else if (S_ISLNK(mode)) {
@@ -562,7 +562,7 @@ static void update_file_flags(struct merge_options *o,
 			safe_create_leading_directories_const(path);
 			unlink(path);
 			if (symlink(lnk, path))
-				die("failed to symlink %s: %s", path, strerror(errno));
+				die_errno("failed to symlink '%s'", path);
 			free(lnk);
 		} else
 			die("do not know what to do with %06o %s '%s'",
diff --git a/pack-refs.c b/pack-refs.c
index 301fc60..7f43f8a 100644
--- a/pack-refs.c
+++ b/pack-refs.c
@@ -93,8 +93,7 @@ int pack_refs(unsigned int flags)
 				       LOCK_DIE_ON_ERROR);
 	cbdata.refs_file = fdopen(fd, "w");
 	if (!cbdata.refs_file)
-		die("unable to create ref-pack file structure (%s)",
-		    strerror(errno));
+		die_errno("unable to create ref-pack file structure");
 
 	/* perhaps other traits later as well */
 	fprintf(cbdata.refs_file, "# pack-refs with: peeled \n");
@@ -103,7 +102,7 @@ int pack_refs(unsigned int flags)
 	if (ferror(cbdata.refs_file))
 		die("failed to write ref-pack file");
 	if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))
-		die("failed to write ref-pack file (%s)", strerror(errno));
+		die_errno("failed to write ref-pack file");
 	/*
 	 * Since the lock file was fdopen()'ed and then fclose()'ed above,
 	 * assign -1 to the lock file descriptor so that commit_lock_file()
@@ -111,7 +110,7 @@ int pack_refs(unsigned int flags)
 	 */
 	packed.fd = -1;
 	if (commit_lock_file(&packed) < 0)
-		die("unable to overwrite old ref-pack file (%s)", strerror(errno));
+		die_errno("unable to overwrite old ref-pack file");
 	if (cbdata.flags & PACK_REFS_PRUNE)
 		prune_refs(cbdata.ref_to_prune);
 	return 0;
diff --git a/pack-write.c b/pack-write.c
index 7053538..741efcd 100644
--- a/pack-write.c
+++ b/pack-write.c
@@ -51,7 +51,7 @@ static int sha1_compare(const void *_a, const void *_b)
 		fd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);
 	}
 	if (fd < 0)
-		die("unable to create %s: %s", index_name, strerror(errno));
+		die_errno("unable to create '%s'", index_name);
 	f = sha1fd(fd, index_name);
 
 	/* if last object's offset is >= 2^31 we should use index V2 */
@@ -174,11 +174,11 @@ void fixup_pack_header_footer(int pack_fd,
 	git_SHA1_Init(&new_sha1_ctx);
 
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	if (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))
-		die("Unable to reread header of %s: %s", pack_name, strerror(errno));
+		die_errno("Unable to reread header of '%s'", pack_name);
 	if (lseek(pack_fd, 0, SEEK_SET) != 0)
-		die("Failed seeking to start of %s: %s", pack_name, strerror(errno));
+		die_errno("Failed seeking to start of '%s'", pack_name);
 	git_SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));
 	hdr.hdr_entries = htonl(object_count);
 	git_SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));
@@ -195,7 +195,7 @@ void fixup_pack_header_footer(int pack_fd,
 		if (!n)
 			break;
 		if (n < 0)
-			die("Failed to checksum %s: %s", pack_name, strerror(errno));
+			die_errno("Failed to checksum '%s'", pack_name);
 		git_SHA1_Update(&new_sha1_ctx, buf, n);
 
 		aligned_sz -= n;
diff --git a/pkt-line.c b/pkt-line.c
index f5d0086..b691abe 100644
--- a/pkt-line.c
+++ b/pkt-line.c
@@ -28,7 +28,7 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)
 		}
 		if (!ret)
 			die("write error (disk full?)");
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 	return nn;
 }
@@ -67,7 +67,7 @@ static void safe_read(int fd, void *buffer, unsigned size)
 {
 	ssize_t ret = read_in_full(fd, buffer, size);
 	if (ret < 0)
-		die("read error (%s)", strerror(errno));
+		die_errno("read error");
 	else if (ret < size)
 		die("The remote end hung up unexpectedly");
 }
diff --git a/read-cache.c b/read-cache.c
index 3f58711..f76b5bb 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -638,7 +638,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)
 {
 	struct stat st;
 	if (lstat(path, &st))
-		die("%s: unable to stat (%s)", path, strerror(errno));
+		die_errno("unable to stat '%s'", path);
 	return add_to_index(istate, path, &st, flags);
 }
 
@@ -1251,11 +1251,11 @@ int read_index_from(struct index_state *istate, const char *path)
 	if (fd < 0) {
 		if (errno == ENOENT)
 			return 0;
-		die("index file open failed (%s)", strerror(errno));
+		die_errno("index file open failed");
 	}
 
 	if (fstat(fd, &st))
-		die("cannot stat the open index (%s)", strerror(errno));
+		die_errno("cannot stat the open index");
 
 	errno = EINVAL;
 	mmap_size = xsize_t(st.st_size);
diff --git a/refs.c b/refs.c
index 24438c6..dffe395 100644
--- a/refs.c
+++ b/refs.c
@@ -1418,7 +1418,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *
 	logfile = git_path("logs/%s", ref);
 	logfd = open(logfile, O_RDONLY, 0);
 	if (logfd < 0)
-		die("Unable to read log %s: %s", logfile, strerror(errno));
+		die_errno("Unable to read log '%s'", logfile);
 	fstat(logfd, &st);
 	if (!st.st_size)
 		die("Log %s is empty.", logfile);
diff --git a/run-command.c b/run-command.c
index eb2efc3..ff3d8e2 100644
--- a/run-command.c
+++ b/run-command.c
@@ -101,8 +101,8 @@ int start_command(struct child_process *cmd)
 		}
 
 		if (cmd->dir && chdir(cmd->dir))
-			die("exec %s: cd to %s failed (%s)", cmd->argv[0],
-			    cmd->dir, strerror(errno));
+			die_errno("exec '%s': cd to '%s' failed", cmd->argv[0],
+			    cmd->dir);
 		if (cmd->env) {
 			for (; *cmd->env; cmd->env++) {
 				if (strchr(*cmd->env, '='))
diff --git a/setup.c b/setup.c
index ebd60de..4d27f28 100644
--- a/setup.c
+++ b/setup.c
@@ -81,7 +81,7 @@ void verify_filename(const char *prefix, const char *arg)
 	if (errno == ENOENT)
 		die("ambiguous argument '%s': unknown revision or path not in the working tree.\n"
 		    "Use '--' to separate paths from revisions", arg);
-	die("'%s': %s", arg, strerror(errno));
+	die_errno("failed to stat '%s'", arg);
 }
 
 /*
@@ -103,7 +103,7 @@ void verify_non_filename(const char *prefix, const char *arg)
 		die("ambiguous argument '%s': both revision and filename\n"
 		    "Use '--' to separate filenames from revisions", arg);
 	if (errno != ENOENT && errno != ENOTDIR)
-		die("'%s': %s", arg, strerror(errno));
+		die_errno("failed to stat '%s'", arg);
 }
 
 const char **get_pathspec(const char *prefix, const char **pathspec)
@@ -257,7 +257,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		return NULL;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Error opening %s: %s", path, strerror(errno));
+		die_errno("Error opening '%s'", path);
 	buf = xmalloc(st.st_size + 1);
 	len = read_in_full(fd, buf, st.st_size);
 	close(fd);
@@ -389,7 +389,7 @@ static int check_repository_format_gently(int *nongit_ok)
 			die("Not a git repository (or any of the parent directories): %s", DEFAULT_GIT_DIR_ENVIRONMENT);
 		}
 		if (chdir(".."))
-			die("Cannot change to %s/..: %s", cwd, strerror(errno));
+			die_errno("Cannot change to '%s/..'", cwd);
 	}
 
 	inside_git_dir = 0;
diff --git a/sha1_file.c b/sha1_file.c
index 8f5fe62..4576ff7 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2286,7 +2286,7 @@ static void close_sha1_file(int fd)
 	if (fsync_object_files)
 		fsync_or_die(fd, "sha1 file");
 	if (close(fd) != 0)
-		die("error when closing sha1 file (%s)", strerror(errno));
+		die_errno("error when closing sha1 file");
 }
 
 /* Size of directory component, including the ending '/' */
diff --git a/shell.c b/shell.c
index b968be7..e4864e0 100644
--- a/shell.c
+++ b/shell.c
@@ -60,7 +60,7 @@ int main(int argc, char **argv)
 	while (devnull_fd >= 0 && devnull_fd <= 2)
 		devnull_fd = dup(devnull_fd);
 	if (devnull_fd == -1)
-		die("opening /dev/null failed (%s)", strerror(errno));
+		die_errno("opening /dev/null failed");
 	close (devnull_fd);
 
 	/*
diff --git a/test-sha1.c b/test-sha1.c
index 9b98d07..80daba9 100644
--- a/test-sha1.c
+++ b/test-sha1.c
@@ -32,7 +32,7 @@ int main(int ac, char **av)
 			if (sz == 0)
 				break;
 			if (sz < 0)
-				die("test-sha1: %s", strerror(errno));
+				die_errno("test-sha1");
 			this_sz += sz;
 			cp += sz;
 			room -= sz;
diff --git a/wrapper.c b/wrapper.c
index 7eb3218..c9be140 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -96,7 +96,7 @@
 		release_pack_memory(length, fd);
 		ret = mmap(start, length, prot, flags, fd, offset);
 		if (ret == MAP_FAILED)
-			die("Out of memory? mmap failed: %s", strerror(errno));
+			die_errno("Out of memory? mmap failed");
 	}
 	return ret;
 }
@@ -175,7 +175,7 @@ int xdup(int fd)
 {
 	int ret = dup(fd);
 	if (ret < 0)
-		die("dup failed: %s", strerror(errno));
+		die_errno("dup failed");
 	return ret;
 }
 
@@ -183,7 +183,7 @@ int xdup(int fd)
 {
 	FILE *stream = fdopen(fd, mode);
 	if (stream == NULL)
-		die("Out of memory? fdopen failed: %s", strerror(errno));
+		die_errno("Out of memory? fdopen failed");
 	return stream;
 }
 
@@ -193,7 +193,7 @@ int xmkstemp(char *template)
 
 	fd = mkstemp(template);
 	if (fd < 0)
-		die("Unable to create temporary file: %s", strerror(errno));
+		die_errno("Unable to create temporary file");
 	return fd;
 }
 
diff --git a/write_or_die.c b/write_or_die.c
index 4c29255..d45b536 100644
--- a/write_or_die.c
+++ b/write_or_die.c
@@ -41,14 +41,14 @@ void maybe_flush_or_die(FILE *f, const char *desc)
 		 */
 		if (errno == EPIPE || errno == EINVAL)
 			exit(0);
-		die("write failure on %s: %s", desc, strerror(errno));
+		die_errno("write failure on '%s'", desc);
 	}
 }
 
 void fsync_or_die(int fd, const char *msg)
 {
 	if (fsync(fd) < 0) {
-		die("%s: fsync error (%s)", msg, strerror(errno));
+		die_errno("fsync error on '%s'", msg);
 	}
 }
 
@@ -57,7 +57,7 @@ void write_or_die(int fd, const void *buf, size_t count)
 	if (write_in_full(fd, buf, count) < 0) {
 		if (errno == EPIPE)
 			exit(0);
-		die("write error (%s)", strerror(errno));
+		die_errno("write error");
 	}
 }
 
-- 
1.6.3.3.433.gc91b

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH v4 4/4] Use die_errno() instead of die() when checking syscalls
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
                             ` (2 preceding siblings ...)
  2009-06-27 15:58           ` [PATCH v4 3/4] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
@ 2009-06-27 15:58           ` Thomas Rast
  2009-06-27 18:38           ` [PATCH v4 0/4] die_errno() Junio C Hamano
  4 siblings, 0 replies; 42+ messages in thread
From: Thomas Rast @ 2009-06-27 15:58 UTC (permalink / raw)
  To: Junio C Hamano
  Cc: git, Johannes Sixt, Jeff King, Alexander Potashev, Junio C Hamano

Lots of die() calls did not actually report the kind of error, which
can leave the user confused as to the real problem.  Use die_errno()
where we check a system/library call that sets errno on failure, or
one of the following that wrap such calls:

  Function              Passes on error from
  --------              --------------------
  odb_pack_keep         open
  read_ancestry         fopen
  read_in_full          xread
  strbuf_read           xread
  strbuf_read_file      open or strbuf_read_file
  strbuf_readlink       readlink
  write_in_full         xwrite

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 abspath.c               |   12 ++++++------
 builtin-add.c           |    2 +-
 builtin-apply.c         |    6 +++---
 builtin-archive.c       |    4 ++--
 builtin-blame.c         |    8 ++++----
 builtin-clone.c         |   10 +++++-----
 builtin-commit.c        |    5 +++--
 builtin-fast-export.c   |    2 +-
 builtin-fmt-merge-msg.c |    2 +-
 builtin-fsck.c          |    2 +-
 builtin-init-db.c       |   21 +++++++++++----------
 builtin-log.c           |    4 ++--
 builtin-mailsplit.c     |    6 +++---
 builtin-merge.c         |   21 ++++++++++++---------
 builtin-rev-parse.c     |    2 +-
 builtin-revert.c        |    2 +-
 builtin-stripspace.c    |    2 +-
 builtin-tag.c           |    2 +-
 builtin-tar-tree.c      |    2 +-
 combine-diff.c          |    2 +-
 diff.c                  |    6 +++---
 entry.c                 |    2 +-
 fast-import.c           |    4 ++--
 hash-object.c           |    2 +-
 ll-merge.c              |    2 +-
 mktag.c                 |    2 +-
 read-cache.c            |    2 +-
 setup.c                 |   10 +++++-----
 transport.c             |    4 ++--
 unpack-file.c           |    2 +-
 30 files changed, 79 insertions(+), 74 deletions(-)

diff --git a/abspath.c b/abspath.c
index 649f34f..4bee0ba 100644
--- a/abspath.c
+++ b/abspath.c
@@ -41,13 +41,13 @@ int is_directory(const char *path)
 
 		if (*buf) {
 			if (!*cwd && !getcwd(cwd, sizeof(cwd)))
-				die ("Could not get current working directory");
+				die_errno ("Could not get current working directory");
 
 			if (chdir(buf))
-				die ("Could not switch to '%s'", buf);
+				die_errno ("Could not switch to '%s'", buf);
 		}
 		if (!getcwd(buf, PATH_MAX))
-			die ("Could not get current working directory");
+			die_errno ("Could not get current working directory");
 
 		if (last_elem) {
 			int len = strlen(buf);
@@ -63,7 +63,7 @@ int is_directory(const char *path)
 		if (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {
 			len = readlink(buf, next_buf, PATH_MAX);
 			if (len < 0)
-				die ("Invalid symlink: %s", buf);
+				die_errno ("Invalid symlink '%s'", buf);
 			if (PATH_MAX <= len)
 				die("symbolic link too long: %s", buf);
 			next_buf[len] = '\0';
@@ -75,7 +75,7 @@ int is_directory(const char *path)
 	}
 
 	if (*cwd && chdir(cwd))
-		die ("Could not change back to '%s'", cwd);
+		die_errno ("Could not change back to '%s'", cwd);
 
 	return buf;
 }
@@ -109,7 +109,7 @@ int is_directory(const char *path)
 	} else {
 		const char *cwd = get_pwd_cwd();
 		if (!cwd)
-			die("Cannot determine the current working directory");
+			die_errno("Cannot determine the current working directory");
 		if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX)
 			die("Too long path: %.*s", 60, path);
 	}
diff --git a/builtin-add.c b/builtin-add.c
index 4e44148..78989da 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -220,7 +220,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
 	launch_editor(file, NULL, NULL);
 
 	if (stat(file, &st))
-		die("Could not stat '%s'", file);
+		die_errno("Could not stat '%s'", file);
 	if (!st.st_size)
 		die("Empty patch. Aborted.");
 
diff --git a/builtin-apply.c b/builtin-apply.c
index 2df2cb9..dc0ff5e 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned 
 	} else {
 		if (!cached) {
 			if (lstat(path, &st) < 0)
-				die("unable to stat newly created file %s",
-				    path);
+				die_errno("unable to stat newly created file '%s'",
+					  path);
 			fill_stat_cache_info(ce, &st);
 		}
 		if (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)
@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned
 			++nr;
 		}
 	}
-	die("unable to write file %s mode %o", path, mode);
+	die_errno("unable to write file '%s' mode %o", path, mode);
 }
 
 static void create_file(struct patch *patch)
diff --git a/builtin-archive.c b/builtin-archive.c
index 3c5a5a7..f9a4bea 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -13,10 +13,10 @@ static void create_output_file(const char *output_file)
 {
 	int output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);
 	if (output_fd < 0)
-		die("could not create archive file: %s ", output_file);
+		die_errno("could not create archive file '%s'", output_file);
 	if (output_fd != 1) {
 		if (dup2(output_fd, 1) < 0)
-			die("could not redirect output");
+			die_errno("could not redirect output");
 		else
 			close(output_fd);
 	}
diff --git a/builtin-blame.c b/builtin-blame.c
index 7d8fbd5..fd6ca51 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -2008,23 +2008,23 @@ static int git_blame_config(const char *var, const char *value, void *cb)
 
 		if (contents_from) {
 			if (stat(contents_from, &st) < 0)
-				die("Cannot stat %s", contents_from);
+				die_errno("Cannot stat '%s'", contents_from);
 			read_from = contents_from;
 		}
 		else {
 			if (lstat(path, &st) < 0)
-				die("Cannot lstat %s", path);
+				die_errno("Cannot lstat '%s'", path);
 			read_from = path;
 		}
 		mode = canon_mode(st.st_mode);
 		switch (st.st_mode & S_IFMT) {
 		case S_IFREG:
 			if (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)
-				die("cannot open or read %s", read_from);
+				die_errno("cannot open or read '%s'", read_from);
 			break;
 		case S_IFLNK:
 			if (strbuf_readlink(&buf, read_from, st.st_size) < 0)
-				die("cannot readlink %s", read_from);
+				die_errno("cannot readlink '%s'", read_from);
 			break;
 		default:
 			die("unsupported file type %s", read_from);
diff --git a/builtin-clone.c b/builtin-clone.c
index ccb0480..32dea74 100644
--- a/builtin-clone.c
+++ b/builtin-clone.c
@@ -220,13 +220,13 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 
 	dir = opendir(src->buf);
 	if (!dir)
-		die("failed to open %s", src->buf);
+		die_errno("failed to open '%s'", src->buf);
 
 	if (mkdir(dest->buf, 0777)) {
 		if (errno != EEXIST)
-			die("failed to create directory %s", dest->buf);
+			die_errno("failed to create directory '%s'", dest->buf);
 		else if (stat(dest->buf, &buf))
-			die("failed to stat %s", dest->buf);
+			die_errno("failed to stat '%s'", dest->buf);
 		else if (!S_ISDIR(buf.st_mode))
 			die("%s exists and is not a directory", dest->buf);
 	}
@@ -257,11 +257,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)
 			if (!link(src->buf, dest->buf))
 				continue;
 			if (option_local)
-				die("failed to create link %s", dest->buf);
+				die_errno("failed to create link '%s'", dest->buf);
 			option_no_hardlinks = 1;
 		}
 		if (copy_file(dest->buf, src->buf, 0666))
-			die("failed to copy file to %s", dest->buf);
+			die_errno("failed to copy file to '%s'", dest->buf);
 	}
 	closedir(dir);
 }
diff --git a/builtin-commit.c b/builtin-commit.c
index 88c51bd..4bcce06 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -434,7 +434,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
 		if (isatty(0))
 			fprintf(stderr, "(reading log message from standard input)\n");
 		if (strbuf_read(&sb, 0, 0) < 0)
-			die("could not read log from standard input");
+			die_errno("could not read log from standard input");
 		hook_arg1 = "message";
 	} else if (logfile) {
 		if (strbuf_read_file(&sb, logfile, 0) < 0)
@@ -964,8 +964,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
 	/* Finally, get the commit message */
 	strbuf_reset(&sb);
 	if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {
+		int saved_errno = errno;
 		rollback_index_files();
-		die("could not read commit message");
+		die("could not read commit message: %s", strerror(saved_errno));
 	}
 
 	/* Truncate the message just before the diff, if any. */
diff --git a/builtin-fast-export.c b/builtin-fast-export.c
index 333d438..9a8a6fc 100644
--- a/builtin-fast-export.c
+++ b/builtin-fast-export.c
@@ -119,7 +119,7 @@ static void handle_object(const unsigned char *sha1)
 
 	printf("blob\nmark :%"PRIu32"\ndata %lu\n", last_idnum, size);
 	if (size && fwrite(buf, size, 1, stdout) != 1)
-		die ("Could not write blob %s", sha1_to_hex(sha1));
+		die_errno ("Could not write blob '%s'", sha1_to_hex(sha1));
 	printf("\n");
 
 	show_progress();
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index 1248d5e..9d52400 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)
 	if (inpath && strcmp(inpath, "-")) {
 		in = fopen(inpath, "r");
 		if (!in)
-			die("cannot open %s", inpath);
+			die_errno("cannot open '%s'", inpath);
 	}
 
 	if (strbuf_read(&input, fileno(in), 0) < 0)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index 32a1e41..b3d38fa 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c
@@ -217,7 +217,7 @@ static void check_unreachable_object(struct object *obj)
 				return;
 			}
 			if (!(f = fopen(filename, "w")))
-				die("Could not open %s", filename);
+				die_errno("Could not open '%s'", filename);
 			if (obj->type == OBJ_BLOB) {
 				enum object_type type;
 				unsigned long size;
diff --git a/builtin-init-db.c b/builtin-init-db.c
index d1fa12a..4a56006 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -61,20 +61,20 @@ static void copy_templates_1(char *path, int baselen,
 		memcpy(template + template_baselen, de->d_name, namelen+1);
 		if (lstat(path, &st_git)) {
 			if (errno != ENOENT)
-				die("cannot stat %s", path);
+				die_errno("cannot stat '%s'", path);
 		}
 		else
 			exists = 1;
 
 		if (lstat(template, &st_template))
-			die("cannot stat template %s", template);
+			die_errno("cannot stat template '%s'", template);
 
 		if (S_ISDIR(st_template.st_mode)) {
 			DIR *subdir = opendir(template);
 			int baselen_sub = baselen + namelen;
 			int template_baselen_sub = template_baselen + namelen;
 			if (!subdir)
-				die("cannot opendir %s", template);
+				die_errno("cannot opendir '%s'", template);
 			path[baselen_sub++] =
 				template[template_baselen_sub++] = '/';
 			path[baselen_sub] =
@@ -91,16 +91,17 @@ static void copy_templates_1(char *path, int baselen,
 			int len;
 			len = readlink(template, lnk, sizeof(lnk));
 			if (len < 0)
-				die("cannot readlink %s", template);
+				die_errno("cannot readlink '%s'", template);
 			if (sizeof(lnk) <= len)
 				die("insanely long symlink %s", template);
 			lnk[len] = 0;
 			if (symlink(lnk, path))
-				die("cannot symlink %s %s", lnk, path);
+				die_errno("cannot symlink '%s' '%s'", lnk, path);
 		}
 		else if (S_ISREG(st_template.st_mode)) {
 			if (copy_file(path, template, st_template.st_mode))
-				die("cannot copy %s to %s", template, path);
+				die_errno("cannot copy '%s' to '%s'", template,
+					  path);
 		}
 		else
 			error("ignoring template %s", template);
@@ -350,7 +351,7 @@ static int guess_repository_type(const char *git_dir)
 	if (!strcmp(".", git_dir))
 		return 1;
 	if (!getcwd(cwd, sizeof(cwd)))
-		die("cannot tell cwd");
+		die_errno("cannot tell cwd");
 	if (!strcmp(git_dir, cwd))
 		return 1;
 	/*
@@ -440,11 +441,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
 		if (!git_work_tree_cfg) {
 			git_work_tree_cfg = xcalloc(PATH_MAX, 1);
 			if (!getcwd(git_work_tree_cfg, PATH_MAX))
-				die ("Cannot access current working directory.");
+				die_errno ("Cannot access current working directory");
 		}
 		if (access(get_git_work_tree(), X_OK))
-			die ("Cannot access work tree '%s'",
-			     get_git_work_tree());
+			die_errno ("Cannot access work tree '%s'",
+				   get_git_work_tree());
 	}
 
 	set_git_dir(make_absolute_path(git_dir));
diff --git a/builtin-log.c b/builtin-log.c
index 44f9a27..0c2fa0a 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
 		if (use_stdout)
 			die("standard output, or directory, which one?");
 		if (mkdir(output_directory, 0777) < 0 && errno != EEXIST)
-			die("Could not create directory %s",
-			    output_directory);
+			die_errno("Could not create directory '%s'",
+				  output_directory);
 	}
 
 	if (rev.pending.nr == 1) {
diff --git a/builtin-mailsplit.c b/builtin-mailsplit.c
index 71f3b3b..ad5f6b5 100644
--- a/builtin-mailsplit.c
+++ b/builtin-mailsplit.c
@@ -81,7 +81,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 
 	fd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);
 	if (fd < 0)
-		die("cannot open output file %s", name);
+		die_errno("cannot open output file '%s'", name);
 	output = fdopen(fd, "w");
 
 	/* Copy it out, while searching for a line that begins with
@@ -91,7 +91,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 		int is_partial = len && buf[len-1] != '\n';
 
 		if (fwrite(buf, 1, len, output) != len)
-			die("cannot write output");
+			die_errno("cannot write output");
 
 		len = read_line_with_nul(buf, sizeof(buf), mbox);
 		if (len == 0) {
@@ -99,7 +99,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)
 				status = 1;
 				break;
 			}
-			die("cannot read mbox");
+			die_errno("cannot read mbox");
 		}
 		if (!is_partial && !is_bare && is_from_line(buf, len))
 			break; /* done with one message */
diff --git a/builtin-merge.c b/builtin-merge.c
index 5ad2188..82b5466 100644
--- a/builtin-merge.c
+++ b/builtin-merge.c
@@ -268,7 +268,7 @@ static void squash_message(void)
 	printf("Squash commit -- not updating HEAD\n");
 	fd = open(git_path("SQUASH_MSG"), O_WRONLY | O_CREAT, 0666);
 	if (fd < 0)
-		die("Could not write to %s", git_path("SQUASH_MSG"));
+		die_errno("Could not write to '%s'", git_path("SQUASH_MSG"));
 
 	init_revisions(&rev, NULL);
 	rev.ignore_merges = 1;
@@ -764,7 +764,8 @@ static int suggest_conflicts(void)
 
 	fp = fopen(git_path("MERGE_MSG"), "a");
 	if (!fp)
-		die("Could not open %s for writing", git_path("MERGE_MSG"));
+		die_errno("Could not open '%s' for writing",
+			  git_path("MERGE_MSG"));
 	fprintf(fp, "\nConflicts:\n");
 	for (pos = 0; pos < active_nr; pos++) {
 		struct cache_entry *ce = active_cache[pos];
@@ -1189,27 +1190,29 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 				sha1_to_hex(j->item->object.sha1));
 		fd = open(git_path("MERGE_HEAD"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing",
-				git_path("MERGE_HEAD"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_HEAD"));
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_HEAD"));
+			die_errno("Could not write to '%s'", git_path("MERGE_HEAD"));
 		close(fd);
 		strbuf_addch(&merge_msg, '\n');
 		fd = open(git_path("MERGE_MSG"), O_WRONLY | O_CREAT, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MSG"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MSG"));
 		if (write_in_full(fd, merge_msg.buf, merge_msg.len) !=
 			merge_msg.len)
-			die("Could not write to %s", git_path("MERGE_MSG"));
+			die_errno("Could not write to '%s'", git_path("MERGE_MSG"));
 		close(fd);
 		fd = open(git_path("MERGE_MODE"), O_WRONLY | O_CREAT | O_TRUNC, 0666);
 		if (fd < 0)
-			die("Could open %s for writing", git_path("MERGE_MODE"));
+			die_errno("Could not open '%s' for writing",
+				  git_path("MERGE_MODE"));
 		strbuf_reset(&buf);
 		if (!allow_fast_forward)
 			strbuf_addf(&buf, "no-ff");
 		if (write_in_full(fd, buf.buf, buf.len) != buf.len)
-			die("Could not write to %s", git_path("MERGE_MODE"));
+			die_errno("Could not write to '%s'", git_path("MERGE_MODE"));
 		close(fd);
 	}
 
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 112d622..da26dbc 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -592,7 +592,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
 					continue;
 				}
 				if (!getcwd(cwd, PATH_MAX))
-					die("unable to get current working directory");
+					die_errno("unable to get current working directory");
 				printf("%s/.git\n", cwd);
 				continue;
 			}
diff --git a/builtin-revert.c b/builtin-revert.c
index c87115a..151aa6a 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)
 {
 	int len = strlen(string);
 	if (write_in_full(msg_fd, string, len) < 0)
-		die ("Could not write to MERGE_MSG");
+		die_errno ("Could not write to MERGE_MSG");
 }
 
 static void add_message_to_msg(const char *message)
diff --git a/builtin-stripspace.c b/builtin-stripspace.c
index d6e3896..1fd2205 100644
--- a/builtin-stripspace.c
+++ b/builtin-stripspace.c
@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)
 		strip_comments = 1;
 
 	if (strbuf_read(&buf, 0, 1024) < 0)
-		die("could not read the input");
+		die_errno("could not read the input");
 
 	stripspace(&buf, strip_comments);
 
diff --git a/builtin-tag.c b/builtin-tag.c
index 4f6e414..a51a6d1 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -442,7 +442,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		else {
 			if (!strcmp(msgfile, "-")) {
 				if (strbuf_read(&buf, 0, 1024) < 0)
-					die("cannot read %s", msgfile);
+					die_errno("cannot read '%s'", msgfile);
 			} else {
 				if (strbuf_read_file(&buf, msgfile, 1024) < 0)
 					die_errno("could not open or read '%s'",
diff --git a/builtin-tar-tree.c b/builtin-tar-tree.c
index f88e721..8b3a35e 100644
--- a/builtin-tar-tree.c
+++ b/builtin-tar-tree.c
@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
 
 	n = write_in_full(1, content + 11, 41);
 	if (n < 41)
-		die("git get-tar-commit-id: write error");
+		die_errno("git get-tar-commit-id: write error");
 
 	return 0;
 }
diff --git a/combine-diff.c b/combine-diff.c
index 60d0367..bbf74fc 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -746,7 +746,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
 
 			done = read_in_full(fd, result, len);
 			if (done < 0)
-				die("read error '%s'", elem->path);
+				die_errno("read error '%s'", elem->path);
 			else if (done < len)
 				die("early EOF '%s'", elem->path);
 
diff --git a/diff.c b/diff.c
index 79aea7f..0a020ff 100644
--- a/diff.c
+++ b/diff.c
@@ -1982,7 +1982,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		size = buf.len;
 	}
 	if (write_in_full(fd, blob, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	temp->name = temp->tmp_path;
 	strcpy(temp->hex, sha1_to_hex(sha1));
@@ -2026,7 +2026,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,
 		if (S_ISLNK(st.st_mode)) {
 			struct strbuf sb = STRBUF_INIT;
 			if (strbuf_readlink(&sb, name, st.st_size) < 0)
-				die("readlink(%s)", name);
+				die_errno("readlink(%s)", name);
 			prep_temp_blob(name, temp, sb.buf, sb.len,
 				       (one->sha1_valid ?
 					one->sha1 : null_sha1),
@@ -2219,7 +2219,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)
 				return;
 			}
 			if (lstat(one->path, &st) < 0)
-				die("stat %s", one->path);
+				die_errno("stat '%s'", one->path);
 			if (index_path(one->sha1, one->path, &st, 0))
 				die("cannot hash %s", one->path);
 		}
diff --git a/entry.c b/entry.c
index 8ec880b..d3e86c7 100644
--- a/entry.c
+++ b/entry.c
@@ -37,7 +37,7 @@ static void create_directories(const char *path, int path_len,
 			if (errno == EEXIST && state->force &&
 			    !unlink_or_warn(buf) && !mkdir(buf, 0777))
 				continue;
-			die("cannot create directory at %s", buf);
+			die_errno("cannot create directory at '%s'", buf);
 		}
 	}
 	free(buf);
diff --git a/fast-import.c b/fast-import.c
index d31a4e8..7ef9865 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)
 
 	keep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);
 	if (keep_fd < 0)
-		die("cannot create keep file");
+		die_errno("cannot create keep file");
 	write_or_die(keep_fd, keep_msg, strlen(keep_msg));
 	if (close(keep_fd))
-		die("failed to write keep file");
+		die_errno("failed to write keep file");
 
 	snprintf(name, sizeof(name), "%s/pack/pack-%s.pack",
 		 get_object_directory(), sha1_to_hex(pack_data->sha1));
diff --git a/hash-object.c b/hash-object.c
index 47cf43c..9455dd0 100644
--- a/hash-object.c
+++ b/hash-object.c
@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,
 	int fd;
 	fd = open(path, O_RDONLY);
 	if (fd < 0)
-		die("Cannot open %s", path);
+		die_errno("Cannot open '%s'", path);
 	hash_fd(fd, type, write_object, vpath);
 }
 
diff --git a/ll-merge.c b/ll-merge.c
index 9168958..dad795a 100644
--- a/ll-merge.c
+++ b/ll-merge.c
@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, src->ptr, src->size) != src->size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 }
 
diff --git a/mktag.c b/mktag.c
index 99a356e..a609e3e 100644
--- a/mktag.c
+++ b/mktag.c
@@ -165,7 +165,7 @@ int main(int argc, char **argv)
 	setup_git_directory();
 
 	if (strbuf_read(&buf, 0, 4096) < 0) {
-		die("could not read from stdin");
+		die_errno("could not read from stdin");
 	}
 
 	/* Verify it for some basic sanity: it needs to start with
diff --git a/read-cache.c b/read-cache.c
index f76b5bb..4e3e272 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)
 	mmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
 	close(fd);
 	if (mmap == MAP_FAILED)
-		die("unable to map index file");
+		die_errno("unable to map index file");
 
 	hdr = mmap;
 	if (verify_hdr(hdr, mmap_size) < 0)
diff --git a/setup.c b/setup.c
index 4d27f28..e3781b6 100644
--- a/setup.c
+++ b/setup.c
@@ -327,7 +327,7 @@ static int check_repository_format_gently(int *nongit_ok)
 				return NULL;
 			set_git_dir(make_absolute_path(gitdirenv));
 			if (chdir(work_tree_env) < 0)
-				die ("Could not chdir to %s", work_tree_env);
+				die_errno ("Could not chdir to '%s'", work_tree_env);
 			strcat(buffer, "/");
 			return retval;
 		}
@@ -339,7 +339,7 @@ static int check_repository_format_gently(int *nongit_ok)
 	}
 
 	if (!getcwd(cwd, sizeof(cwd)-1))
-		die("Unable to read current working directory");
+		die_errno("Unable to read current working directory");
 
 	ceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);
 	if (ceil_offset < 0 && has_dos_drive_prefix(cwd))
@@ -382,7 +382,7 @@ static int check_repository_format_gently(int *nongit_ok)
 		if (offset <= ceil_offset) {
 			if (nongit_ok) {
 				if (chdir(cwd))
-					die("Cannot come back to cwd");
+					die_errno("Cannot come back to cwd");
 				*nongit_ok = 1;
 				return NULL;
 			}
@@ -493,10 +493,10 @@ int check_repository_format(void)
 		static char buffer[PATH_MAX + 1];
 		char *rel;
 		if (retval && chdir(retval))
-			die ("Could not jump back into original cwd");
+			die_errno ("Could not jump back into original cwd");
 		rel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());
 		if (rel && *rel && chdir(get_git_work_tree()))
-			die ("Could not jump to working directory");
+			die_errno ("Could not jump to working directory");
 		return rel && *rel ? strcat(rel, "/") : NULL;
 	}
 
diff --git a/transport.c b/transport.c
index 501a77b..ccf788d 100644
--- a/transport.c
+++ b/transport.c
@@ -158,7 +158,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	temp_dir_len = temp_dir.len;
 
 	strbuf_addstr(&buf, rsync_url(transport->url));
@@ -321,7 +321,7 @@ static int rsync_transport_push(struct transport *transport,
 
 	strbuf_addstr(&temp_dir, git_path("rsync-refs-XXXXXX"));
 	if (!mkdtemp(temp_dir.buf))
-		die ("Could not make temporary directory");
+		die_errno ("Could not make temporary directory");
 	strbuf_addch(&temp_dir, '/');
 
 	if (flags & TRANSPORT_PUSH_ALL) {
diff --git a/unpack-file.c b/unpack-file.c
index 75cd2f1..ac9cbf7 100644
--- a/unpack-file.c
+++ b/unpack-file.c
@@ -17,7 +17,7 @@
 	strcpy(path, ".merge_file_XXXXXX");
 	fd = xmkstemp(path);
 	if (write_in_full(fd, buf, size) != size)
-		die("unable to write temp-file");
+		die_errno("unable to write temp-file");
 	close(fd);
 	return path;
 }
-- 
1.6.3.3.433.gc91b

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH v4 0/4] die_errno()
  2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
                             ` (3 preceding siblings ...)
  2009-06-27 15:58           ` [PATCH v4 4/4] Use die_errno() instead of die() when checking syscalls Thomas Rast
@ 2009-06-27 18:38           ` Junio C Hamano
  4 siblings, 0 replies; 42+ messages in thread
From: Junio C Hamano @ 2009-06-27 18:38 UTC (permalink / raw)
  To: Thomas Rast
  Cc: Junio C Hamano, git, Johannes Sixt, Jeff King, Alexander Potashev

Thomas Rast <trast@student.ethz.ch> writes:

> This just picks up Junio's %-doubling patch from pu, with the extra
> change I suggested in <200906121204.37752.trast@student.ethz.ch> to
> handle the border case where a lone % would end up at the end of the
> buffer.  The rest is the same as v3.

Thanks.  Will queue.

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2009-06-27 18:38 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-06-02 21:34 [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
2009-06-03  1:55 ` Jeff King
     [not found]   ` <2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com>
2009-06-04  1:58     ` Alexander Potashev
2009-06-04 20:32       ` Jeff King
2009-06-04  2:05   ` [PATCH] diesys calls die and also reports strerror(errno) Alexander Potashev
2009-06-04 20:50     ` Jeff King
2009-06-04 21:13       ` Junio C Hamano
2009-06-05  6:25       ` Johannes Sixt
2009-06-05  7:12         ` Junio C Hamano
2009-06-06 22:09           ` Jeff King
2009-06-06 13:09   ` [PATCH] add strerror(errno) to die() calls where applicable Thomas Rast
2009-06-06 14:44     ` [PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch> Thomas Rast
2009-06-08 21:02       ` [PATCH v3 0/3] die_errno() Thomas Rast
2009-06-27 15:58         ` [PATCH v4 0/4] die_errno() Thomas Rast
2009-06-27 15:58           ` [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
2009-06-27 15:58           ` [PATCH v4 2/4] die_errno(): double % in strerror() output just in case Thomas Rast
2009-06-27 15:58           ` [PATCH v4 3/4] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
2009-06-27 15:58           ` [PATCH v4 4/4] Use die_errno() instead of die() when checking syscalls Thomas Rast
2009-06-27 18:38           ` [PATCH v4 0/4] die_errno() Junio C Hamano
2009-06-08 21:02       ` [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
2009-06-08 22:07         ` Jeff King
2009-06-09  8:22           ` Thomas Rast
2009-06-09  8:53             ` Jeff King
2009-06-09  9:29               ` Andreas Ericsson
2009-06-08 21:02       ` [PATCH v3 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
2009-06-08 21:02       ` [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
2009-06-06 14:44     ` [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die() Thomas Rast
2009-06-06 20:36       ` Johannes Sixt
2009-06-06 20:56         ` Thomas Rast
2009-06-06 21:17           ` Johannes Sixt
2009-06-06 22:47           ` Jeff King
2009-06-06 22:13       ` Jeff King
2009-06-07 11:12         ` Alexander Potashev
2009-06-07 16:57           ` Junio C Hamano
2009-06-08 12:36             ` Jeff King
2009-06-08 15:35               ` Alexander Potashev
2009-06-08 22:04                 ` Jeff King
2009-06-06 14:44     ` [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno() Thomas Rast
2009-06-06 20:31       ` Johannes Sixt
2009-06-06 14:44     ` [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls Thomas Rast
2009-06-06 21:02       ` Johannes Sixt
2009-06-06 22:27         ` Thomas Rast

Code repositories for project(s) associated with this inbox:

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).