# [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls

14 messages from 2009-06-08 to 2009-06-27. Participants: Thomas Rast, Jeff King, Andreas Ericsson, Junio C Hamano.
Thread: https://gitlist.dev/t/19751

## Thomas Rast, 2009-06-08 21:02

Subject: [PATCH v3 0/3] die_errno()
Message-ID: <cover.1244494646.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/cover.1244494646.git.trast%40student.ethz.ch
In-Reply-To: <cover.1244299302.git.trast@student.ethz.ch>

```
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(-)

```

## Thomas Rast, 2009-06-08 21:02

Subject: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <5f43aa9d0b69e99600a73bddd4c93217608ab661.1244494647.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/5f43aa9d0b69e99600a73bddd4c93217608ab661.1244494647.git.trast%40student.ethz.ch
In-Reply-To: <cover.1244494646.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-08 21:02

Subject: [PATCH v3 2/3] Convert existing die(..., strerror(errno)) to die_errno()
Message-ID: <5a74ed8a911fc1048c021bc3b42e679526bc4c8e.1244494647.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/5a74ed8a911fc1048c021bc3b42e679526bc4c8e.1244494647.git.trast%40student.ethz.ch
In-Reply-To: <5f43aa9d0b69e99600a73bddd4c93217608ab661.1244494647.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-08 21:02

Subject: [PATCH v3 3/3] Use die_errno() instead of die() when checking syscalls
Message-ID: <00748543db1ade0ba92fc4a23038efa538b209d3.1244494647.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/00748543db1ade0ba92fc4a23038efa538b209d3.1244494647.git.trast%40student.ethz.ch
In-Reply-To: <5a74ed8a911fc1048c021bc3b42e679526bc4c8e.1244494647.git.trast@student.ethz.ch>

```
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

```

## Jeff King, 2009-06-08 22:07

Subject: Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <20090608220713.GB29942@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20090608220713.GB29942%40sigill.intra.peff.net
In-Reply-To: <5f43aa9d0b69e99600a73bddd4c93217608ab661.1244494647.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-09 08:22

Subject: Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <200906091022.31738.trast@student.ethz.ch>
URL: https://gitlist.dev/e/200906091022.31738.trast%40student.ethz.ch
In-Reply-To: <20090608220713.GB29942@sigill.intra.peff.net>

```
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

```

## Jeff King, 2009-06-09 08:53

Subject: Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <20090609085328.GA25721@coredump.intra.peff.net>
URL: https://gitlist.dev/e/20090609085328.GA25721%40coredump.intra.peff.net
In-Reply-To: <200906091022.31738.trast@student.ethz.ch>

```
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

```

## Andreas Ericsson, 2009-06-09 09:29

Subject: Re: [PATCH v3 1/3] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <4A2E2B8F.3020005@op5.se>
URL: https://gitlist.dev/e/4A2E2B8F.3020005%40op5.se
In-Reply-To: <20090609085328.GA25721@coredump.intra.peff.net>

```
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.

```

## Thomas Rast, 2009-06-27 15:58

Subject: [PATCH v4 0/4] die_errno()
Message-ID: <cover.1246115204.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/cover.1246115204.git.trast%40student.ethz.ch
In-Reply-To: <cover.1244494646.git.trast@student.ethz.ch>

```
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(-)

```

## Thomas Rast, 2009-06-27 15:58

Subject: [PATCH v4 1/4] Introduce die_errno() that appends strerror(errno) to die()
Message-ID: <352b76f4c7b442cae5c16451396ad129d25ef29a.1246115205.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/352b76f4c7b442cae5c16451396ad129d25ef29a.1246115205.git.trast%40student.ethz.ch
In-Reply-To: <cover.1246115204.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-27 15:58

Subject: [PATCH v4 2/4] die_errno(): double % in strerror() output just in case
Message-ID: <c3635ed5bd260b5f358893917d05bd09320ae9d6.1246115205.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/c3635ed5bd260b5f358893917d05bd09320ae9d6.1246115205.git.trast%40student.ethz.ch
In-Reply-To: <cover.1246115204.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-27 15:58

Subject: [PATCH v4 3/4] Convert existing die(..., strerror(errno)) to die_errno()
Message-ID: <4cdc708912562f284a5561bdd862828db169cda6.1246115205.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/4cdc708912562f284a5561bdd862828db169cda6.1246115205.git.trast%40student.ethz.ch
In-Reply-To: <cover.1246115204.git.trast@student.ethz.ch>

```
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

```

## Thomas Rast, 2009-06-27 15:58

Subject: [PATCH v4 4/4] Use die_errno() instead of die() when checking syscalls
Message-ID: <872dc06da0f72fc1f73f3d14e303ccc922504863.1246115205.git.trast@student.ethz.ch>
URL: https://gitlist.dev/e/872dc06da0f72fc1f73f3d14e303ccc922504863.1246115205.git.trast%40student.ethz.ch
In-Reply-To: <cover.1246115204.git.trast@student.ethz.ch>

```
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

```

## Junio C Hamano, 2009-06-27 18:38

Subject: Re: [PATCH v4 0/4] die_errno()
Message-ID: <7vhby1iksv.fsf@alter.siamese.dyndns.org>
URL: https://gitlist.dev/e/7vhby1iksv.fsf%40alter.siamese.dyndns.org
In-Reply-To: <cover.1246115204.git.trast@student.ethz.ch>

```
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.

```
