{"thread":{"id":"19644","subject":"[PATCH] add strerror(errno) to die() calls where applicable","startedAt":"2009-06-02T21:34:33Z","lastAt":"2009-06-08T22:04:24Z","messageCount":28,"participants":["Thomas Rast","Jeff King","Alexander Potashev","Junio C Hamano","Johannes Sixt"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"115282","messageId":"8df45fb3586160fa5c47af39d2a7eb2b8d405a3c.1243978065.git.trast@student.ethz.ch","threadId":"19644","inReplyTo":null,"subject":"[PATCH] add strerror(errno) to die() calls where applicable","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-02T21:34:33Z","receivedAt":"2009-06-02T21:34:33Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Lots of die() calls did not actually report the kind of error, which\ncan leave the user confused as to the real problem.  Add a\nstrerror(errno) where the die() is immediately preceded by a\nsystem/library call that sets errno on failure, or by one of the\nfollowing that wrap such calls:\n\n  odb_pack_keep\n  read_ancestry\n  read_in_full\n  strbuf_read\n  strbuf_read_file\n  strbuf_readlink\n  write_buffer\n  write_in_full\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n abspath.c               |   17 +++++++++++------\n builtin-add.c           |    2 +-\n builtin-apply.c         |    8 ++++----\n builtin-archive.c       |    5 +++--\n builtin-blame.c         |   16 ++++++++++------\n builtin-clone.c         |   16 ++++++++++------\n builtin-commit.c        |   15 +++++++++------\n builtin-fast-export.c   |    5 +++--\n builtin-fmt-merge-msg.c |    2 +-\n builtin-fsck.c          |    7 ++++---\n builtin-init-db.c       |   27 +++++++++++++++++----------\n builtin-log.c           |    4 ++--\n builtin-mailsplit.c     |    7 ++++---\n builtin-merge.c         |   25 ++++++++++++++++---------\n builtin-rev-parse.c     |    3 ++-\n builtin-revert.c        |    2 +-\n builtin-stripspace.c    |    2 +-\n builtin-tag.c           |    3 ++-\n builtin-tar-tree.c      |    2 +-\n combine-diff.c          |    3 ++-\n diff.c                  |    6 +++---\n entry.c                 |    3 ++-\n fast-import.c           |    4 ++--\n hash-object.c           |    2 +-\n ll-merge.c              |    2 +-\n mktag.c                 |    2 +-\n read-cache.c            |    2 +-\n setup.c                 |   15 ++++++++++-----\n sha1_file.c             |    2 +-\n transport.c             |    6 ++++--\n unpack-file.c           |    2 +-\n 31 files changed, 131 insertions(+), 86 deletions(-)\n\ndiff --git a/abspath.c b/abspath.c\nindex 649f34f..7fff78f 100644\n--- a/abspath.c\n+++ b/abspath.c\n@@ -41,13 +41,16 @@ int is_directory(const char *path)\n \n \t\tif (*buf) {\n \t\t\tif (!*cwd && !getcwd(cwd, sizeof(cwd)))\n-\t\t\t\tdie (\"Could not get current working directory\");\n+\t\t\t\tdie (\"Could not get current working directory: %s\",\n+\t\t\t\t     strerror(errno));\n \n \t\t\tif (chdir(buf))\n-\t\t\t\tdie (\"Could not switch to '%s'\", buf);\n+\t\t\t\tdie (\"Could not switch to '%s': %s\", buf,\n+\t\t\t\t     strerror(errno));\n \t\t}\n \t\tif (!getcwd(buf, PATH_MAX))\n-\t\t\tdie (\"Could not get current working directory\");\n+\t\t\tdie (\"Could not get current working directory: %s\",\n+\t\t\t     strerror(errno));\n \n \t\tif (last_elem) {\n \t\t\tint len = strlen(buf);\n@@ -63,7 +66,8 @@ int is_directory(const char *path)\n \t\tif (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {\n \t\t\tlen = readlink(buf, next_buf, PATH_MAX);\n \t\t\tif (len < 0)\n-\t\t\t\tdie (\"Invalid symlink: %s\", buf);\n+\t\t\t\tdie (\"Invalid symlink '%s': %s\", buf,\n+\t\t\t\t     strerror(errno));\n \t\t\tif (PATH_MAX <= len)\n \t\t\t\tdie(\"symbolic link too long: %s\", buf);\n \t\t\tnext_buf[len] = '\\0';\n@@ -75,7 +79,7 @@ int is_directory(const char *path)\n \t}\n \n \tif (*cwd && chdir(cwd))\n-\t\tdie (\"Could not change back to '%s'\", cwd);\n+\t\tdie (\"Could not change back to '%s': %s\", cwd, strerror(errno));\n \n \treturn buf;\n }\n@@ -109,7 +113,8 @@ int is_directory(const char *path)\n \t} else {\n \t\tconst char *cwd = get_pwd_cwd();\n \t\tif (!cwd)\n-\t\t\tdie(\"Cannot determine the current working directory\");\n+\t\t\tdie(\"Cannot determine the current working directory\",\n+\t\t\t    strerror(errno));\n \t\tif (snprintf(buf, PATH_MAX, \"%s/%s\", cwd, path) >= PATH_MAX)\n \t\t\tdie(\"Too long path: %.*s\", 60, path);\n \t}\ndiff --git a/builtin-add.c b/builtin-add.c\nindex c1b229a..88c6672 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -220,7 +220,7 @@ int edit_patch(int argc, const char **argv, const char *prefix)\n \tlaunch_editor(file, NULL, NULL);\n \n \tif (stat(file, &st))\n-\t\tdie(\"Could not stat '%s'\", file);\n+\t\tdie(\"Could not stat '%s': %s\", file, strerror(errno));\n \tif (!st.st_size)\n \t\tdie(\"Empty patch. Aborted.\");\n \ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 94ba2bd..1ea5113 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned \n \t} else {\n \t\tif (!cached) {\n \t\t\tif (lstat(path, &st) < 0)\n-\t\t\t\tdie(\"unable to stat newly created file %s\",\n-\t\t\t\t    path);\n+\t\t\t\tdie(\"unable to stat newly created file '%s': %s\",\n+\t\t\t\t    path, strerror(errno));\n \t\t\tfill_stat_cache_info(ce, &st);\n \t\t}\n \t\tif (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)\n@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n \tstrbuf_release(&nbuf);\n \n \tif (close(fd) < 0)\n-\t\tdie(\"closing file %s: %s\", path, strerror(errno));\n+\t\tdie(\"closing file '%s': %s\", path, strerror(errno));\n \treturn 0;\n }\n \n@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned\n \t\t\t++nr;\n \t\t}\n \t}\n-\tdie(\"unable to write file %s mode %o\", path, mode);\n+\tdie(\"unable to write file '%s' mode %o: %s\", path, mode, strerror(errno));\n }\n \n static void create_file(struct patch *patch)\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex 3c5a5a7..10877ef 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -13,10 +13,11 @@ static void create_output_file(const char *output_file)\n {\n \tint output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n \tif (output_fd < 0)\n-\t\tdie(\"could not create archive file: %s \", output_file);\n+\t\tdie(\"could not create archive file '%s': %s\", output_file,\n+\t\t    strerror(errno));\n \tif (output_fd != 1) {\n \t\tif (dup2(output_fd, 1) < 0)\n-\t\t\tdie(\"could not redirect output\");\n+\t\t\tdie(\"could not redirect output: %s\", strerror(errno));\n \t\telse\n \t\t\tclose(output_fd);\n \t}\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 9dc3335..e5b465e 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -1998,23 +1998,27 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n \n \t\tif (contents_from) {\n \t\t\tif (stat(contents_from, &st) < 0)\n-\t\t\t\tdie(\"Cannot stat %s\", contents_from);\n+\t\t\t\tdie(\"Cannot stat '%s': %s\", contents_from,\n+\t\t\t\t    strerror(errno));\n \t\t\tread_from = contents_from;\n \t\t}\n \t\telse {\n \t\t\tif (lstat(path, &st) < 0)\n-\t\t\t\tdie(\"Cannot lstat %s\", path);\n+\t\t\t\tdie(\"Cannot lstat '%s': %s\", path,\n+\t\t\t\t    strerror(errno));\n \t\t\tread_from = path;\n \t\t}\n \t\tmode = canon_mode(st.st_mode);\n \t\tswitch (st.st_mode & S_IFMT) {\n \t\tcase S_IFREG:\n \t\t\tif (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)\n-\t\t\t\tdie(\"cannot open or read %s\", read_from);\n+\t\t\t\tdie(\"cannot open or read '%s': %s\", read_from,\n+\t\t\t\t    strerror(errno));\n \t\t\tbreak;\n \t\tcase S_IFLNK:\n \t\t\tif (strbuf_readlink(&buf, read_from, st.st_size) < 0)\n-\t\t\t\tdie(\"cannot readlink %s\", read_from);\n+\t\t\t\tdie(\"cannot readlink '%s': %s\", read_from,\n+\t\t\t\t    strerror(errno));\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tdie(\"unsupported file type %s\", read_from);\n@@ -2251,7 +2255,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \targc = parse_options_end(&ctx);\n \n \tif (revs_file && read_ancestry(revs_file))\n-\t\tdie(\"reading graft file %s failed: %s\",\n+\t\tdie(\"reading graft file '%s' failed: %s\",\n \t\t    revs_file, strerror(errno));\n \n \tif (cmd_is_annotate) {\n@@ -2340,7 +2344,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \n \t\tsetup_work_tree();\n \t\tif (!has_string_in_work_tree(path))\n-\t\t\tdie(\"cannot stat path %s: %s\", path, strerror(errno));\n+\t\t\tdie(\"cannot stat path '%s': %s\", path, strerror(errno));\n \t}\n \n \tsetup_revisions(argc, argv, &revs, NULL);\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex 5c46496..a175ed1 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -220,13 +220,15 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)\n \n \tdir = opendir(src->buf);\n \tif (!dir)\n-\t\tdie(\"failed to open %s\", src->buf);\n+\t\tdie(\"failed to open '%s': %s\", src->buf, strerror(errno));\n \n \tif (mkdir(dest->buf, 0777)) {\n \t\tif (errno != EEXIST)\n-\t\t\tdie(\"failed to create directory %s\", dest->buf);\n+\t\t\tdie(\"failed to create directory '%s': %s\", dest->buf,\n+\t\t\t    strerror(errno));\n \t\telse if (stat(dest->buf, &buf))\n-\t\t\tdie(\"failed to stat %s\", dest->buf);\n+\t\t\tdie(\"failed to stat '%s': %s\", dest->buf,\n+\t\t\t    strerror(errno));\n \t\telse if (!S_ISDIR(buf.st_mode))\n \t\t\tdie(\"%s exists and is not a directory\", dest->buf);\n \t}\n@@ -252,17 +254,19 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)\n \t\t}\n \n \t\tif (unlink(dest->buf) && errno != ENOENT)\n-\t\t\tdie(\"failed to unlink %s: %s\",\n+\t\t\tdie(\"failed to unlink '%s': %s\",\n \t\t\t    dest->buf, strerror(errno));\n \t\tif (!option_no_hardlinks) {\n \t\t\tif (!link(src->buf, dest->buf))\n \t\t\t\tcontinue;\n \t\t\tif (option_local)\n-\t\t\t\tdie(\"failed to create link %s\", dest->buf);\n+\t\t\t\tdie(\"failed to create link '%s': %s\", dest->buf,\n+\t\t\t\t    strerror(errno));\n \t\t\toption_no_hardlinks = 1;\n \t\t}\n \t\tif (copy_file(dest->buf, src->buf, 0666))\n-\t\t\tdie(\"failed to copy file to %s\", dest->buf);\n+\t\t\tdie(\"failed to copy file to '%s': %s\", dest->buf,\n+\t\t\t    strerror(errno));\n \t}\n \tclosedir(dir);\n }\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex 41e222d..c21c16b 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -434,7 +434,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t\tif (isatty(0))\n \t\t\tfprintf(stderr, \"(reading log message from standard input)\\n\");\n \t\tif (strbuf_read(&sb, 0, 0) < 0)\n-\t\t\tdie(\"could not read log from standard input\");\n+\t\t\tdie(\"could not read log from standard input: %s\",\n+\t\t\t    strerror(errno));\n \t\thook_arg1 = \"message\";\n \t} else if (logfile) {\n \t\tif (strbuf_read_file(&sb, logfile, 0) < 0)\n@@ -458,7 +459,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t\thook_arg1 = \"squash\";\n \t} else if (template_file && !stat(template_file, &statbuf)) {\n \t\tif (strbuf_read_file(&sb, template_file, 0) < 0)\n-\t\t\tdie(\"could not read %s: %s\",\n+\t\t\tdie(\"could not read '%s': %s\",\n \t\t\t    template_file, strerror(errno));\n \t\thook_arg1 = \"template\";\n \t}\n@@ -472,7 +473,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \n \tfp = fopen(git_path(commit_editmsg), \"w\");\n \tif (fp == NULL)\n-\t\tdie(\"could not open %s: %s\",\n+\t\tdie(\"could not open '%s': %s\",\n \t\t    git_path(commit_editmsg), strerror(errno));\n \n \tif (cleanup_mode != CLEANUP_NONE)\n@@ -968,7 +969,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \tstrbuf_reset(&sb);\n \tif (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {\n \t\trollback_index_files();\n-\t\tdie(\"could not read commit message\");\n+\t\tdie(\"could not read commit message: %s\", strerror(errno));\n \t}\n \n \t/* Truncate the message just before the diff, if any. */\n@@ -1021,8 +1022,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \n \tif (commit_index_files())\n \t\tdie (\"Repository has been updated, but unable to write\\n\"\n-\t\t     \"new_index file. Check that disk is not full or quota is\\n\"\n-\t\t     \"not exceeded, and then \\\"git reset HEAD\\\" to recover.\");\n+\t\t     \"new_index file: %s.\\n\"\n+\t\t     \"Check that disk is not full or quota is not exceeded,\\n\"\n+\t\t     \"and then \\\"git reset HEAD\\\" to recover.\",\n+\t\t     strerror(errno));\n \n \trerere();\n \trun_hook(get_index_file(), \"post-commit\", NULL);\ndiff --git a/builtin-fast-export.c b/builtin-fast-export.c\nindex 6cef810..45a3ec8 100644\n--- a/builtin-fast-export.c\n+++ b/builtin-fast-export.c\n@@ -119,7 +119,8 @@ static void handle_object(const unsigned char *sha1)\n \n \tprintf(\"blob\\nmark :%\"PRIu32\"\\ndata %lu\\n\", last_idnum, size);\n \tif (size && fwrite(buf, size, 1, stdout) != 1)\n-\t\tdie (\"Could not write blob %s\", sha1_to_hex(sha1));\n+\t\tdie (\"Could not write blob '%s': %s\", sha1_to_hex(sha1),\n+\t\t     strerror(errno));\n \tprintf(\"\\n\");\n \n \tshow_progress();\n@@ -451,7 +452,7 @@ static void import_marks(char *input_file)\n \tchar line[512];\n \tFILE *f = fopen(input_file, \"r\");\n \tif (!f)\n-\t\tdie(\"cannot read %s: %s\", input_file, strerror(errno));\n+\t\tdie(\"cannot read '%s': %s\", input_file, strerror(errno));\n \n \twhile (fgets(line, sizeof(line), f)) {\n \t\tuint32_t mark;\ndiff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c\nindex fbf9582..051f4a4 100644\n--- a/builtin-fmt-merge-msg.c\n+++ b/builtin-fmt-merge-msg.c\n@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \tif (inpath && strcmp(inpath, \"-\")) {\n \t\tin = fopen(inpath, \"r\");\n \t\tif (!in)\n-\t\t\tdie(\"cannot open %s\", inpath);\n+\t\t\tdie(\"cannot open '%s': %s\", inpath, strerror(errno));\n \t}\n \n \tif (strbuf_read(&input, fileno(in), 0) < 0)\ndiff --git a/builtin-fsck.c b/builtin-fsck.c\nindex 7da706c..e22f1a4 100644\n--- a/builtin-fsck.c\n+++ b/builtin-fsck.c\n@@ -217,7 +217,8 @@ static void check_unreachable_object(struct object *obj)\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (!(f = fopen(filename, \"w\")))\n-\t\t\t\tdie(\"Could not open %s\", filename);\n+\t\t\t\tdie(\"Could not open '%s': %s\", filename,\n+\t\t\t\t    strerror(errno));\n \t\t\tif (obj->type == OBJ_BLOB) {\n \t\t\t\tenum object_type type;\n \t\t\t\tunsigned long size;\n@@ -225,14 +226,14 @@ static void check_unreachable_object(struct object *obj)\n \t\t\t\t\t\t&type, &size);\n \t\t\t\tif (buf) {\n \t\t\t\t\tif (fwrite(buf, size, 1, f) != 1)\n-\t\t\t\t\t\tdie(\"Could not write %s: %s\",\n+\t\t\t\t\t\tdie(\"Could not write '%s': %s\",\n \t\t\t\t\t\t    filename, strerror(errno));\n \t\t\t\t\tfree(buf);\n \t\t\t\t}\n \t\t\t} else\n \t\t\t\tfprintf(f, \"%s\\n\", sha1_to_hex(obj->sha1));\n \t\t\tif (fclose(f))\n-\t\t\t\tdie(\"Could not finish %s: %s\",\n+\t\t\t\tdie(\"Could not finish '%s': %s\",\n \t\t\t\t    filename, strerror(errno));\n \t\t}\n \t\treturn;\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex d1fa12a..4cdeb21 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -61,20 +61,23 @@ static void copy_templates_1(char *path, int baselen,\n \t\tmemcpy(template + template_baselen, de->d_name, namelen+1);\n \t\tif (lstat(path, &st_git)) {\n \t\t\tif (errno != ENOENT)\n-\t\t\t\tdie(\"cannot stat %s\", path);\n+\t\t\t\tdie(\"cannot stat '%s': %s\", path,\n+\t\t\t\t    strerror(errno));\n \t\t}\n \t\telse\n \t\t\texists = 1;\n \n \t\tif (lstat(template, &st_template))\n-\t\t\tdie(\"cannot stat template %s\", template);\n+\t\t\tdie(\"cannot stat template '%s': %s\", template,\n+\t\t\t    strerror(errno));\n \n \t\tif (S_ISDIR(st_template.st_mode)) {\n \t\t\tDIR *subdir = opendir(template);\n \t\t\tint baselen_sub = baselen + namelen;\n \t\t\tint template_baselen_sub = template_baselen + namelen;\n \t\t\tif (!subdir)\n-\t\t\t\tdie(\"cannot opendir %s\", template);\n+\t\t\t\tdie(\"cannot opendir '%s': %s\", template,\n+\t\t\t\t    strerror(errno));\n \t\t\tpath[baselen_sub++] =\n \t\t\t\ttemplate[template_baselen_sub++] = '/';\n \t\t\tpath[baselen_sub] =\n@@ -91,16 +94,19 @@ static void copy_templates_1(char *path, int baselen,\n \t\t\tint len;\n \t\t\tlen = readlink(template, lnk, sizeof(lnk));\n \t\t\tif (len < 0)\n-\t\t\t\tdie(\"cannot readlink %s\", template);\n+\t\t\t\tdie(\"cannot readlink '%s': %s\", template,\n+\t\t\t\t    strerror(errno));\n \t\t\tif (sizeof(lnk) <= len)\n \t\t\t\tdie(\"insanely long symlink %s\", template);\n \t\t\tlnk[len] = 0;\n \t\t\tif (symlink(lnk, path))\n-\t\t\t\tdie(\"cannot symlink %s %s\", lnk, path);\n+\t\t\t\tdie(\"cannot symlink '%s' '%s': %s\", lnk, path,\n+\t\t\t\t    strerror(errno));\n \t\t}\n \t\telse if (S_ISREG(st_template.st_mode)) {\n \t\t\tif (copy_file(path, template, st_template.st_mode))\n-\t\t\t\tdie(\"cannot copy %s to %s\", template, path);\n+\t\t\t\tdie(\"cannot copy '%s' to '%s': %s\", template,\n+\t\t\t\t    path, strerror(errno));\n \t\t}\n \t\telse\n \t\t\terror(\"ignoring template %s\", template);\n@@ -350,7 +356,7 @@ static int guess_repository_type(const char *git_dir)\n \tif (!strcmp(\".\", git_dir))\n \t\treturn 1;\n \tif (!getcwd(cwd, sizeof(cwd)))\n-\t\tdie(\"cannot tell cwd\");\n+\t\tdie(\"cannot tell cwd: %s\", strerror(errno));\n \tif (!strcmp(git_dir, cwd))\n \t\treturn 1;\n \t/*\n@@ -440,11 +446,12 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\tif (!git_work_tree_cfg) {\n \t\t\tgit_work_tree_cfg = xcalloc(PATH_MAX, 1);\n \t\t\tif (!getcwd(git_work_tree_cfg, PATH_MAX))\n-\t\t\t\tdie (\"Cannot access current working directory.\");\n+\t\t\t\tdie (\"Cannot access current working directory: %s\",\n+\t\t\t\t     strerror(errno));\n \t\t}\n \t\tif (access(get_git_work_tree(), X_OK))\n-\t\t\tdie (\"Cannot access work tree '%s'\",\n-\t\t\t     get_git_work_tree());\n+\t\t\tdie (\"Cannot access work tree '%s': %s\",\n+\t\t\t     get_git_work_tree(), strerror(errno));\n \t}\n \n \tset_git_dir(make_absolute_path(git_dir));\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 0d34050..76cb3e2 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\tif (use_stdout)\n \t\t\tdie(\"standard output, or directory, which one?\");\n \t\tif (mkdir(output_directory, 0777) < 0 && errno != EEXIST)\n-\t\t\tdie(\"Could not create directory %s\",\n-\t\t\t    output_directory);\n+\t\t\tdie(\"Could not create directory '%s': %s\",\n+\t\t\t    output_directory, strerror(errno));\n \t}\n \n \tif (rev.pending.nr == 1) {\ndiff --git a/builtin-mailsplit.c b/builtin-mailsplit.c\nindex 71f3b3b..30c4e6f 100644\n--- a/builtin-mailsplit.c\n+++ b/builtin-mailsplit.c\n@@ -81,7 +81,8 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)\n \n \tfd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);\n \tif (fd < 0)\n-\t\tdie(\"cannot open output file %s\", name);\n+\t\tdie(\"cannot open output file '%s': %s\", name,\n+\t\t    strerror(errno));\n \toutput = fdopen(fd, \"w\");\n \n \t/* Copy it out, while searching for a line that begins with\n@@ -91,7 +92,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)\n \t\tint is_partial = len && buf[len-1] != '\\n';\n \n \t\tif (fwrite(buf, 1, len, output) != len)\n-\t\t\tdie(\"cannot write output\");\n+\t\t\tdie(\"cannot write output: %s\", strerror(errno));\n \n \t\tlen = read_line_with_nul(buf, sizeof(buf), mbox);\n \t\tif (len == 0) {\n@@ -99,7 +100,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)\n \t\t\t\tstatus = 1;\n \t\t\t\tbreak;\n \t\t\t}\n-\t\t\tdie(\"cannot read mbox\");\n+\t\t\tdie(\"cannot read mbox: %s\", strerror(errno));\n \t\t}\n \t\tif (!is_partial && !is_bare && is_from_line(buf, len))\n \t\t\tbreak; /* done with one message */\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex 8d101ef..4bac88e 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -268,7 +268,8 @@ static void squash_message(void)\n \tprintf(\"Squash commit -- not updating HEAD\\n\");\n \tfd = open(git_path(\"SQUASH_MSG\"), O_WRONLY | O_CREAT, 0666);\n \tif (fd < 0)\n-\t\tdie(\"Could not write to %s\", git_path(\"SQUASH_MSG\"));\n+\t\tdie(\"Could not write to '%s': %s\", git_path(\"SQUASH_MSG\"),\n+\t\t    strerror(errno));\n \n \tinit_revisions(&rev, NULL);\n \trev.ignore_merges = 1;\n@@ -764,7 +765,8 @@ static int suggest_conflicts(void)\n \n \tfp = fopen(git_path(\"MERGE_MSG\"), \"a\");\n \tif (!fp)\n-\t\tdie(\"Could not open %s for writing\", git_path(\"MERGE_MSG\"));\n+\t\tdie(\"Could not open '%s' for writing: %s\", git_path(\"MERGE_MSG\"),\n+\t\t    strerror(errno));\n \tfprintf(fp, \"\\nConflicts:\\n\");\n \tfor (pos = 0; pos < active_nr; pos++) {\n \t\tstruct cache_entry *ce = active_cache[pos];\n@@ -1186,27 +1188,32 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\tsha1_to_hex(j->item->object.sha1));\n \t\tfd = open(git_path(\"MERGE_HEAD\"), O_WRONLY | O_CREAT, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\",\n-\t\t\t\tgit_path(\"MERGE_HEAD\"));\n+\t\t\tdie(\"Could not open '%s' for writing: %s\",\n+\t\t\t    git_path(\"MERGE_HEAD\"), strerror(errno));\n \t\tif (write_in_full(fd, buf.buf, buf.len) != buf.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_HEAD\"));\n+\t\t\tdie(\"Could not write to '%s': %s\",\n+\t\t\t    git_path(\"MERGE_HEAD\"), strerror(errno));\n \t\tclose(fd);\n \t\tstrbuf_addch(&merge_msg, '\\n');\n \t\tfd = open(git_path(\"MERGE_MSG\"), O_WRONLY | O_CREAT, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\", git_path(\"MERGE_MSG\"));\n+\t\t\tdie(\"Could not open '%s' for writing: %s\",\n+\t\t\t    git_path(\"MERGE_MSG\"), strerror(errno));\n \t\tif (write_in_full(fd, merge_msg.buf, merge_msg.len) !=\n \t\t\tmerge_msg.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_MSG\"));\n+\t\t\tdie(\"Could not write to '%s': %s\",\n+\t\t\t    git_path(\"MERGE_MSG\"), strerror(errno));\n \t\tclose(fd);\n \t\tfd = open(git_path(\"MERGE_MODE\"), O_WRONLY | O_CREAT | O_TRUNC, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\", git_path(\"MERGE_MODE\"));\n+\t\t\tdie(\"Could not open '%s' for writing\",\n+\t\t\t    git_path(\"MERGE_MODE\"), strerror(errno));\n \t\tstrbuf_reset(&buf);\n \t\tif (!allow_fast_forward)\n \t\t\tstrbuf_addf(&buf, \"no-ff\");\n \t\tif (write_in_full(fd, buf.buf, buf.len) != buf.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_MODE\"));\n+\t\t\tdie(\"Could not write to '%s': %s\",\n+\t\t\t    git_path(\"MERGE_MODE\"), strerror(errno));\n \t\tclose(fd);\n \t}\n \ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex 112d622..bbc21f8 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -592,7 +592,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \t\t\t\tif (!getcwd(cwd, PATH_MAX))\n-\t\t\t\t\tdie(\"unable to get current working directory\");\n+\t\t\t\t\tdie(\"unable to get current working directory: %s\",\n+\t\t\t\t\t    strerror(errno));\n \t\t\t\tprintf(\"%s/.git\\n\", cwd);\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/builtin-revert.c b/builtin-revert.c\nindex c87115a..a82c4b8 100644\n--- a/builtin-revert.c\n+++ b/builtin-revert.c\n@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)\n {\n \tint len = strlen(string);\n \tif (write_in_full(msg_fd, string, len) < 0)\n-\t\tdie (\"Could not write to MERGE_MSG\");\n+\t\tdie (\"Could not write to MERGE_MSG: %s\", strerror(errno));\n }\n \n static void add_message_to_msg(const char *message)\ndiff --git a/builtin-stripspace.c b/builtin-stripspace.c\nindex d6e3896..7444f3f 100644\n--- a/builtin-stripspace.c\n+++ b/builtin-stripspace.c\n@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)\n \t\tstrip_comments = 1;\n \n \tif (strbuf_read(&buf, 0, 1024) < 0)\n-\t\tdie(\"could not read the input\");\n+\t\tdie(\"could not read the input: %s\", strerror(errno));\n \n \tstripspace(&buf, strip_comments);\n \ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex dc3db62..e509888 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -443,7 +443,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\telse {\n \t\t\tif (!strcmp(msgfile, \"-\")) {\n \t\t\t\tif (strbuf_read(&buf, 0, 1024) < 0)\n-\t\t\t\t\tdie(\"cannot read %s\", msgfile);\n+\t\t\t\t\tdie(\"cannot read '%s': %s\", msgfile,\n+\t\t\t\t\t    strerror(errno));\n \t\t\t} else {\n \t\t\t\tif (strbuf_read_file(&buf, msgfile, 1024) < 0)\n \t\t\t\t\tdie(\"could not open or read '%s': %s\",\ndiff --git a/builtin-tar-tree.c b/builtin-tar-tree.c\nindex f88e721..066887f 100644\n--- a/builtin-tar-tree.c\n+++ b/builtin-tar-tree.c\n@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)\n \n \tn = write_in_full(1, content + 11, 41);\n \tif (n < 41)\n-\t\tdie(\"git get-tar-commit-id: write error\");\n+\t\tdie(\"git get-tar-commit-id: write error: %s\", strerror(errno));\n \n \treturn 0;\n }\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 60d0367..540e877 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -746,7 +746,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \n \t\t\tdone = read_in_full(fd, result, len);\n \t\t\tif (done < 0)\n-\t\t\t\tdie(\"read error '%s'\", elem->path);\n+\t\t\t\tdie(\"read error '%s': %s\", elem->path,\n+\t\t\t\t    strerror(errno));\n \t\t\telse if (done < len)\n \t\t\t\tdie(\"early EOF '%s'\", elem->path);\n \ndiff --git a/diff.c b/diff.c\nindex dcfbcb0..6c0ba41 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1974,7 +1974,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \t\tsize = buf.len;\n \t}\n \tif (write_in_full(fd, blob, size) != size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie(\"unable to write temp-file: %s\", strerror(errno));\n \tclose(fd);\n \ttemp->name = temp->tmp_path;\n \tstrcpy(temp->hex, sha1_to_hex(sha1));\n@@ -2016,7 +2016,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \t\tif (S_ISLNK(st.st_mode)) {\n \t\t\tstruct strbuf sb = STRBUF_INIT;\n \t\t\tif (strbuf_readlink(&sb, name, st.st_size) < 0)\n-\t\t\t\tdie(\"readlink(%s)\", name);\n+\t\t\t\tdie(\"readlink(%s): %s\", name, strerror(errno));\n \t\t\tprep_temp_blob(name, temp, sb.buf, sb.len,\n \t\t\t\t       (one->sha1_valid ?\n \t\t\t\t\tone->sha1 : null_sha1),\n@@ -2209,7 +2209,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (lstat(one->path, &st) < 0)\n-\t\t\t\tdie(\"stat %s\", one->path);\n+\t\t\t\tdie(\"stat '%s': %s\", one->path, strerror(errno));\n \t\t\tif (index_path(one->sha1, one->path, &st, 0))\n \t\t\t\tdie(\"cannot hash %s\", one->path);\n \t\t}\ndiff --git a/entry.c b/entry.c\nindex cc841ed..0dde848 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -37,7 +37,8 @@ static void create_directories(const char *path, int path_len,\n \t\t\tif (errno == EEXIST && state->force &&\n \t\t\t    !unlink_or_warn(buf) && !mkdir(buf, 0777))\n \t\t\t\tcontinue;\n-\t\t\tdie(\"cannot create directory at %s\", buf);\n+\t\t\tdie(\"cannot create directory at '%s': %s\", buf,\n+\t\t\t    strerror(errno));\n \t\t}\n \t}\n \tfree(buf);\ndiff --git a/fast-import.c b/fast-import.c\nindex a2a2458..686cafc 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)\n \n \tkeep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);\n \tif (keep_fd < 0)\n-\t\tdie(\"cannot create keep file\");\n+\t\tdie(\"cannot create keep file: %s\", strerror(errno));\n \twrite_or_die(keep_fd, keep_msg, strlen(keep_msg));\n \tif (close(keep_fd))\n-\t\tdie(\"failed to write keep file\");\n+\t\tdie(\"failed to write keep file: %s\", strerror(errno));\n \n \tsnprintf(name, sizeof(name), \"%s/pack/pack-%s.pack\",\n \t\t get_object_directory(), sha1_to_hex(pack_data->sha1));\ndiff --git a/hash-object.c b/hash-object.c\nindex 47cf43c..778dabe 100644\n--- a/hash-object.c\n+++ b/hash-object.c\n@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,\n \tint fd;\n \tfd = open(path, O_RDONLY);\n \tif (fd < 0)\n-\t\tdie(\"Cannot open %s\", path);\n+\t\tdie(\"Cannot open '%s': %s\", path, strerror(errno));\n \thash_fd(fd, type, write_object, vpath);\n }\n \ndiff --git a/ll-merge.c b/ll-merge.c\nindex 81c02ad..681f3a0 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)\n \tstrcpy(path, \".merge_file_XXXXXX\");\n \tfd = xmkstemp(path);\n \tif (write_in_full(fd, src->ptr, src->size) != src->size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie(\"unable to write temp-file: %s\", strerror(errno));\n \tclose(fd);\n }\n \ndiff --git a/mktag.c b/mktag.c\nindex 99a356e..238269a 100644\n--- a/mktag.c\n+++ b/mktag.c\n@@ -165,7 +165,7 @@ int main(int argc, char **argv)\n \tsetup_git_directory();\n \n \tif (strbuf_read(&buf, 0, 4096) < 0) {\n-\t\tdie(\"could not read from stdin\");\n+\t\tdie(\"could not read from stdin: %s\", strerror(errno));\n \t}\n \n \t/* Verify it for some basic sanity: it needs to start with\ndiff --git a/read-cache.c b/read-cache.c\nindex 3f58711..2bb142c 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)\n \tmmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);\n \tclose(fd);\n \tif (mmap == MAP_FAILED)\n-\t\tdie(\"unable to map index file\");\n+\t\tdie(\"unable to map index file: %s\", strerror(errno));\n \n \thdr = mmap;\n \tif (verify_hdr(hdr, mmap_size) < 0)\ndiff --git a/setup.c b/setup.c\nindex ebd60de..8548801 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -327,7 +327,8 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\t\t\treturn NULL;\n \t\t\tset_git_dir(make_absolute_path(gitdirenv));\n \t\t\tif (chdir(work_tree_env) < 0)\n-\t\t\t\tdie (\"Could not chdir to %s\", work_tree_env);\n+\t\t\t\tdie (\"Could not chdir to %s: %s\", work_tree_env,\n+\t\t\t\t     strerror(errno));\n \t\t\tstrcat(buffer, \"/\");\n \t\t\treturn retval;\n \t\t}\n@@ -339,7 +340,8 @@ static int check_repository_format_gently(int *nongit_ok)\n \t}\n \n \tif (!getcwd(cwd, sizeof(cwd)-1))\n-\t\tdie(\"Unable to read current working directory\");\n+\t\tdie(\"Unable to read current working directory: %s\",\n+\t\t    strerror(errno));\n \n \tceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);\n \tif (ceil_offset < 0 && has_dos_drive_prefix(cwd))\n@@ -382,7 +384,8 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\tif (offset <= ceil_offset) {\n \t\t\tif (nongit_ok) {\n \t\t\t\tif (chdir(cwd))\n-\t\t\t\t\tdie(\"Cannot come back to cwd\");\n+\t\t\t\t\tdie(\"Cannot come back to cwd: %s\",\n+\t\t\t\t\t    strerror(errno));\n \t\t\t\t*nongit_ok = 1;\n \t\t\t\treturn NULL;\n \t\t\t}\n@@ -493,10 +496,12 @@ int check_repository_format(void)\n \t\tstatic char buffer[PATH_MAX + 1];\n \t\tchar *rel;\n \t\tif (retval && chdir(retval))\n-\t\t\tdie (\"Could not jump back into original cwd\");\n+\t\t\tdie (\"Could not jump back into original cwd: %s\",\n+\t\t\t     strerror(errno));\n \t\trel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());\n \t\tif (rel && *rel && chdir(get_git_work_tree()))\n-\t\t\tdie (\"Could not jump to working directory\");\n+\t\t\tdie (\"Could not jump to working directory: %s\",\n+\t\t\t     strerror(errno));\n \t\treturn rel && *rel ? strcat(rel, \"/\") : NULL;\n \t}\n \ndiff --git a/sha1_file.c b/sha1_file.c\nindex e73cd4f..f6fc256 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2382,7 +2382,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen,\n \tsize = stream.total_out;\n \n \tif (write_buffer(fd, compressed, size) < 0)\n-\t\tdie(\"unable to write sha1 file\");\n+\t\tdie(\"unable to write sha1 file: %s\", strerror(errno));\n \tclose_sha1_file(fd);\n \tfree(compressed);\n \ndiff --git a/transport.c b/transport.c\nindex 17891d5..93cc9a6 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -158,7 +158,8 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)\n \n \tstrbuf_addstr(&temp_dir, git_path(\"rsync-refs-XXXXXX\"));\n \tif (!mkdtemp(temp_dir.buf))\n-\t\tdie (\"Could not make temporary directory\");\n+\t\tdie (\"Could not make temporary directory: %s\",\n+\t\t     strerror(errno));\n \ttemp_dir_len = temp_dir.len;\n \n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n@@ -321,7 +322,8 @@ static int rsync_transport_push(struct transport *transport,\n \n \tstrbuf_addstr(&temp_dir, git_path(\"rsync-refs-XXXXXX\"));\n \tif (!mkdtemp(temp_dir.buf))\n-\t\tdie (\"Could not make temporary directory\");\n+\t\tdie (\"Could not make temporary directory: %s\",\n+\t\t     strerror(errno));\n \tstrbuf_addch(&temp_dir, '/');\n \n \tif (flags & TRANSPORT_PUSH_ALL) {\ndiff --git a/unpack-file.c b/unpack-file.c\nindex 75cd2f1..af9afc8 100644\n--- a/unpack-file.c\n+++ b/unpack-file.c\n@@ -17,7 +17,7 @@\n \tstrcpy(path, \".merge_file_XXXXXX\");\n \tfd = xmkstemp(path);\n \tif (write_in_full(fd, buf, size) != size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie(\"unable to write temp-file: %s\", strerror(errno));\n \tclose(fd);\n \treturn path;\n }\n-- \n1.6.3.1.325.g02d91\n"},{"id":"115305","messageId":"20090603015503.GA14166@coredump.intra.peff.net","threadId":"19644","inReplyTo":"8df45fb3586160fa5c47af39d2a7eb2b8d405a3c.1243978065.git.trast@student.ethz.ch","subject":"Re: [PATCH] add strerror(errno) to die() calls where applicable","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-03T01:55:03Z","receivedAt":"2009-06-03T01:55:03Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:\n\n> Lots of die() calls did not actually report the kind of error, which\n> can leave the user confused as to the real problem.  Add a\n> strerror(errno) where the die() is immediately preceded by a\n> system/library call that sets errno on failure, or by one of the\n> following that wrap such calls:\n\nI like this, as I remember being frustrated in the past by \"cannot $foo\"\nmessages with no indication of the cause of the error. My only questions\nor concerns with such a patch would be:\n\n  1. How did you determine the set of callsites? Did you check that each\n     non-syscall function always sets errno? Are there are functions\n     which are setting errno which could also be included?\n\n  2. Extra error conditions may leak information about the filesystem to\n     people feeding bogus paths to upload-pack. I didn't see anything\n     obvious in your patch that would cause this, but it is something to\n     consider.\n\n  3. This is such a common thing to do, I wonder if we would be better\n     off adding a \"diesys\" function that appends \": strerror(errno)\"\n     to the emitted error. Something like the (totally untested) patch\n     below.\n\nAnd a few comments on the patch itself:\n\n> @@ -109,7 +113,8 @@ int is_directory(const char *path)\n>  \t} else {\n>  \t\tconst char *cwd = get_pwd_cwd();\n>  \t\tif (!cwd)\n> -\t\t\tdie(\"Cannot determine the current working directory\");\n> +\t\t\tdie(\"Cannot determine the current working directory\",\n> +\t\t\t    strerror(errno));\n\nMissing \": %s\" here?\n\n> -\t\tdie(\"closing file %s: %s\", path, strerror(errno));\n> +\t\tdie(\"closing file '%s': %s\", path, strerror(errno));\n\nThis one is actually just a style change, though I think it is\nworthwhile (and there are a few others like it).\n\n\nThe diesys patch is below.\n\n---\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 4236647..410ac87 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -155,6 +155,7 @@\n /* General helper functions */\n extern void usage(const char *err) NORETURN;\n extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n+extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));\n \ndiff --git a/usage.c b/usage.c\nindex 820d09f..da5e58e 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -12,6 +12,14 @@ static void report(const char *prefix, const char *err, va_list params)\n \tfprintf(stderr, \"%s%s\\n\", prefix, msg);\n }\n \n+static void report_sys(int err, const char *prefix, const char *fmt, va_list\n+\t\tparams)\n+{\n+\tchar msg[1024];\n+\tvsnprintf(msg, sizeof(msg), fmt, params);\n+\tfprintf(stderr, \"%s%s: %s\\n\", prefix, msg, hstrerror(err));\n+}\n+\n static NORETURN void usage_builtin(const char *err)\n {\n \tfprintf(stderr, \"usage: %s\\n\", err);\n@@ -24,6 +32,12 @@ static NORETURN void die_builtin(const char *err, va_list params)\n \texit(128);\n }\n \n+static NORETURN void diesys_builtin(int err, const char *fmt, va_list params)\n+{\n+\treport_sys(err, \"fatal: \", fmt, params);\n+\texit(128);\n+}\n+\n static void error_builtin(const char *err, va_list params)\n {\n \treport(\"error: \", err, params);\n@@ -38,6 +52,7 @@ static void warn_builtin(const char *warn, va_list params)\n  * (ugh), so keep things static. */\n static void (*usage_routine)(const char *err) NORETURN = usage_builtin;\n static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;\n+static void (*diesys_routine)(int err, const char *fmt, va_list params) NORETURN = diesys_builtin;\n static void (*error_routine)(const char *err, va_list params) = error_builtin;\n static void (*warn_routine)(const char *err, va_list params) = warn_builtin;\n \n@@ -60,6 +75,16 @@ void die(const char *err, ...)\n \tva_end(params);\n }\n \n+void diesys(const char *fmt, ...)\n+{\n+\tva_list params;\n+\tint err = errno;\n+\n+\tva_start(params, fmt);\n+\tdiesys_routine(err, fmt, params);\n+\tva_end(params);\n+}\n+\n int error(const char *err, ...)\n {\n \tva_list params;\n"},{"id":"115406","messageId":"2325a7950906031858oed495d0x406ea375ff08eb28@mail.gmail.com","threadId":"19644","inReplyTo":"2325a7950906031855t1977448lbb1c8aa671c72f3d@mail.gmail.com","subject":"Re: [PATCH] add strerror(errno) to die() calls where applicable","fromName":"Alexander Potashev","fromEmail":"aspotashev@gmail.com","sentAt":"2009-06-04T01:58:14Z","receivedAt":"2009-06-04T01:58:14Z","isPatch":true,"sender":{"key":"aspotashev@gmail.com","avatar":null},"body":"Hi Jeff,\nI was also thinking (about 1 month ago) about a helper function\nsimilar to your 'diesys', but I never thought that adding yet another\n\"backend\" function (diesys_routine) is reasonable.\n\nFollowing your approach, you will need to add 'set_diesys_routine' and\ncall it along with 'set_die_routine' (however, if you want to use\n'diesys', but there are several places in 'daemon.c' and\n'fast-import.c' where 'die' is being used to write 'strerror(errno)').\n\nI think, we should just keep the backend interface as is and implement\n'diesys' through 'die_routine'.\n\n\nAlexander\n\n\n2009/6/3 Jeff King <peff@peff.net>:\n> On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:\n>\n>> Lots of die() calls did not actually report the kind of error, which\n>> can leave the user confused as to the real problem.  Add a\n>> strerror(errno) where the die() is immediately preceded by a\n>> system/library call that sets errno on failure, or by one of the\n>> following that wrap such calls:\n>\n> I like this, as I remember being frustrated in the past by \"cannot $foo\"\n> messages with no indication of the cause of the error. My only questions\n> or concerns with such a patch would be:\n>\n>  1. How did you determine the set of callsites? Did you check that each\n>     non-syscall function always sets errno? Are there are functions\n>     which are setting errno which could also be included?\n>\n>  2. Extra error conditions may leak information about the filesystem to\n>     people feeding bogus paths to upload-pack. I didn't see anything\n>     obvious in your patch that would cause this, but it is something to\n>     consider.\n>\n>  3. This is such a common thing to do, I wonder if we would be better\n>     off adding a \"diesys\" function that appends \": strerror(errno)\"\n>     to the emitted error. Something like the (totally untested) patch\n>     below.\n>\n> And a few comments on the patch itself:\n>\n>> @@ -109,7 +113,8 @@ int is_directory(const char *path)\n>>       } else {\n>>               const char *cwd = get_pwd_cwd();\n>>               if (!cwd)\n>> -                     die(\"Cannot determine the current working directory\");\n>> +                     die(\"Cannot determine the current working directory\",\n>> +                         strerror(errno));\n>\n> Missing \": %s\" here?\n>\n>> -             die(\"closing file %s: %s\", path, strerror(errno));\n>> +             die(\"closing file '%s': %s\", path, strerror(errno));\n>\n> This one is actually just a style change, though I think it is\n> worthwhile (and there are a few others like it).\n>\n>\n> The diesys patch is below.\n>\n> ---\n> diff --git a/git-compat-util.h b/git-compat-util.h\n> index 4236647..410ac87 100644\n> --- a/git-compat-util.h\n> +++ b/git-compat-util.h\n> @@ -155,6 +155,7 @@\n>  /* General helper functions */\n>  extern void usage(const char *err) NORETURN;\n>  extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n> +extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n>  extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n>  extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));\n>\n> diff --git a/usage.c b/usage.c\n> index 820d09f..da5e58e 100644\n> --- a/usage.c\n> +++ b/usage.c\n> @@ -12,6 +12,14 @@ static void report(const char *prefix, const char *err, va_list params)\n>        fprintf(stderr, \"%s%s\\n\", prefix, msg);\n>  }\n>\n> +static void report_sys(int err, const char *prefix, const char *fmt, va_list\n> +               params)\n> +{\n> +       char msg[1024];\n> +       vsnprintf(msg, sizeof(msg), fmt, params);\n> +       fprintf(stderr, \"%s%s: %s\\n\", prefix, msg, hstrerror(err));\n> +}\n> +\n>  static NORETURN void usage_builtin(const char *err)\n>  {\n>        fprintf(stderr, \"usage: %s\\n\", err);\n> @@ -24,6 +32,12 @@ static NORETURN void die_builtin(const char *err, va_list params)\n>        exit(128);\n>  }\n>\n> +static NORETURN void diesys_builtin(int err, const char *fmt, va_list params)\n> +{\n> +       report_sys(err, \"fatal: \", fmt, params);\n> +       exit(128);\n> +}\n> +\n>  static void error_builtin(const char *err, va_list params)\n>  {\n>        report(\"error: \", err, params);\n> @@ -38,6 +52,7 @@ static void warn_builtin(const char *warn, va_list params)\n>  * (ugh), so keep things static. */\n>  static void (*usage_routine)(const char *err) NORETURN = usage_builtin;\n>  static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin;\n> +static void (*diesys_routine)(int err, const char *fmt, va_list params) NORETURN = diesys_builtin;\n>  static void (*error_routine)(const char *err, va_list params) = error_builtin;\n>  static void (*warn_routine)(const char *err, va_list params) = warn_builtin;\n>\n> @@ -60,6 +75,16 @@ void die(const char *err, ...)\n>        va_end(params);\n>  }\n>\n> +void diesys(const char *fmt, ...)\n> +{\n> +       va_list params;\n> +       int err = errno;\n> +\n> +       va_start(params, fmt);\n> +       diesys_routine(err, fmt, params);\n> +       va_end(params);\n> +}\n> +\n>  int error(const char *err, ...)\n>  {\n>        va_list params;\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n>\n"},{"id":"115405","messageId":"1244081105-7149-1-git-send-email-aspotashev@gmail.com","threadId":"19644","inReplyTo":"20090603015503.GA14166@coredump.intra.peff.net","subject":"[PATCH] diesys calls die and also reports strerror(errno)","fromName":"Alexander Potashev","fromEmail":"aspotashev@gmail.com","sentAt":"2009-06-04T02:05:05Z","receivedAt":"2009-06-04T02:05:05Z","isPatch":true,"sender":{"key":"aspotashev@gmail.com","avatar":null},"body":"Signed-off-by: Alexander Potashev <aspotashev@gmail.com>\n---\nFirstly I was going to write a 'adapt_to_fmt' function which would\ndouble all inclusions of '%', and then use it for strerror(err) and\nmake printf-like functions happy (actually 'die_routine').\n\nBUT, Have you ever seen an error description containing '%'? I haven't.\nSo, handling the case of '%'s is not worth injecting several dump lines\ninto the sources of the Beatiful Content Tracker.\n\n\n\n git-compat-util.h |    1 +\n usage.c           |   18 ++++++++++++++++++\n 2 files changed, 19 insertions(+), 0 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex f25f7f1..cbfee60 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -162,6 +162,7 @@ extern char *gitbasename(char *);\n /* General helper functions */\n extern void usage(const char *err) NORETURN;\n extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n+extern void diesys(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));\n \ndiff --git a/usage.c b/usage.c\nindex 820d09f..e20f696 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -60,6 +60,24 @@ void die(const char *err, ...)\n \tva_end(params);\n }\n \n+void diesys(const char *err, ...)\n+{\n+\tva_list params;\n+\tchar *fullfmt;\n+\tconst char *strerr;\n+\n+\tva_start(params, err);\n+\n+\tstrerr = strerror(errno);\n+\tif (strchr(strerr, '%'))\n+\t\tstrerr = \"<error description contains '%%'>\";\n+\tfullfmt = xmalloc(strlen(err) + strlen(strerr) + 3);\n+\tsprintf(fullfmt, \"%s: %s\", err, strerr);\n+\tdie_routine(fullfmt, params);\n+\n+\tva_end(params);\n+}\n+\n int error(const char *err, ...)\n {\n \tva_list params;\n-- \n1.6.2.3\n"},{"id":"115439","messageId":"20090604203239.GA17478@sigill.intra.peff.net","threadId":"19644","inReplyTo":"2325a7950906031858oed495d0x406ea375ff08eb28@mail.gmail.com","subject":"Re: [PATCH] add strerror(errno) to die() calls where applicable","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-04T20:32:39Z","receivedAt":"2009-06-04T20:32:39Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 04, 2009 at 05:58:14AM +0400, Alexander Potashev wrote:\n\n> I was also thinking (about 1 month ago) about a helper function\n> similar to your 'diesys', but I never thought that adding yet another\n> \"backend\" function (diesys_routine) is reasonable.\n> \n> Following your approach, you will need to add 'set_diesys_routine' and\n> call it along with 'set_die_routine' (however, if you want to use\n> 'diesys', but there are several places in 'daemon.c' and\n> 'fast-import.c' where 'die' is being used to write 'strerror(errno)').\n\nYeah, I didn't look into who is actually using set_die_routine, but\nadding another routine like this makes it a lot more annoying for\ngit-daemon to use it. So I think your approach is probably better,\nthough I have a few comments on the patch itself (which I'll put in the\nnext mail).\n\n-Peff\n\nPS Actually, the nicest interface IMHO would be a variadic macro\nlike:\n\n  #define diesys(fmt, ...) die(fmt \": %s\", __VA_ARGS__, strerror(errno))\n\nbut that requires a c99 compiler, which we otherwise do not need.\n"},{"id":"115442","messageId":"20090604205055.GB17478@sigill.intra.peff.net","threadId":"19644","inReplyTo":"1244081105-7149-1-git-send-email-aspotashev@gmail.com","subject":"Re: [PATCH] diesys calls die and also reports strerror(errno)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-04T20:50:55Z","receivedAt":"2009-06-04T20:50:55Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:\n\n> Firstly I was going to write a 'adapt_to_fmt' function which would\n> double all inclusions of '%', and then use it for strerror(err) and\n> make printf-like functions happy (actually 'die_routine').\n> \n> BUT, Have you ever seen an error description containing '%'? I haven't.\n> So, handling the case of '%'s is not worth injecting several dump lines\n> into the sources of the Beatiful Content Tracker.\n\nThat makes me a little nervous. No, I don't think there are any '%'\nsigns in standard 'C' locale messages (at least not in GNU libc). But\nwhat about other locales, especially ones which use a multi-byte\nencoding?\n\nThough your code does at least recognize the situation and does\nsomething sane instead of feeding bogus parameters to fprintf.\n\n> +void diesys(const char *err, ...)\n> +{\n> +\tva_list params;\n> +\tchar *fullfmt;\n> +\tconst char *strerr;\n> +\n> +\tva_start(params, err);\n> +\n> +\tstrerr = strerror(errno);\n> +\tif (strchr(strerr, '%'))\n> +\t\tstrerr = \"<error description contains '%%'>\";\n> +\tfullfmt = xmalloc(strlen(err) + strlen(strerr) + 3);\n> +\tsprintf(fullfmt, \"%s: %s\", err, strerr);\n> +\tdie_routine(fullfmt, params);\n> +\n> +\tva_end(params);\n> +}\n\nShould we be calling malloc here? One of the possible error conditions\nis that we're out of memory (though xmalloc itself just uses \"die\"). I\ndon't think there is a good reason not to use a reasonably-sized static\nbuffer, which should increase robustness (report() is already using a\n1024-character buffer, so any message would be truncated there anyway).\n\n-Peff\n"},{"id":"115444","messageId":"7v3aafwvmo.fsf@alter.siamese.dyndns.org","threadId":"19644","inReplyTo":"20090604205055.GB17478@sigill.intra.peff.net","subject":"Re: [PATCH] diesys calls die and also reports strerror(errno)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-04T21:13:03Z","receivedAt":"2009-06-04T21:13:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> Should we be calling malloc here? One of the possible error conditions\n> is that we're out of memory (though xmalloc itself just uses \"die\"). I\n> don't think there is a good reason not to use a reasonably-sized static\n> buffer, which should increase robustness (report() is already using a\n> 1024-character buffer, so any message would be truncated there anyway).\n\nYup, and at that point, tacking strerror value while expanding possible %\nbecomes even easier.\n"},{"id":"115485","messageId":"4A28BA3E.3090800@viscovery.net","threadId":"19644","inReplyTo":"20090604205055.GB17478@sigill.intra.peff.net","subject":"Re: [PATCH] diesys calls die and also reports strerror(errno)","fromName":"Johannes Sixt","fromEmail":"j.sixt@viscovery.net","sentAt":"2009-06-05T06:25:02Z","receivedAt":"2009-06-05T06:25:02Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Jeff King schrieb:\n> On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:\n>> +void diesys(const char *err, ...)\n\nAm I the only one who thinks that 'die_errno' would be a better name for\nthis function?\n\n-- Hannes\n"},{"id":"115489","messageId":"7vtz2vnogt.fsf@alter.siamese.dyndns.org","threadId":"19644","inReplyTo":"4A28BA3E.3090800@viscovery.net","subject":"Re: [PATCH] diesys calls die and also reports strerror(errno)","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-05T07:12:34Z","receivedAt":"2009-06-05T07:12:34Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Sixt <j.sixt@viscovery.net> writes:\n\n> Jeff King schrieb:\n>> On Thu, Jun 04, 2009 at 06:05:05AM +0400, Alexander Potashev wrote:\n>>> +void diesys(const char *err, ...)\n>\n> Am I the only one who thinks that 'die_errno' would be a better name for\n> this function?\n\nYou are not alone.  I did find diesys() unreadable, but simply did not\nthink of an obviously better alternative like you did.\n"},{"id":"115647","messageId":"200906061509.15870.trast@student.ethz.ch","threadId":"19644","inReplyTo":"20090603015503.GA14166@coredump.intra.peff.net","subject":"Re: [PATCH] add strerror(errno) to die() calls where applicable","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T13:09:10Z","receivedAt":"2009-06-06T13:09:10Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Sorry for not getting around to this again all week.  I'll try to\nreroll later today...\n\nJeff King wrote:\n>   1. How did you determine the set of callsites? Did you check that each\n>      non-syscall function always sets errno? Are there are functions\n>      which are setting errno which could also be included?\n\nBasically by 'git grep die | grep -v errno' and then looking at the\ncode immediately before the die().  Rather tedious, but I couldn't see\nan obvious way to automate the task.\n\nAs for the non-syscall functions, at first I had a longer list but I\neventually settled with the ones mentioned, but I decided it was too\nrisky and just stuck with those that are very clear:\n\n> On Tue, Jun 02, 2009 at 11:34:33PM +0200, Thomas Rast wrote:\n> >   odb_pack_keep\n\nTries open() in two ways, but can only return <0 by passing the return\nvalue of the second.\n\n> >   read_ancestry\n\nOnly returns -1 if fopen() returned NULL.\n\n> >   read_in_full\n\nOnly returns <=0 if xread() returned <=0, which in turn only happens\nif read() returned <0.\n\n> >   strbuf_read\n\nReturns -1 if xread() did so.\n\n> >   strbuf_read_file\n\nReturns -1 if open() or strbuf_read() failed.\n\n> >   strbuf_readlink\n\nReturns -1 if readlink() failed.  (The other option, that the buffer\nwas still too small at STRBUF_MAXLINK, would imply that readlink()\nwanted to return more than PATH_MAX chars.)\n\n> >   write_buffer\n\nI'll drop this one, I missed that it actually does its own errno\nreporting already.  (Other than that it's just a thin wrapper around\nwrite_in_full.)\n\n> >   write_in_full\n\nSymmetric to read_in_full: only returns <=0 if xwrite() did, which in\nturn only happens if write() returned <0.\n\n\nThere were lots of cases that aren't quite as clear-cut.  For example,\nthere are many call sites where the index is written out that look\nlike\n\n\tif (write_cache(fd, active_cache, active_nr) ||\n\t    close_lock_file(&index_lock))\n\t\tdie(\"unable to write new_index file\");\n\nDealing with those will be somewhat more complicated, as the error\ncase is not all that clearly defined.  But at least at a quick glance,\nwrite_cache does not even indicate what file it failed to write.\n\n>   2. Extra error conditions may leak information about the filesystem to\n>      people feeding bogus paths to upload-pack. I didn't see anything\n>      obvious in your patch that would cause this, but it is something to\n>      consider.\n\nGood point.\n\n> > -\t\tdie(\"closing file %s: %s\", path, strerror(errno));\n> > +\t\tdie(\"closing file '%s': %s\", path, strerror(errno));\n> \n> This one is actually just a style change, though I think it is\n> worthwhile (and there are a few others like it).\n\nYes, as I was already going through the calls I thought some\nconsistency would be nice.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"115651","messageId":"cover.1244299302.git.trast@student.ethz.ch","threadId":"19644","inReplyTo":"200906061509.15870.trast@student.ethz.ch","subject":"[PATCH v2 0/3] Thomas Rast <trast@student.ethz.ch>","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T14:44:50Z","receivedAt":"2009-06-06T14:44:50Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"So here's the reroll.\n\nChanges since v1:\n\n- add die_errno() [1/3] and use it [2/3]\n\n- [3/3] dropped errno reporting after write_buffer, as it already does\n  error(..., strerror(errno))\n\n- [3/3] save errno around rollback_locks in builtin-commit.c:965\n\n\n\nThomas Rast (3):\n  Introduce die_errno() that appends strerror(errno) to die()\n  Convert existing die(..., strerror(errno)) to die_errno()\n  Use die_errno() instead of die() when checking syscalls\n\n abspath.c                |   12 ++++++------\n bisect.c                 |    5 ++---\n branch.c                 |    4 ++--\n builtin-add.c            |    2 +-\n builtin-apply.c          |   12 ++++++------\n builtin-archive.c        |    4 ++--\n builtin-blame.c          |   16 +++++++---------\n builtin-clone.c          |   22 ++++++++++------------\n builtin-commit-tree.c    |    3 +--\n builtin-commit.c         |   36 +++++++++++++++++-------------------\n builtin-config.c         |    4 ++--\n builtin-diff.c           |    2 +-\n builtin-fast-export.c    |    5 ++---\n builtin-fetch--tool.c    |    2 +-\n builtin-fmt-merge-msg.c  |    5 ++---\n builtin-fsck.c           |   10 +++++-----\n builtin-grep.c           |    2 +-\n builtin-init-db.c        |   22 +++++++++++-----------\n builtin-log.c            |    4 ++--\n builtin-mailsplit.c      |    7 +++----\n builtin-merge.c          |   33 +++++++++++++++++++--------------\n builtin-mv.c             |    2 +-\n builtin-pack-objects.c   |   14 +++++---------\n builtin-rev-parse.c      |    2 +-\n builtin-revert.c         |    2 +-\n builtin-rm.c             |    2 +-\n builtin-send-pack.c      |    2 +-\n builtin-stripspace.c     |    2 +-\n builtin-tag.c            |    9 ++++-----\n builtin-tar-tree.c       |    2 +-\n builtin-unpack-objects.c |    2 +-\n combine-diff.c           |    2 +-\n connect.c                |    4 ++--\n csum-file.c              |    5 ++---\n daemon.c                 |   15 +++++++--------\n diff.c                   |   10 +++++-----\n dir.c                    |    2 +-\n entry.c                  |   10 +++++-----\n fast-import.c            |    8 ++++----\n git-compat-util.h        |    1 +\n git.c                    |    6 +++---\n hash-object.c            |    2 +-\n index-pack.c             |   21 ++++++++++-----------\n ll-merge.c               |    2 +-\n merge-recursive.c        |    6 +++---\n mktag.c                  |    2 +-\n pack-refs.c              |    7 +++----\n pack-write.c             |   10 +++++-----\n pkt-line.c               |    4 ++--\n read-cache.c             |    8 ++++----\n refs.c                   |    2 +-\n run-command.c            |    4 ++--\n setup.c                  |   18 +++++++++---------\n sha1_file.c              |    2 +-\n shell.c                  |    2 +-\n test-sha1.c              |    2 +-\n transport.c              |    4 ++--\n unpack-file.c            |    2 +-\n usage.c                  |   13 +++++++++++++\n wrapper.c                |    8 ++++----\n write_or_die.c           |    6 +++---\n 61 files changed, 219 insertions(+), 220 deletions(-)\n"},{"id":"115652","messageId":"3672f22723a4c14c4a6d67278e9865424c0c68dc.1244299302.git.trast@student.ethz.ch","threadId":"19644","inReplyTo":"cover.1244299302.git.trast@student.ethz.ch","subject":"[PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T14:44:51Z","receivedAt":"2009-06-06T14:44:51Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"There are many calls to die() that do, or should, report\nstrerror(errno) to indicate how the syscall they guard failed.\nIntroduce a small helper function for this case.\n\nCode by Jeff King and Alexander Potashev, name by Johannes Sixt.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n git-compat-util.h |    1 +\n usage.c           |   13 +++++++++++++\n 2 files changed, 14 insertions(+), 0 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex f25f7f1..0366cde 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -162,6 +162,7 @@\n /* General helper functions */\n extern void usage(const char *err) NORETURN;\n extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n+extern void die_errno(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2)));\n extern int error(const char *err, ...) __attribute__((format (printf, 1, 2)));\n extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)));\n \ndiff --git a/usage.c b/usage.c\nindex 820d09f..1819e0a 100644\n--- a/usage.c\n+++ b/usage.c\n@@ -60,6 +60,19 @@ void die(const char *err, ...)\n \tva_end(params);\n }\n \n+void die_errno(const char *err, ...)\n+{\n+\tva_list params;\n+\tchar msg[1024];\n+\n+\tva_start(params, err);\n+\n+\tvsnprintf(msg, sizeof(msg), err, params);\n+\tdie(\"%s: %s\", msg, strerror(errno));\n+\n+\tva_end(params);\n+}\n+\n int error(const char *err, ...)\n {\n \tva_list params;\n-- \n1.6.3.2.288.g40844\n"},{"id":"115653","messageId":"095b4af080c11b4ad3fcfaefc9cdf49d383cb714.1244299302.git.trast@student.ethz.ch","threadId":"19644","inReplyTo":"3672f22723a4c14c4a6d67278e9865424c0c68dc.1244299302.git.trast@student.ethz.ch","subject":"[PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno()","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T14:44:52Z","receivedAt":"2009-06-06T14:44:52Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Change calls to die(..., strerror(errno)) to use the new die_errno().\n\nIn the process, also make slight style adjustments: at least state\n_something_ about the function that failed (instead of just printing\nthe pathname), and put paths in single quotes.\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n bisect.c                 |    5 ++---\n branch.c                 |    4 ++--\n builtin-apply.c          |    6 +++---\n builtin-blame.c          |    7 +++----\n builtin-clone.c          |   11 +++++------\n builtin-commit-tree.c    |    2 +-\n builtin-commit.c         |   23 ++++++++++-------------\n builtin-config.c         |    4 ++--\n builtin-diff.c           |    2 +-\n builtin-fast-export.c    |    2 +-\n builtin-fetch--tool.c    |    2 +-\n builtin-fmt-merge-msg.c  |    3 +--\n builtin-fsck.c           |    8 ++++----\n builtin-grep.c           |    2 +-\n builtin-merge.c          |    8 ++++----\n builtin-mv.c             |    2 +-\n builtin-pack-objects.c   |   14 +++++---------\n builtin-rm.c             |    2 +-\n builtin-send-pack.c      |    2 +-\n builtin-tag.c            |    7 +++----\n builtin-unpack-objects.c |    2 +-\n connect.c                |    4 ++--\n csum-file.c              |    6 +++---\n daemon.c                 |   15 +++++++--------\n diff.c                   |    4 ++--\n dir.c                    |    2 +-\n entry.c                  |    8 ++++----\n fast-import.c            |    4 ++--\n git.c                    |    6 +++---\n index-pack.c             |   21 ++++++++++-----------\n merge-recursive.c        |    6 +++---\n pack-refs.c              |    7 +++----\n pack-write.c             |   10 +++++-----\n pkt-line.c               |    4 ++--\n read-cache.c             |    6 +++---\n refs.c                   |    2 +-\n run-command.c            |    4 ++--\n setup.c                  |    8 ++++----\n sha1_file.c              |    2 +-\n shell.c                  |    2 +-\n test-sha1.c              |    2 +-\n wrapper.c                |    8 ++++----\n write_or_die.c           |    6 +++---\n 43 files changed, 120 insertions(+), 135 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex c43c120..281e16a 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -461,7 +461,7 @@ void read_bisect_paths(struct argv_array *array)\n \tFILE *fp = fopen(filename, \"r\");\n \n \tif (!fp)\n-\t\tdie(\"Could not open file '%s': %s\", filename, strerror(errno));\n+\t\tdie_errno(\"Could not open file '%s'\", filename);\n \n \twhile (strbuf_getline(&str, fp, '\\n') != EOF) {\n \t\tchar *quoted;\n@@ -632,8 +632,7 @@ static void mark_expected_rev(char *bisect_rev_hex)\n \tint fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);\n \n \tif (fd < 0)\n-\t\tdie(\"could not create file '%s': %s\",\n-\t\t    filename, strerror(errno));\n+\t\tdie_errno(\"could not create file '%s'\", filename);\n \n \tbisect_rev_hex[len] = '\\n';\n \twrite_or_die(fd, bisect_rev_hex, len + 1);\ndiff --git a/branch.c b/branch.c\nindex 62030af..05ef3f5 100644\n--- a/branch.c\n+++ b/branch.c\n@@ -172,7 +172,7 @@ void create_branch(const char *head,\n \n \tlock = lock_any_ref_for_update(ref.buf, NULL, 0);\n \tif (!lock)\n-\t\tdie(\"Failed to lock ref for update: %s.\", strerror(errno));\n+\t\tdie_errno(\"Failed to lock ref for update\");\n \n \tif (reflog)\n \t\tlog_all_ref_updates = 1;\n@@ -188,7 +188,7 @@ void create_branch(const char *head,\n \t\tsetup_tracking(name, real_ref, track);\n \n \tif (write_ref_sha1(lock, sha1, msg) < 0)\n-\t\tdie(\"Failed to write ref: %s.\", strerror(errno));\n+\t\tdie_errno(\"Failed to write ref\");\n \n \tstrbuf_release(&ref);\n \tfree(real_ref);\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 94ba2bd..6526c08 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -280,7 +280,7 @@ static void say_patch_name(FILE *output, const char *pre,\n static void read_patch_file(struct strbuf *sb, int fd)\n {\n \tif (strbuf_read(sb, fd, 0) < 0)\n-\t\tdie(\"git apply: read returned %s\", strerror(errno));\n+\t\tdie_errno(\"git apply: failed to read\");\n \n \t/*\n \t * Make sure that we have some slop in the buffer\n@@ -2864,7 +2864,7 @@ static int try_create_file(const char *path, unsigned int mode, const char *buf,\n \tstrbuf_release(&nbuf);\n \n \tif (close(fd) < 0)\n-\t\tdie(\"closing file %s: %s\", path, strerror(errno));\n+\t\tdie_errno(\"closing file '%s'\", path);\n \treturn 0;\n }\n \n@@ -3354,7 +3354,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)\n \n \t\tfd = open(arg, O_RDONLY);\n \t\tif (fd < 0)\n-\t\t\tdie(\"can't open patch '%s': %s\", arg, strerror(errno));\n+\t\t\tdie_errno(\"can't open patch '%s'\", arg);\n \t\tread_stdin = 0;\n \t\tset_default_whitespace_mode(whitespace_option);\n \t\terrs |= apply_patch(fd, arg, options);\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 0c2d29a..7d8fbd5 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -2035,7 +2035,7 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n \t\tcontents_from = \"standard input\";\n \t\tmode = 0;\n \t\tif (strbuf_read(&buf, 0, 0) < 0)\n-\t\t\tdie(\"read error %s from stdin\", strerror(errno));\n+\t\t\tdie_errno(\"failed to read from stdin\");\n \t}\n \tconvert_to_git(path, buf.buf, buf.len, &buf, 0);\n \torigin->file.ptr = buf.buf;\n@@ -2261,8 +2261,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \targc = parse_options_end(&ctx);\n \n \tif (revs_file && read_ancestry(revs_file))\n-\t\tdie(\"reading graft file %s failed: %s\",\n-\t\t    revs_file, strerror(errno));\n+\t\tdie_errno(\"reading graft file '%s' failed\", revs_file);\n \n \tif (cmd_is_annotate) {\n \t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n@@ -2350,7 +2349,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \n \t\tsetup_work_tree();\n \t\tif (!has_string_in_work_tree(path))\n-\t\t\tdie(\"cannot stat path %s: %s\", path, strerror(errno));\n+\t\t\tdie_errno(\"cannot stat path '%s'\", path);\n \t}\n \n \tsetup_revisions(argc, argv, &revs, NULL);\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex 5c46496..5f34414 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -252,8 +252,7 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)\n \t\t}\n \n \t\tif (unlink(dest->buf) && errno != ENOENT)\n-\t\t\tdie(\"failed to unlink %s: %s\",\n-\t\t\t    dest->buf, strerror(errno));\n+\t\t\tdie_errno(\"failed to unlink '%s'\", dest->buf);\n \t\tif (!option_no_hardlinks) {\n \t\t\tif (!link(src->buf, dest->buf))\n \t\t\t\tcontinue;\n@@ -420,11 +419,11 @@ int cmd_clone(int argc, const char **argv, const char *prefix)\n \tif (!option_bare) {\n \t\tjunk_work_tree = work_tree;\n \t\tif (safe_create_leading_directories_const(work_tree) < 0)\n-\t\t\tdie(\"could not create leading directories of '%s': %s\",\n-\t\t\t\t\twork_tree, strerror(errno));\n+\t\t\tdie_errno(\"could not create leading directories of '%s'\",\n+\t\t\t\t  work_tree);\n \t\tif (!dest_exists && mkdir(work_tree, 0755))\n-\t\t\tdie(\"could not create work tree dir '%s': %s.\",\n-\t\t\t\t\twork_tree, strerror(errno));\n+\t\t\tdie_errno(\"could not create work tree dir '%s'.\",\n+\t\t\t\t  work_tree);\n \t\tset_git_work_tree(work_tree);\n \t}\n \tjunk_git_dir = git_dir;\ndiff --git a/builtin-commit-tree.c b/builtin-commit-tree.c\nindex 0453425..6467077 100644\n--- a/builtin-commit-tree.c\n+++ b/builtin-commit-tree.c\n@@ -124,7 +124,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (strbuf_read(&buffer, 0, 0) < 0)\n-\t\tdie(\"git commit-tree: read returned %s\", strerror(errno));\n+\t\tdie_errno(\"git commit-tree: failed to read\");\n \n \tif (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {\n \t\tprintf(\"%s\\n\", sha1_to_hex(commit_sha1));\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex 41e222d..cce25b5 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -438,8 +438,8 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t\thook_arg1 = \"message\";\n \t} else if (logfile) {\n \t\tif (strbuf_read_file(&sb, logfile, 0) < 0)\n-\t\t\tdie(\"could not read log file '%s': %s\",\n-\t\t\t    logfile, strerror(errno));\n+\t\t\tdie_errno(\"could not read log file '%s'\",\n+\t\t\t\t  logfile);\n \t\thook_arg1 = \"message\";\n \t} else if (use_message) {\n \t\tbuffer = strstr(use_message_buffer, \"\\n\\n\");\n@@ -450,16 +450,15 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t\thook_arg2 = use_message;\n \t} else if (!stat(git_path(\"MERGE_MSG\"), &statbuf)) {\n \t\tif (strbuf_read_file(&sb, git_path(\"MERGE_MSG\"), 0) < 0)\n-\t\t\tdie(\"could not read MERGE_MSG: %s\", strerror(errno));\n+\t\t\tdie_errno(\"could not read MERGE_MSG\");\n \t\thook_arg1 = \"merge\";\n \t} else if (!stat(git_path(\"SQUASH_MSG\"), &statbuf)) {\n \t\tif (strbuf_read_file(&sb, git_path(\"SQUASH_MSG\"), 0) < 0)\n-\t\t\tdie(\"could not read SQUASH_MSG: %s\", strerror(errno));\n+\t\t\tdie_errno(\"could not read SQUASH_MSG\");\n \t\thook_arg1 = \"squash\";\n \t} else if (template_file && !stat(template_file, &statbuf)) {\n \t\tif (strbuf_read_file(&sb, template_file, 0) < 0)\n-\t\t\tdie(\"could not read %s: %s\",\n-\t\t\t    template_file, strerror(errno));\n+\t\t\tdie_errno(\"could not read '%s'\", template_file);\n \t\thook_arg1 = \"template\";\n \t}\n \n@@ -472,8 +471,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \n \tfp = fopen(git_path(commit_editmsg), \"w\");\n \tif (fp == NULL)\n-\t\tdie(\"could not open %s: %s\",\n-\t\t    git_path(commit_editmsg), strerror(errno));\n+\t\tdie_errno(\"could not open '%s'\", git_path(commit_editmsg));\n \n \tif (cleanup_mode != CLEANUP_NONE)\n \t\tstripspace(&sb, 0);\n@@ -497,7 +495,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t}\n \n \tif (fwrite(sb.buf, 1, sb.len, fp) < sb.len)\n-\t\tdie(\"could not write commit template: %s\", strerror(errno));\n+\t\tdie_errno(\"could not write commit template\");\n \n \tstrbuf_release(&sb);\n \n@@ -940,8 +938,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tpptr = &commit_list_insert(lookup_commit(head_sha1), pptr)->next;\n \t\tfp = fopen(git_path(\"MERGE_HEAD\"), \"r\");\n \t\tif (fp == NULL)\n-\t\t\tdie(\"could not open %s for reading: %s\",\n-\t\t\t    git_path(\"MERGE_HEAD\"), strerror(errno));\n+\t\t\tdie_errno(\"could not open %s for reading\",\n+\t\t\t\t  git_path(\"MERGE_HEAD\"));\n \t\twhile (strbuf_getline(&m, fp, '\\n') != EOF) {\n \t\t\tunsigned char sha1[20];\n \t\t\tif (get_sha1_hex(m.buf, sha1) < 0)\n@@ -952,8 +950,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t\tstrbuf_release(&m);\n \t\tif (!stat(git_path(\"MERGE_MODE\"), &statbuf)) {\n \t\t\tif (strbuf_read_file(&sb, git_path(\"MERGE_MODE\"), 0) < 0)\n-\t\t\t\tdie(\"could not read MERGE_MODE: %s\",\n-\t\t\t\t\t\tstrerror(errno));\n+\t\t\t\tdie_errno(\"could not read MERGE_MODE\");\n \t\t\tif (!strcmp(sb.buf, \"no-ff\"))\n \t\t\t\tallow_fast_forward = 0;\n \t\t}\ndiff --git a/builtin-config.c b/builtin-config.c\nindex 60915f9..6858433 100644\n--- a/builtin-config.c\n+++ b/builtin-config.c\n@@ -383,8 +383,8 @@ int cmd_config(int argc, const char **argv, const char *unused_prefix)\n \t\tcheck_argc(argc, 0, 0);\n \t\tif (git_config(show_all_config, NULL) < 0) {\n \t\t\tif (config_exclusive_filename)\n-\t\t\t\tdie(\"unable to read config file %s: %s\",\n-\t\t\t\t    config_exclusive_filename, strerror(errno));\n+\t\t\t\tdie_errno(\"unable to read config file %s\",\n+\t\t\t\t\t  config_exclusive_filename);\n \t\t\telse\n \t\t\t\tdie(\"error processing config file(s)\");\n \t\t}\ndiff --git a/builtin-diff.c b/builtin-diff.c\nindex d75d69b..2e51f40 100644\n--- a/builtin-diff.c\n+++ b/builtin-diff.c\n@@ -70,7 +70,7 @@ static int builtin_diff_b_f(struct rev_info *revs,\n \t\tusage(builtin_diff_usage);\n \n \tif (lstat(path, &st))\n-\t\tdie(\"'%s': %s\", path, strerror(errno));\n+\t\tdie_errno(\"failed to stat '%s'\", path);\n \tif (!(S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)))\n \t\tdie(\"'%s': not a regular file or symlink\", path);\n \ndiff --git a/builtin-fast-export.c b/builtin-fast-export.c\nindex 6cef810..333d438 100644\n--- a/builtin-fast-export.c\n+++ b/builtin-fast-export.c\n@@ -451,7 +451,7 @@ static void import_marks(char *input_file)\n \tchar line[512];\n \tFILE *f = fopen(input_file, \"r\");\n \tif (!f)\n-\t\tdie(\"cannot read %s: %s\", input_file, strerror(errno));\n+\t\tdie_errno(\"cannot read '%s'\", input_file);\n \n \twhile (fgets(line, sizeof(line), f)) {\n \t\tuint32_t mark;\ndiff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c\nindex 29356d2..3dbdf7a 100644\n--- a/builtin-fetch--tool.c\n+++ b/builtin-fetch--tool.c\n@@ -8,7 +8,7 @@\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tif (strbuf_read(&buf, 0, 1024) < 0) {\n-\t\tdie(\"error reading standard input: %s\", strerror(errno));\n+\t\tdie_errno(\"error reading standard input\");\n \t}\n \treturn strbuf_detach(&buf, NULL);\n }\ndiff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c\nindex fbf9582..1248d5e 100644\n--- a/builtin-fmt-merge-msg.c\n+++ b/builtin-fmt-merge-msg.c\n@@ -372,8 +372,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \t}\n \n \tif (strbuf_read(&input, fileno(in), 0) < 0)\n-\t\tdie(\"could not read input file %s\", strerror(errno));\n-\n+\t\tdie_errno(\"could not read input file\");\n \tret = fmt_merge_msg(merge_summary, &input, &output);\n \tif (ret)\n \t\treturn ret;\ndiff --git a/builtin-fsck.c b/builtin-fsck.c\nindex 7da706c..a49dbe1 100644\n--- a/builtin-fsck.c\n+++ b/builtin-fsck.c\n@@ -225,15 +225,15 @@ static void check_unreachable_object(struct object *obj)\n \t\t\t\t\t\t&type, &size);\n \t\t\t\tif (buf) {\n \t\t\t\t\tif (fwrite(buf, size, 1, f) != 1)\n-\t\t\t\t\t\tdie(\"Could not write %s: %s\",\n-\t\t\t\t\t\t    filename, strerror(errno));\n+\t\t\t\t\t\tdie_errno(\"Could not write '%s'\",\n+\t\t\t\t\t\t\t  filename);\n \t\t\t\t\tfree(buf);\n \t\t\t\t}\n \t\t\t} else\n \t\t\t\tfprintf(f, \"%s\\n\", sha1_to_hex(obj->sha1));\n \t\t\tif (fclose(f))\n-\t\t\t\tdie(\"Could not finish %s: %s\",\n-\t\t\t\t    filename, strerror(errno));\n+\t\t\t\tdie_errno(\"Could not finish '%s'\",\n+\t\t\t\t\t  filename);\n \t\t}\n \t\treturn;\n \t}\ndiff --git a/builtin-grep.c b/builtin-grep.c\nindex 73fc922..e558368 100644\n--- a/builtin-grep.c\n+++ b/builtin-grep.c\n@@ -594,7 +594,7 @@ static int file_callback(const struct option *opt, const char *arg, int unset)\n \n \tpatterns = fopen(arg, \"r\");\n \tif (!patterns)\n-\t\tdie(\"'%s': %s\", arg, strerror(errno));\n+\t\tdie_errno(\"cannot open '%s'\", arg);\n \twhile (strbuf_getline(&sb, patterns, '\\n') == 0) {\n \t\t/* ignore empty line like grep does */\n \t\tif (sb.len == 0)\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex 8d101ef..a7e03ce 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -294,9 +294,9 @@ static void squash_message(void)\n \t\t\tNULL, NULL, rev.date_mode, 0);\n \t}\n \tif (write(fd, out.buf, out.len) < 0)\n-\t\tdie(\"Writing SQUASH_MSG: %s\", strerror(errno));\n+\t\tdie_errno(\"Writing SQUASH_MSG\");\n \tif (close(fd))\n-\t\tdie(\"Finishing SQUASH_MSG: %s\", strerror(errno));\n+\t\tdie_errno(\"Finishing SQUASH_MSG\");\n \tstrbuf_release(&out);\n }\n \n@@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct strbuf *msg)\n \n \t\tfp = fopen(git_path(\"FETCH_HEAD\"), \"r\");\n \t\tif (!fp)\n-\t\t\tdie(\"could not open %s for reading: %s\",\n-\t\t\t\tgit_path(\"FETCH_HEAD\"), strerror(errno));\n+\t\t\tdie_errno(\"could not open %s for reading\",\n+\t\t\t\t  git_path(\"FETCH_HEAD\"));\n \t\tstrbuf_getline(&line, fp, '\\n');\n \t\tfclose(fp);\n \t\tptr = strstr(line.buf, \"\\tnot-for-merge\\t\");\ndiff --git a/builtin-mv.c b/builtin-mv.c\nindex 8b81d4b..e82ed20 100644\n--- a/builtin-mv.c\n+++ b/builtin-mv.c\n@@ -209,7 +209,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)\n \t\t\tprintf(\"Renaming %s to %s\\n\", src, dst);\n \t\tif (!show_only && mode != INDEX &&\n \t\t\t\trename(src, dst) < 0 && !ignore_errors)\n-\t\t\tdie (\"renaming %s failed: %s\", src, strerror(errno));\n+\t\t\tdie_errno (\"renaming %s failed\", src);\n \n \t\tif (mode == WORKING_DIRECTORY)\n \t\t\tcontinue;\ndiff --git a/builtin-pack-objects.c b/builtin-pack-objects.c\nindex 9742b45..60355d4 100644\n--- a/builtin-pack-objects.c\n+++ b/builtin-pack-objects.c\n@@ -536,11 +536,9 @@ static void write_pack_file(void)\n \t\t\t\t base_name, sha1_to_hex(sha1));\n \t\t\tfree_pack_by_name(tmpname);\n \t\t\tif (adjust_perm(pack_tmp_name, mode))\n-\t\t\t\tdie(\"unable to make temporary pack file readable: %s\",\n-\t\t\t\t    strerror(errno));\n+\t\t\t\tdie_errno(\"unable to make temporary pack file readable\");\n \t\t\tif (rename(pack_tmp_name, tmpname))\n-\t\t\t\tdie(\"unable to rename temporary pack file: %s\",\n-\t\t\t\t    strerror(errno));\n+\t\t\t\tdie_errno(\"unable to rename temporary pack file\");\n \n \t\t\t/*\n \t\t\t * Packs are runtime accessed in their mtime\n@@ -566,11 +564,9 @@ static void write_pack_file(void)\n \t\t\tsnprintf(tmpname, sizeof(tmpname), \"%s-%s.idx\",\n \t\t\t\t base_name, sha1_to_hex(sha1));\n \t\t\tif (adjust_perm(idx_tmp_name, mode))\n-\t\t\t\tdie(\"unable to make temporary index file readable: %s\",\n-\t\t\t\t    strerror(errno));\n+\t\t\t\tdie_errno(\"unable to make temporary index file readable\");\n \t\t\tif (rename(idx_tmp_name, tmpname))\n-\t\t\t\tdie(\"unable to rename temporary index file: %s\",\n-\t\t\t\t    strerror(errno));\n+\t\t\t\tdie_errno(\"unable to rename temporary index file\");\n \n \t\t\tfree(idx_tmp_name);\n \t\t\tfree(pack_tmp_name);\n@@ -1880,7 +1876,7 @@ static void read_object_list_from_stdin(void)\n \t\t\tif (!ferror(stdin))\n \t\t\t\tdie(\"fgets returned NULL, not EOF, not error!\");\n \t\t\tif (errno != EINTR)\n-\t\t\t\tdie(\"fgets: %s\", strerror(errno));\n+\t\t\t\tdie_errno(\"fgets\");\n \t\t\tclearerr(stdin);\n \t\t\tcontinue;\n \t\t}\ndiff --git a/builtin-rm.c b/builtin-rm.c\nindex 0cc4912..d632ef4 100644\n--- a/builtin-rm.c\n+++ b/builtin-rm.c\n@@ -257,7 +257,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!removed)\n-\t\t\t\tdie(\"git rm: %s: %s\", path, strerror(errno));\n+\t\t\t\tdie_errno(\"git rm: %s\", path);\n \t\t}\n \t}\n \ndiff --git a/builtin-send-pack.c b/builtin-send-pack.c\nindex be3b092..8fe5ab9 100644\n--- a/builtin-send-pack.c\n+++ b/builtin-send-pack.c\n@@ -59,7 +59,7 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext\n \tpo.out = fd;\n \tpo.git_cmd = 1;\n \tif (start_command(&po))\n-\t\tdie(\"git pack-objects failed (%s)\", strerror(errno));\n+\t\tdie_errno(\"git pack-objects failed\");\n \n \t/*\n \t * We feed the pack-objects we just spawned with revision\ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex dc3db62..7b51095 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -308,8 +308,7 @@ static void create_tag(const unsigned char *object, const char *tag,\n \t\tpath = git_pathdup(\"TAG_EDITMSG\");\n \t\tfd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);\n \t\tif (fd < 0)\n-\t\t\tdie(\"could not create file '%s': %s\",\n-\t\t\t\t\t\tpath, strerror(errno));\n+\t\t\tdie_errno(\"could not create file '%s'\", path);\n \n \t\tif (!is_null_sha1(prev))\n \t\t\twrite_tag_body(fd, prev);\n@@ -446,8 +445,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tdie(\"cannot read %s\", msgfile);\n \t\t\t} else {\n \t\t\t\tif (strbuf_read_file(&buf, msgfile, 1024) < 0)\n-\t\t\t\t\tdie(\"could not open or read '%s': %s\",\n-\t\t\t\t\t\tmsgfile, strerror(errno));\n+\t\t\t\t\tdie_errno(\"could not open or read '%s'\",\n+\t\t\t\t\t\tmsgfile);\n \t\t\t}\n \t\t}\n \t}\ndiff --git a/builtin-unpack-objects.c b/builtin-unpack-objects.c\nindex 9a77323..41e9ac5 100644\n--- a/builtin-unpack-objects.c\n+++ b/builtin-unpack-objects.c\n@@ -68,7 +68,7 @@ static void add_object_buffer(struct object *object, char *buffer, unsigned long\n \t\tif (ret <= 0) {\n \t\t\tif (!ret)\n \t\t\t\tdie(\"early EOF\");\n-\t\t\tdie(\"read error on input: %s\", strerror(errno));\n+\t\t\tdie_errno(\"read error on input\");\n \t\t}\n \t\tlen += ret;\n \t} while (len < min);\ndiff --git a/connect.c b/connect.c\nindex f6b8ba6..fd2f9b6 100644\n--- a/connect.c\n+++ b/connect.c\n@@ -256,7 +256,7 @@ static int git_tcp_connect_sock(char *host, int flags)\n \tfreeaddrinfo(ai0);\n \n \tif (sockfd < 0)\n-\t\tdie(\"unable to connect a socket (%s)\", strerror(saved_errno));\n+\t\tdie_errno(\"unable to connect a socket\");\n \n \tif (flags & CONNECT_VERBOSE)\n \t\tfprintf(stderr, \"done.\\n\");\n@@ -345,7 +345,7 @@ static int git_tcp_connect_sock(char *host, int flags)\n \t}\n \n \tif (sockfd < 0)\n-\t\tdie(\"unable to connect a socket (%s)\", strerror(saved_errno));\n+\t\tdie_errno(\"unable to connect a socket\");\n \n \tif (flags & CONNECT_VERBOSE)\n \t\tfprintf(stderr, \"done.\\n\");\ndiff --git a/csum-file.c b/csum-file.c\nindex 2ddb12a..9cc93ba 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -26,7 +26,7 @@ static void flush(struct sha1file *f, void * buf, unsigned int count)\n \t\t}\n \t\tif (!ret)\n \t\t\tdie(\"sha1 file '%s' write error. Out of diskspace\", f->name);\n-\t\tdie(\"sha1 file '%s' write error (%s)\", f->name, strerror(errno));\n+\t\tdie_errno(\"sha1 file '%s' write error\", f->name);\n \t}\n }\n \n@@ -55,8 +55,8 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)\n \t\tif (flags & CSUM_FSYNC)\n \t\t\tfsync_or_die(f->fd, f->name);\n \t\tif (close(f->fd))\n-\t\t\tdie(\"%s: sha1 file error on close (%s)\",\n-\t\t\t    f->name, strerror(errno));\n+\t\t\tdie_errno(\"%s: sha1 file error on close\",\n+\t\t\t    f->name);\n \t\tfd = 0;\n \t} else\n \t\tfd = f->fd;\ndiff --git a/daemon.c b/daemon.c\nindex daa4c8e..5657661 100644\n--- a/daemon.c\n+++ b/daemon.c\n@@ -860,7 +860,7 @@ static int service_loop(int socknum, int *socklist)\n \t\t\t\t\tcase ECONNABORTED:\n \t\t\t\t\t\tcontinue;\n \t\t\t\t\tdefault:\n-\t\t\t\t\t\tdie(\"accept returned %s\", strerror(errno));\n+\t\t\t\t\t\tdie_errno(\"accept returned\");\n \t\t\t\t\t}\n \t\t\t\t}\n \t\t\t\thandle(incoming, (struct sockaddr *)&ss, sslen);\n@@ -876,7 +876,7 @@ static void sanitize_stdfds(void)\n \twhile (fd != -1 && fd < 2)\n \t\tfd = dup(fd);\n \tif (fd == -1)\n-\t\tdie(\"open /dev/null or dup failed: %s\", strerror(errno));\n+\t\tdie_errno(\"open /dev/null or dup failed\");\n \tif (fd > 2)\n \t\tclose(fd);\n }\n@@ -887,12 +887,12 @@ static void daemonize(void)\n \t\tcase 0:\n \t\t\tbreak;\n \t\tcase -1:\n-\t\t\tdie(\"fork failed: %s\", strerror(errno));\n+\t\t\tdie_errno(\"fork failed\");\n \t\tdefault:\n \t\t\texit(0);\n \t}\n \tif (setsid() == -1)\n-\t\tdie(\"setsid failed: %s\", strerror(errno));\n+\t\tdie_errno(\"setsid failed\");\n \tclose(0);\n \tclose(1);\n \tclose(2);\n@@ -903,9 +903,9 @@ static void store_pid(const char *path)\n {\n \tFILE *f = fopen(path, \"w\");\n \tif (!f)\n-\t\tdie(\"cannot open pid file %s: %s\", path, strerror(errno));\n+\t\tdie_errno(\"cannot open pid file %s\", path);\n \tif (fprintf(f, \"%\"PRIuMAX\"\\n\", (uintmax_t) getpid()) < 0 || fclose(f) != 0)\n-\t\tdie(\"failed to write pid file %s: %s\", path, strerror(errno));\n+\t\tdie_errno(\"failed to write pid file %s\", path);\n }\n \n static int serve(char *listen_addr, int listen_port, struct passwd *pass, gid_t gid)\n@@ -1105,8 +1105,7 @@ int main(int argc, char **argv)\n \t\tsocklen_t slen = sizeof(ss);\n \n \t\tif (!freopen(\"/dev/null\", \"w\", stderr))\n-\t\t\tdie(\"failed to redirect stderr to /dev/null: %s\",\n-\t\t\t    strerror(errno));\n+\t\t\tdie_errno(\"failed to redirect stderr to /dev/null\");\n \n \t\tif (getpeername(0, peer, &slen))\n \t\t\tpeer = NULL;\ndiff --git a/diff.c b/diff.c\nindex 4d0a5b9..48043f5 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1975,7 +1975,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \tfd = git_mkstemps(temp->tmp_path, PATH_MAX, template.buf,\n \t\t\tstrlen(base) + 1);\n \tif (fd < 0)\n-\t\tdie(\"unable to create temp-file: %s\", strerror(errno));\n+\t\tdie_errno(\"unable to create temp-file\");\n \tif (convert_to_working_tree(path,\n \t\t\t(const char *)blob, (size_t)size, &buf)) {\n \t\tblob = buf.buf;\n@@ -2021,7 +2021,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \t\tif (lstat(name, &st) < 0) {\n \t\t\tif (errno == ENOENT)\n \t\t\t\tgoto not_a_valid_file;\n-\t\t\tdie(\"stat(%s): %s\", name, strerror(errno));\n+\t\t\tdie_errno(\"stat(%s)\", name);\n \t\t}\n \t\tif (S_ISLNK(st.st_mode)) {\n \t\t\tstruct strbuf sb = STRBUF_INIT;\ndiff --git a/dir.c b/dir.c\nindex bbfcb56..74b3bbf 100644\n--- a/dir.c\n+++ b/dir.c\n@@ -759,7 +759,7 @@ int file_exists(const char *f)\n \tif (!dir)\n \t\treturn NULL;\n \tif (!getcwd(buffer, size))\n-\t\tdie(\"can't find the current directory: %s\", strerror(errno));\n+\t\tdie_errno(\"can't find the current directory\");\n \n \tif (!is_absolute_path(dir))\n \t\tdir = make_absolute_path(dir);\ndiff --git a/entry.c b/entry.c\nindex cc841ed..099eaf4 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -51,7 +51,7 @@ static void remove_subtree(const char *path)\n \tchar *name;\n \n \tif (!dir)\n-\t\tdie(\"cannot opendir %s (%s)\", path, strerror(errno));\n+\t\tdie_errno(\"cannot opendir '%s'\", path);\n \tstrcpy(pathbuf, path);\n \tname = pathbuf + strlen(path);\n \t*name++ = '/';\n@@ -61,15 +61,15 @@ static void remove_subtree(const char *path)\n \t\t\tcontinue;\n \t\tstrcpy(name, de->d_name);\n \t\tif (lstat(pathbuf, &st))\n-\t\t\tdie(\"cannot lstat %s (%s)\", pathbuf, strerror(errno));\n+\t\t\tdie_errno(\"cannot lstat %s\", pathbuf);\n \t\tif (S_ISDIR(st.st_mode))\n \t\t\tremove_subtree(pathbuf);\n \t\telse if (unlink(pathbuf))\n-\t\t\tdie(\"cannot unlink %s (%s)\", pathbuf, strerror(errno));\n+\t\t\tdie_errno(\"cannot unlink %s\", pathbuf);\n \t}\n \tclosedir(dir);\n \tif (rmdir(path))\n-\t\tdie(\"cannot rmdir %s (%s)\", path, strerror(errno));\n+\t\tdie_errno(\"cannot rmdir %s\", path);\n }\n \n static int create_file(const char *path, unsigned int mode)\ndiff --git a/fast-import.c b/fast-import.c\nindex a2a2458..d31a4e8 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -2342,7 +2342,7 @@ static void import_marks(const char *input_file)\n \tchar line[512];\n \tFILE *f = fopen(input_file, \"r\");\n \tif (!f)\n-\t\tdie(\"cannot read %s: %s\", input_file, strerror(errno));\n+\t\tdie_errno(\"cannot read '%s'\", input_file);\n \twhile (fgets(line, sizeof(line), f)) {\n \t\tuintmax_t mark;\n \t\tchar *end;\n@@ -2448,7 +2448,7 @@ int main(int argc, const char **argv)\n \t\t\t\tfclose(pack_edges);\n \t\t\tpack_edges = fopen(a + 20, \"a\");\n \t\t\tif (!pack_edges)\n-\t\t\t\tdie(\"Cannot open %s: %s\", a + 20, strerror(errno));\n+\t\t\t\tdie_errno(\"Cannot open '%s'\", a + 20);\n \t\t} else if (!strcmp(a, \"--force\"))\n \t\t\tforce_update = 1;\n \t\telse if (!strcmp(a, \"--quiet\"))\ndiff --git a/git.c b/git.c\nindex 7d7f949..b035676 100644\n--- a/git.c\n+++ b/git.c\n@@ -200,7 +200,7 @@ static int handle_alias(int *argcp, const char ***argv)\n \t}\n \n \tif (subdir && chdir(subdir))\n-\t\tdie(\"Cannot change to %s: %s\", subdir, strerror(errno));\n+\t\tdie_errno(\"Cannot change to '%s'\", subdir);\n \n \terrno = saved_errno;\n \n@@ -257,11 +257,11 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)\n \n \t/* Check for ENOSPC and EIO errors.. */\n \tif (fflush(stdout))\n-\t\tdie(\"write failure on standard output: %s\", strerror(errno));\n+\t\tdie_errno(\"write failure on standard output\");\n \tif (ferror(stdout))\n \t\tdie(\"unknown write failure on standard output\");\n \tif (fclose(stdout))\n-\t\tdie(\"close failed on standard output: %s\", strerror(errno));\n+\t\tdie_errno(\"close failed on standard output\");\n \treturn 0;\n }\n \ndiff --git a/index-pack.c b/index-pack.c\nindex 6e93ee6..cf6446f 100644\n--- a/index-pack.c\n+++ b/index-pack.c\n@@ -143,7 +143,7 @@ static void flush(void)\n \t\tif (ret <= 0) {\n \t\t\tif (!ret)\n \t\t\t\tdie(\"early EOF\");\n-\t\t\tdie(\"read error on input: %s\", strerror(errno));\n+\t\t\tdie_errno(\"read error on input\");\n \t\t}\n \t\tinput_len += ret;\n \t\tif (from_stdin)\n@@ -178,13 +178,12 @@ static void use(int bytes)\n \t\t} else\n \t\t\toutput_fd = open(pack_name, O_CREAT|O_EXCL|O_RDWR, 0600);\n \t\tif (output_fd < 0)\n-\t\t\tdie(\"unable to create %s: %s\", pack_name, strerror(errno));\n+\t\t\tdie_errno(\"unable to create '%s'\", pack_name);\n \t\tpack_fd = output_fd;\n \t} else {\n \t\tinput_fd = open(pack_name, O_RDONLY);\n \t\tif (input_fd < 0)\n-\t\t\tdie(\"cannot open packfile '%s': %s\",\n-\t\t\t    pack_name, strerror(errno));\n+\t\t\tdie_errno(\"cannot open packfile '%s'\", pack_name);\n \t\toutput_fd = -1;\n \t\tpack_fd = input_fd;\n \t}\n@@ -370,7 +369,7 @@ static void unlink_base_data(struct base_data *c)\n \tdo {\n \t\tssize_t n = pread(pack_fd, data + rdy, len - rdy, from + rdy);\n \t\tif (n < 0)\n-\t\t\tdie(\"cannot pread pack file: %s\", strerror(errno));\n+\t\t\tdie_errno(\"cannot pread pack file\");\n \t\tif (!n)\n \t\t\tdie(\"premature end of pack file, %lu bytes missing\",\n \t\t\t    len - rdy);\n@@ -631,7 +630,7 @@ static void parse_pack_objects(unsigned char *sha1)\n \n \t/* If input_fd is a file, we should have reached its end now. */\n \tif (fstat(input_fd, &st))\n-\t\tdie(\"cannot fstat packfile: %s\", strerror(errno));\n+\t\tdie_errno(\"cannot fstat packfile\");\n \tif (S_ISREG(st.st_mode) &&\n \t\t\tlseek(input_fd, 0, SEEK_CUR) - input_len != st.st_size)\n \t\tdie(\"pack has junk at the end\");\n@@ -788,7 +787,7 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \t\tfsync_or_die(output_fd, curr_pack_name);\n \t\terr = close(output_fd);\n \t\tif (err)\n-\t\t\tdie(\"error while closing pack file: %s\", strerror(errno));\n+\t\t\tdie_errno(\"error while closing pack file\");\n \t}\n \n \tif (keep_msg) {\n@@ -801,16 +800,16 @@ static void final(const char *final_pack_name, const char *curr_pack_name,\n \n \t\tif (keep_fd < 0) {\n \t\t\tif (errno != EEXIST)\n-\t\t\t\tdie(\"cannot write keep file '%s' (%s)\",\n-\t\t\t\t    keep_name, strerror(errno));\n+\t\t\t\tdie_errno(\"cannot write keep file '%s'\",\n+\t\t\t\t\t  keep_name);\n \t\t} else {\n \t\t\tif (keep_msg_len > 0) {\n \t\t\t\twrite_or_die(keep_fd, keep_msg, keep_msg_len);\n \t\t\t\twrite_or_die(keep_fd, \"\\n\", 1);\n \t\t\t}\n \t\t\tif (close(keep_fd) != 0)\n-\t\t\t\tdie(\"cannot close written keep file '%s' (%s)\",\n-\t\t\t\t    keep_name, strerror(errno));\n+\t\t\t\tdie_errno(\"cannot close written keep file '%s'\",\n+\t\t\t\t    keep_name);\n \t\t\treport = \"keep\";\n \t\t}\n \t}\ndiff --git a/merge-recursive.c b/merge-recursive.c\nindex f5df9b9..5d9140b 100644\n--- a/merge-recursive.c\n+++ b/merge-recursive.c\n@@ -438,7 +438,7 @@ static void flush_buffer(int fd, const char *buf, unsigned long size)\n \t\t\t/* Ignore epipe */\n \t\t\tif (errno == EPIPE)\n \t\t\t\tbreak;\n-\t\t\tdie(\"merge-recursive: %s\", strerror(errno));\n+\t\t\tdie_errno(\"merge-recursive\");\n \t\t} else if (!ret) {\n \t\t\tdie(\"merge-recursive: disk full?\");\n \t\t}\n@@ -554,7 +554,7 @@ static void update_file_flags(struct merge_options *o,\n \t\t\t\tmode = 0666;\n \t\t\tfd = open(path, O_WRONLY | O_TRUNC | O_CREAT, mode);\n \t\t\tif (fd < 0)\n-\t\t\t\tdie(\"failed to open %s: %s\", path, strerror(errno));\n+\t\t\t\tdie_errno(\"failed to open '%s'\", path);\n \t\t\tflush_buffer(fd, buf, size);\n \t\t\tclose(fd);\n \t\t} else if (S_ISLNK(mode)) {\n@@ -562,7 +562,7 @@ static void update_file_flags(struct merge_options *o,\n \t\t\tsafe_create_leading_directories_const(path);\n \t\t\tunlink(path);\n \t\t\tif (symlink(lnk, path))\n-\t\t\t\tdie(\"failed to symlink %s: %s\", path, strerror(errno));\n+\t\t\t\tdie_errno(\"failed to symlink '%s'\", path);\n \t\t\tfree(lnk);\n \t\t} else\n \t\t\tdie(\"do not know what to do with %06o %s '%s'\",\ndiff --git a/pack-refs.c b/pack-refs.c\nindex 301fc60..7f43f8a 100644\n--- a/pack-refs.c\n+++ b/pack-refs.c\n@@ -93,8 +93,7 @@ int pack_refs(unsigned int flags)\n \t\t\t\t       LOCK_DIE_ON_ERROR);\n \tcbdata.refs_file = fdopen(fd, \"w\");\n \tif (!cbdata.refs_file)\n-\t\tdie(\"unable to create ref-pack file structure (%s)\",\n-\t\t    strerror(errno));\n+\t\tdie_errno(\"unable to create ref-pack file structure\");\n \n \t/* perhaps other traits later as well */\n \tfprintf(cbdata.refs_file, \"# pack-refs with: peeled \\n\");\n@@ -103,7 +102,7 @@ int pack_refs(unsigned int flags)\n \tif (ferror(cbdata.refs_file))\n \t\tdie(\"failed to write ref-pack file\");\n \tif (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file))\n-\t\tdie(\"failed to write ref-pack file (%s)\", strerror(errno));\n+\t\tdie_errno(\"failed to write ref-pack file\");\n \t/*\n \t * Since the lock file was fdopen()'ed and then fclose()'ed above,\n \t * assign -1 to the lock file descriptor so that commit_lock_file()\n@@ -111,7 +110,7 @@ int pack_refs(unsigned int flags)\n \t */\n \tpacked.fd = -1;\n \tif (commit_lock_file(&packed) < 0)\n-\t\tdie(\"unable to overwrite old ref-pack file (%s)\", strerror(errno));\n+\t\tdie_errno(\"unable to overwrite old ref-pack file\");\n \tif (cbdata.flags & PACK_REFS_PRUNE)\n \t\tprune_refs(cbdata.ref_to_prune);\n \treturn 0;\ndiff --git a/pack-write.c b/pack-write.c\nindex 7053538..0117037 100644\n--- a/pack-write.c\n+++ b/pack-write.c\n@@ -51,7 +51,7 @@ static int sha1_compare(const void *_a, const void *_b)\n \t\tfd = open(index_name, O_CREAT|O_EXCL|O_WRONLY, 0600);\n \t}\n \tif (fd < 0)\n-\t\tdie(\"unable to create %s: %s\", index_name, strerror(errno));\n+\t\tdie_errno(\"unable to create %s\", index_name);\n \tf = sha1fd(fd, index_name);\n \n \t/* if last object's offset is >= 2^31 we should use index V2 */\n@@ -174,11 +174,11 @@ void fixup_pack_header_footer(int pack_fd,\n \tgit_SHA1_Init(&new_sha1_ctx);\n \n \tif (lseek(pack_fd, 0, SEEK_SET) != 0)\n-\t\tdie(\"Failed seeking to start of %s: %s\", pack_name, strerror(errno));\n+\t\tdie_errno(\"Failed seeking to start of '%s'\", pack_name);\n \tif (read_in_full(pack_fd, &hdr, sizeof(hdr)) != sizeof(hdr))\n-\t\tdie(\"Unable to reread header of %s: %s\", pack_name, strerror(errno));\n+\t\tdie_errno(\"Unable to reread header of '%s'\", pack_name);\n \tif (lseek(pack_fd, 0, SEEK_SET) != 0)\n-\t\tdie(\"Failed seeking to start of %s: %s\", pack_name, strerror(errno));\n+\t\tdie_errno(\"Failed seeking to start of '%s'\", pack_name);\n \tgit_SHA1_Update(&old_sha1_ctx, &hdr, sizeof(hdr));\n \thdr.hdr_entries = htonl(object_count);\n \tgit_SHA1_Update(&new_sha1_ctx, &hdr, sizeof(hdr));\n@@ -195,7 +195,7 @@ void fixup_pack_header_footer(int pack_fd,\n \t\tif (!n)\n \t\t\tbreak;\n \t\tif (n < 0)\n-\t\t\tdie(\"Failed to checksum %s: %s\", pack_name, strerror(errno));\n+\t\t\tdie_errno(\"Failed to checksum '%s'\", pack_name);\n \t\tgit_SHA1_Update(&new_sha1_ctx, buf, n);\n \n \t\taligned_sz -= n;\ndiff --git a/pkt-line.c b/pkt-line.c\nindex f5d0086..b691abe 100644\n--- a/pkt-line.c\n+++ b/pkt-line.c\n@@ -28,7 +28,7 @@ ssize_t safe_write(int fd, const void *buf, ssize_t n)\n \t\t}\n \t\tif (!ret)\n \t\t\tdie(\"write error (disk full?)\");\n-\t\tdie(\"write error (%s)\", strerror(errno));\n+\t\tdie_errno(\"write error\");\n \t}\n \treturn nn;\n }\n@@ -67,7 +67,7 @@ static void safe_read(int fd, void *buffer, unsigned size)\n {\n \tssize_t ret = read_in_full(fd, buffer, size);\n \tif (ret < 0)\n-\t\tdie(\"read error (%s)\", strerror(errno));\n+\t\tdie_errno(\"read error\");\n \telse if (ret < size)\n \t\tdie(\"The remote end hung up unexpectedly\");\n }\ndiff --git a/read-cache.c b/read-cache.c\nindex 3f58711..f76b5bb 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -638,7 +638,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int flags)\n {\n \tstruct stat st;\n \tif (lstat(path, &st))\n-\t\tdie(\"%s: unable to stat (%s)\", path, strerror(errno));\n+\t\tdie_errno(\"unable to stat '%s'\", path);\n \treturn add_to_index(istate, path, &st, flags);\n }\n \n@@ -1251,11 +1251,11 @@ int read_index_from(struct index_state *istate, const char *path)\n \tif (fd < 0) {\n \t\tif (errno == ENOENT)\n \t\t\treturn 0;\n-\t\tdie(\"index file open failed (%s)\", strerror(errno));\n+\t\tdie_errno(\"index file open failed\");\n \t}\n \n \tif (fstat(fd, &st))\n-\t\tdie(\"cannot stat the open index (%s)\", strerror(errno));\n+\t\tdie_errno(\"cannot stat the open index\");\n \n \terrno = EINVAL;\n \tmmap_size = xsize_t(st.st_size);\ndiff --git a/refs.c b/refs.c\nindex 24438c6..dffe395 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1418,7 +1418,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char *\n \tlogfile = git_path(\"logs/%s\", ref);\n \tlogfd = open(logfile, O_RDONLY, 0);\n \tif (logfd < 0)\n-\t\tdie(\"Unable to read log %s: %s\", logfile, strerror(errno));\n+\t\tdie_errno(\"Unable to read log '%s'\", logfile);\n \tfstat(logfd, &st);\n \tif (!st.st_size)\n \t\tdie(\"Log %s is empty.\", logfile);\ndiff --git a/run-command.c b/run-command.c\nindex eb2efc3..79bdfd4 100644\n--- a/run-command.c\n+++ b/run-command.c\n@@ -101,8 +101,8 @@ int start_command(struct child_process *cmd)\n \t\t}\n \n \t\tif (cmd->dir && chdir(cmd->dir))\n-\t\t\tdie(\"exec %s: cd to %s failed (%s)\", cmd->argv[0],\n-\t\t\t    cmd->dir, strerror(errno));\n+\t\t\tdie_errno(\"exec %s: cd to '%s' failed\", cmd->argv[0],\n+\t\t\t    cmd->dir);\n \t\tif (cmd->env) {\n \t\t\tfor (; *cmd->env; cmd->env++) {\n \t\t\t\tif (strchr(*cmd->env, '='))\ndiff --git a/setup.c b/setup.c\nindex ebd60de..4d27f28 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -81,7 +81,7 @@ void verify_filename(const char *prefix, const char *arg)\n \tif (errno == ENOENT)\n \t\tdie(\"ambiguous argument '%s': unknown revision or path not in the working tree.\\n\"\n \t\t    \"Use '--' to separate paths from revisions\", arg);\n-\tdie(\"'%s': %s\", arg, strerror(errno));\n+\tdie_errno(\"failed to stat '%s'\", arg);\n }\n \n /*\n@@ -103,7 +103,7 @@ void verify_non_filename(const char *prefix, const char *arg)\n \t\tdie(\"ambiguous argument '%s': both revision and filename\\n\"\n \t\t    \"Use '--' to separate filenames from revisions\", arg);\n \tif (errno != ENOENT && errno != ENOTDIR)\n-\t\tdie(\"'%s': %s\", arg, strerror(errno));\n+\t\tdie_errno(\"failed to stat '%s'\", arg);\n }\n \n const char **get_pathspec(const char *prefix, const char **pathspec)\n@@ -257,7 +257,7 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\treturn NULL;\n \tfd = open(path, O_RDONLY);\n \tif (fd < 0)\n-\t\tdie(\"Error opening %s: %s\", path, strerror(errno));\n+\t\tdie_errno(\"Error opening '%s'\", path);\n \tbuf = xmalloc(st.st_size + 1);\n \tlen = read_in_full(fd, buf, st.st_size);\n \tclose(fd);\n@@ -389,7 +389,7 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\t\tdie(\"Not a git repository (or any of the parent directories): %s\", DEFAULT_GIT_DIR_ENVIRONMENT);\n \t\t}\n \t\tif (chdir(\"..\"))\n-\t\t\tdie(\"Cannot change to %s/..: %s\", cwd, strerror(errno));\n+\t\t\tdie_errno(\"Cannot change to '%s/..'\", cwd);\n \t}\n \n \tinside_git_dir = 0;\ndiff --git a/sha1_file.c b/sha1_file.c\nindex e73cd4f..1964a6d 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2287,7 +2287,7 @@ static void close_sha1_file(int fd)\n \tif (fsync_object_files)\n \t\tfsync_or_die(fd, \"sha1 file\");\n \tif (close(fd) != 0)\n-\t\tdie(\"error when closing sha1 file (%s)\", strerror(errno));\n+\t\tdie_errno(\"error when closing sha1 file\");\n }\n \n /* Size of directory component, including the ending '/' */\ndiff --git a/shell.c b/shell.c\nindex b968be7..e4864e0 100644\n--- a/shell.c\n+++ b/shell.c\n@@ -60,7 +60,7 @@ int main(int argc, char **argv)\n \twhile (devnull_fd >= 0 && devnull_fd <= 2)\n \t\tdevnull_fd = dup(devnull_fd);\n \tif (devnull_fd == -1)\n-\t\tdie(\"opening /dev/null failed (%s)\", strerror(errno));\n+\t\tdie_errno(\"opening /dev/null failed\");\n \tclose (devnull_fd);\n \n \t/*\ndiff --git a/test-sha1.c b/test-sha1.c\nindex 9b98d07..80daba9 100644\n--- a/test-sha1.c\n+++ b/test-sha1.c\n@@ -32,7 +32,7 @@ int main(int ac, char **av)\n \t\t\tif (sz == 0)\n \t\t\t\tbreak;\n \t\t\tif (sz < 0)\n-\t\t\t\tdie(\"test-sha1: %s\", strerror(errno));\n+\t\t\t\tdie_errno(\"test-sha1\");\n \t\t\tthis_sz += sz;\n \t\t\tcp += sz;\n \t\t\troom -= sz;\ndiff --git a/wrapper.c b/wrapper.c\nindex 7eb3218..c9be140 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -96,7 +96,7 @@\n \t\trelease_pack_memory(length, fd);\n \t\tret = mmap(start, length, prot, flags, fd, offset);\n \t\tif (ret == MAP_FAILED)\n-\t\t\tdie(\"Out of memory? mmap failed: %s\", strerror(errno));\n+\t\t\tdie_errno(\"Out of memory? mmap failed\");\n \t}\n \treturn ret;\n }\n@@ -175,7 +175,7 @@ int xdup(int fd)\n {\n \tint ret = dup(fd);\n \tif (ret < 0)\n-\t\tdie(\"dup failed: %s\", strerror(errno));\n+\t\tdie_errno(\"dup failed\");\n \treturn ret;\n }\n \n@@ -183,7 +183,7 @@ int xdup(int fd)\n {\n \tFILE *stream = fdopen(fd, mode);\n \tif (stream == NULL)\n-\t\tdie(\"Out of memory? fdopen failed: %s\", strerror(errno));\n+\t\tdie_errno(\"Out of memory? fdopen failed\");\n \treturn stream;\n }\n \n@@ -193,7 +193,7 @@ int xmkstemp(char *template)\n \n \tfd = mkstemp(template);\n \tif (fd < 0)\n-\t\tdie(\"Unable to create temporary file: %s\", strerror(errno));\n+\t\tdie_errno(\"Unable to create temporary file\");\n \treturn fd;\n }\n \ndiff --git a/write_or_die.c b/write_or_die.c\nindex 4c29255..d45b536 100644\n--- a/write_or_die.c\n+++ b/write_or_die.c\n@@ -41,14 +41,14 @@ void maybe_flush_or_die(FILE *f, const char *desc)\n \t\t */\n \t\tif (errno == EPIPE || errno == EINVAL)\n \t\t\texit(0);\n-\t\tdie(\"write failure on %s: %s\", desc, strerror(errno));\n+\t\tdie_errno(\"write failure on '%s'\", desc);\n \t}\n }\n \n void fsync_or_die(int fd, const char *msg)\n {\n \tif (fsync(fd) < 0) {\n-\t\tdie(\"%s: fsync error (%s)\", msg, strerror(errno));\n+\t\tdie_errno(\"fsync error on '%s'\", msg);\n \t}\n }\n \n@@ -57,7 +57,7 @@ void write_or_die(int fd, const void *buf, size_t count)\n \tif (write_in_full(fd, buf, count) < 0) {\n \t\tif (errno == EPIPE)\n \t\t\texit(0);\n-\t\tdie(\"write error (%s)\", strerror(errno));\n+\t\tdie_errno(\"write error\");\n \t}\n }\n \n-- \n1.6.3.2.288.g40844\n"},{"id":"115654","messageId":"62538974f2c0f4561428507e514daa87dbfcac01.1244299302.git.trast@student.ethz.ch","threadId":"19644","inReplyTo":"095b4af080c11b4ad3fcfaefc9cdf49d383cb714.1244299302.git.trast@student.ethz.ch","subject":"[PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T14:44:53Z","receivedAt":"2009-06-06T14:44:53Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Lots of die() calls did not actually report the kind of error, which\ncan leave the user confused as to the real problem.  Use die_errno()\nwhere we check a system/library call that sets errno on failure, or\none of the following that wrap such calls:\n\n  Function              Passes on error from\n  --------              --------------------\n  odb_pack_keep         open\n  read_ancestry         fopen\n  read_in_full          xread\n  strbuf_read           xread\n  strbuf_read_file      open or strbuf_read_file\n  strbuf_readlink       readlink\n  write_in_full         xwrite\n\nSigned-off-by: Thomas Rast <trast@student.ethz.ch>\n---\n abspath.c               |   12 ++++++------\n builtin-add.c           |    2 +-\n builtin-apply.c         |    6 +++---\n builtin-archive.c       |    4 ++--\n builtin-blame.c         |    9 ++++-----\n builtin-clone.c         |   11 +++++------\n builtin-commit-tree.c   |    1 -\n builtin-commit.c        |   13 +++++++------\n builtin-fast-export.c   |    3 +--\n builtin-fmt-merge-msg.c |    2 +-\n builtin-fsck.c          |    2 +-\n builtin-init-db.c       |   22 +++++++++++-----------\n builtin-log.c           |    4 ++--\n builtin-mailsplit.c     |    7 +++----\n builtin-merge.c         |   25 +++++++++++++++----------\n builtin-rev-parse.c     |    2 +-\n builtin-revert.c        |    2 +-\n builtin-stripspace.c    |    2 +-\n builtin-tag.c           |    2 +-\n builtin-tar-tree.c      |    2 +-\n combine-diff.c          |    2 +-\n csum-file.c             |    3 +--\n diff.c                  |    6 +++---\n entry.c                 |    2 +-\n fast-import.c           |    4 ++--\n hash-object.c           |    2 +-\n ll-merge.c              |    2 +-\n mktag.c                 |    2 +-\n read-cache.c            |    2 +-\n setup.c                 |   10 +++++-----\n transport.c             |    4 ++--\n unpack-file.c           |    2 +-\n 32 files changed, 87 insertions(+), 87 deletions(-)\n\ndiff --git a/abspath.c b/abspath.c\nindex 649f34f..4bee0ba 100644\n--- a/abspath.c\n+++ b/abspath.c\n@@ -41,13 +41,13 @@ int is_directory(const char *path)\n \n \t\tif (*buf) {\n \t\t\tif (!*cwd && !getcwd(cwd, sizeof(cwd)))\n-\t\t\t\tdie (\"Could not get current working directory\");\n+\t\t\t\tdie_errno (\"Could not get current working directory\");\n \n \t\t\tif (chdir(buf))\n-\t\t\t\tdie (\"Could not switch to '%s'\", buf);\n+\t\t\t\tdie_errno (\"Could not switch to '%s'\", buf);\n \t\t}\n \t\tif (!getcwd(buf, PATH_MAX))\n-\t\t\tdie (\"Could not get current working directory\");\n+\t\t\tdie_errno (\"Could not get current working directory\");\n \n \t\tif (last_elem) {\n \t\t\tint len = strlen(buf);\n@@ -63,7 +63,7 @@ int is_directory(const char *path)\n \t\tif (!lstat(buf, &st) && S_ISLNK(st.st_mode)) {\n \t\t\tlen = readlink(buf, next_buf, PATH_MAX);\n \t\t\tif (len < 0)\n-\t\t\t\tdie (\"Invalid symlink: %s\", buf);\n+\t\t\t\tdie_errno (\"Invalid symlink '%s'\", buf);\n \t\t\tif (PATH_MAX <= len)\n \t\t\t\tdie(\"symbolic link too long: %s\", buf);\n \t\t\tnext_buf[len] = '\\0';\n@@ -75,7 +75,7 @@ int is_directory(const char *path)\n \t}\n \n \tif (*cwd && chdir(cwd))\n-\t\tdie (\"Could not change back to '%s'\", cwd);\n+\t\tdie_errno (\"Could not change back to '%s'\", cwd);\n \n \treturn buf;\n }\n@@ -109,7 +109,7 @@ int is_directory(const char *path)\n \t} else {\n \t\tconst char *cwd = get_pwd_cwd();\n \t\tif (!cwd)\n-\t\t\tdie(\"Cannot determine the current working directory\");\n+\t\t\tdie_errno(\"Cannot determine the current working directory\");\n \t\tif (snprintf(buf, PATH_MAX, \"%s/%s\", cwd, path) >= PATH_MAX)\n \t\t\tdie(\"Too long path: %.*s\", 60, path);\n \t}\ndiff --git a/builtin-add.c b/builtin-add.c\nindex c1b229a..8f651c1 100644\n--- a/builtin-add.c\n+++ b/builtin-add.c\n@@ -220,7 +220,7 @@ int edit_patch(int argc, const char **argv, const char *prefix)\n \tlaunch_editor(file, NULL, NULL);\n \n \tif (stat(file, &st))\n-\t\tdie(\"Could not stat '%s'\", file);\n+\t\tdie_errno(\"Could not stat '%s'\", file);\n \tif (!st.st_size)\n \t\tdie(\"Empty patch. Aborted.\");\n \ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 6526c08..dbc7f21 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2823,8 +2823,8 @@ static void add_index_file(const char *path, unsigned mode, void *buf, unsigned \n \t} else {\n \t\tif (!cached) {\n \t\t\tif (lstat(path, &st) < 0)\n-\t\t\t\tdie(\"unable to stat newly created file %s\",\n-\t\t\t\t    path);\n+\t\t\t\tdie_errno(\"unable to stat newly created file '%s'\",\n+\t\t\t\t\t  path);\n \t\t\tfill_stat_cache_info(ce, &st);\n \t\t}\n \t\tif (write_sha1_file(buf, size, blob_type, ce->sha1) < 0)\n@@ -2913,7 +2913,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned\n \t\t\t++nr;\n \t\t}\n \t}\n-\tdie(\"unable to write file %s mode %o\", path, mode);\n+\tdie_errno(\"unable to write file '%s' mode %o\", path, mode);\n }\n \n static void create_file(struct patch *patch)\ndiff --git a/builtin-archive.c b/builtin-archive.c\nindex 3c5a5a7..f9a4bea 100644\n--- a/builtin-archive.c\n+++ b/builtin-archive.c\n@@ -13,10 +13,10 @@ static void create_output_file(const char *output_file)\n {\n \tint output_fd = open(output_file, O_CREAT | O_WRONLY | O_TRUNC, 0666);\n \tif (output_fd < 0)\n-\t\tdie(\"could not create archive file: %s \", output_file);\n+\t\tdie_errno(\"could not create archive file '%s'\", output_file);\n \tif (output_fd != 1) {\n \t\tif (dup2(output_fd, 1) < 0)\n-\t\t\tdie(\"could not redirect output\");\n+\t\t\tdie_errno(\"could not redirect output\");\n \t\telse\n \t\t\tclose(output_fd);\n \t}\ndiff --git a/builtin-blame.c b/builtin-blame.c\nindex 7d8fbd5..7c23d49 100644\n--- a/builtin-blame.c\n+++ b/builtin-blame.c\n@@ -2008,23 +2008,23 @@ static int git_blame_config(const char *var, const char *value, void *cb)\n \n \t\tif (contents_from) {\n \t\t\tif (stat(contents_from, &st) < 0)\n-\t\t\t\tdie(\"Cannot stat %s\", contents_from);\n+\t\t\t\tdie_errno(\"Cannot stat '%s'\", contents_from);\n \t\t\tread_from = contents_from;\n \t\t}\n \t\telse {\n \t\t\tif (lstat(path, &st) < 0)\n-\t\t\t\tdie(\"Cannot lstat %s\", path);\n+\t\t\t\tdie_errno(\"Cannot lstat '%s'\", path);\n \t\t\tread_from = path;\n \t\t}\n \t\tmode = canon_mode(st.st_mode);\n \t\tswitch (st.st_mode & S_IFMT) {\n \t\tcase S_IFREG:\n \t\t\tif (strbuf_read_file(&buf, read_from, st.st_size) != st.st_size)\n-\t\t\t\tdie(\"cannot open or read %s\", read_from);\n+\t\t\t\tdie_errno(\"cannot open or read '%s'\", read_from);\n \t\t\tbreak;\n \t\tcase S_IFLNK:\n \t\t\tif (strbuf_readlink(&buf, read_from, st.st_size) < 0)\n-\t\t\t\tdie(\"cannot readlink %s\", read_from);\n+\t\t\t\tdie_errno(\"cannot readlink '%s'\", read_from);\n \t\t\tbreak;\n \t\tdefault:\n \t\t\tdie(\"unsupported file type %s\", read_from);\n@@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char *prefix)\n \n \tif (revs_file && read_ancestry(revs_file))\n \t\tdie_errno(\"reading graft file '%s' failed\", revs_file);\n-\n \tif (cmd_is_annotate) {\n \t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n \t\tblame_date_mode = DATE_ISO8601;\ndiff --git a/builtin-clone.c b/builtin-clone.c\nindex 5f34414..03b691b 100644\n--- a/builtin-clone.c\n+++ b/builtin-clone.c\n@@ -220,13 +220,12 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)\n \n \tdir = opendir(src->buf);\n \tif (!dir)\n-\t\tdie(\"failed to open %s\", src->buf);\n-\n+\t\tdie_errno(\"failed to open '%s'\", src->buf);\n \tif (mkdir(dest->buf, 0777)) {\n \t\tif (errno != EEXIST)\n-\t\t\tdie(\"failed to create directory %s\", dest->buf);\n+\t\t\tdie_errno(\"failed to create directory '%s'\", dest->buf);\n \t\telse if (stat(dest->buf, &buf))\n-\t\t\tdie(\"failed to stat %s\", dest->buf);\n+\t\t\tdie_errno(\"failed to stat '%s'\", dest->buf);\n \t\telse if (!S_ISDIR(buf.st_mode))\n \t\t\tdie(\"%s exists and is not a directory\", dest->buf);\n \t}\n@@ -257,11 +256,11 @@ static void copy_or_link_directory(struct strbuf *src, struct strbuf *dest)\n \t\t\tif (!link(src->buf, dest->buf))\n \t\t\t\tcontinue;\n \t\t\tif (option_local)\n-\t\t\t\tdie(\"failed to create link %s\", dest->buf);\n+\t\t\t\tdie_errno(\"failed to create link '%s'\", dest->buf);\n \t\t\toption_no_hardlinks = 1;\n \t\t}\n \t\tif (copy_file(dest->buf, src->buf, 0666))\n-\t\t\tdie(\"failed to copy file to %s\", dest->buf);\n+\t\t\tdie_errno(\"failed to copy file to '%s'\", dest->buf);\n \t}\n \tclosedir(dir);\n }\ndiff --git a/builtin-commit-tree.c b/builtin-commit-tree.c\nindex 6467077..3ce8e82 100644\n--- a/builtin-commit-tree.c\n+++ b/builtin-commit-tree.c\n@@ -125,7 +125,6 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)\n \n \tif (strbuf_read(&buffer, 0, 0) < 0)\n \t\tdie_errno(\"git commit-tree: failed to read\");\n-\n \tif (!commit_tree(buffer.buf, tree_sha1, parents, commit_sha1, NULL)) {\n \t\tprintf(\"%s\\n\", sha1_to_hex(commit_sha1));\n \t\treturn 0;\ndiff --git a/builtin-commit.c b/builtin-commit.c\nindex cce25b5..77298e9 100644\n--- a/builtin-commit.c\n+++ b/builtin-commit.c\n@@ -434,7 +434,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \t\tif (isatty(0))\n \t\t\tfprintf(stderr, \"(reading log message from standard input)\\n\");\n \t\tif (strbuf_read(&sb, 0, 0) < 0)\n-\t\t\tdie(\"could not read log from standard input\");\n+\t\t\tdie_errno(\"could not read log from standard input\");\n \t\thook_arg1 = \"message\";\n \t} else if (logfile) {\n \t\tif (strbuf_read_file(&sb, logfile, 0) < 0)\n@@ -472,7 +472,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \tfp = fopen(git_path(commit_editmsg), \"w\");\n \tif (fp == NULL)\n \t\tdie_errno(\"could not open '%s'\", git_path(commit_editmsg));\n-\n \tif (cleanup_mode != CLEANUP_NONE)\n \t\tstripspace(&sb, 0);\n \n@@ -496,7 +495,6 @@ static int prepare_to_commit(const char *index_file, const char *prefix)\n \n \tif (fwrite(sb.buf, 1, sb.len, fp) < sb.len)\n \t\tdie_errno(\"could not write commit template\");\n-\n \tstrbuf_release(&sb);\n \n \tdetermine_author_info();\n@@ -964,8 +962,9 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \t/* Finally, get the commit message */\n \tstrbuf_reset(&sb);\n \tif (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) {\n+\t\tint saved_errno = errno;\n \t\trollback_index_files();\n-\t\tdie(\"could not read commit message\");\n+\t\tdie(\"could not read commit message: %s\", strerror(saved_errno));\n \t}\n \n \t/* Truncate the message just before the diff, if any. */\n@@ -1018,8 +1017,10 @@ int cmd_commit(int argc, const char **argv, const char *prefix)\n \n \tif (commit_index_files())\n \t\tdie (\"Repository has been updated, but unable to write\\n\"\n-\t\t     \"new_index file. Check that disk is not full or quota is\\n\"\n-\t\t     \"not exceeded, and then \\\"git reset HEAD\\\" to recover.\");\n+\t\t     \"new_index file: %s.\\n\"\n+\t\t     \"Check that disk is not full or quota is not exceeded,\\n\"\n+\t\t     \"and then \\\"git reset HEAD\\\" to recover.\",\n+\t\t     strerror(errno));\n \n \trerere();\n \trun_hook(get_index_file(), \"post-commit\", NULL);\ndiff --git a/builtin-fast-export.c b/builtin-fast-export.c\nindex 333d438..3199d8a 100644\n--- a/builtin-fast-export.c\n+++ b/builtin-fast-export.c\n@@ -119,7 +119,7 @@ static void handle_object(const unsigned char *sha1)\n \n \tprintf(\"blob\\nmark :%\"PRIu32\"\\ndata %lu\\n\", last_idnum, size);\n \tif (size && fwrite(buf, size, 1, stdout) != 1)\n-\t\tdie (\"Could not write blob %s\", sha1_to_hex(sha1));\n+\t\tdie_errno (\"Could not write blob '%s'\", sha1_to_hex(sha1));\n \tprintf(\"\\n\");\n \n \tshow_progress();\n@@ -452,7 +452,6 @@ static void import_marks(char *input_file)\n \tFILE *f = fopen(input_file, \"r\");\n \tif (!f)\n \t\tdie_errno(\"cannot read '%s'\", input_file);\n-\n \twhile (fgets(line, sizeof(line), f)) {\n \t\tuint32_t mark;\n \t\tchar *line_end, *mark_end;\ndiff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c\nindex 1248d5e..9d52400 100644\n--- a/builtin-fmt-merge-msg.c\n+++ b/builtin-fmt-merge-msg.c\n@@ -368,7 +368,7 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \tif (inpath && strcmp(inpath, \"-\")) {\n \t\tin = fopen(inpath, \"r\");\n \t\tif (!in)\n-\t\t\tdie(\"cannot open %s\", inpath);\n+\t\t\tdie_errno(\"cannot open '%s'\", inpath);\n \t}\n \n \tif (strbuf_read(&input, fileno(in), 0) < 0)\ndiff --git a/builtin-fsck.c b/builtin-fsck.c\nindex a49dbe1..d0f48cd 100644\n--- a/builtin-fsck.c\n+++ b/builtin-fsck.c\n@@ -217,7 +217,7 @@ static void check_unreachable_object(struct object *obj)\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (!(f = fopen(filename, \"w\")))\n-\t\t\t\tdie(\"Could not open %s\", filename);\n+\t\t\t\tdie_errno(\"Could not open '%s'\", filename);\n \t\t\tif (obj->type == OBJ_BLOB) {\n \t\t\t\tenum object_type type;\n \t\t\t\tunsigned long size;\ndiff --git a/builtin-init-db.c b/builtin-init-db.c\nindex d1fa12a..50418cd 100644\n--- a/builtin-init-db.c\n+++ b/builtin-init-db.c\n@@ -61,20 +61,19 @@ static void copy_templates_1(char *path, int baselen,\n \t\tmemcpy(template + template_baselen, de->d_name, namelen+1);\n \t\tif (lstat(path, &st_git)) {\n \t\t\tif (errno != ENOENT)\n-\t\t\t\tdie(\"cannot stat %s\", path);\n+\t\t\t\tdie_errno(\"cannot stat '%s'\", path);\n \t\t}\n \t\telse\n \t\t\texists = 1;\n \n \t\tif (lstat(template, &st_template))\n-\t\t\tdie(\"cannot stat template %s\", template);\n-\n+\t\t\tdie_errno(\"cannot stat template '%s'\", template);\n \t\tif (S_ISDIR(st_template.st_mode)) {\n \t\t\tDIR *subdir = opendir(template);\n \t\t\tint baselen_sub = baselen + namelen;\n \t\t\tint template_baselen_sub = template_baselen + namelen;\n \t\t\tif (!subdir)\n-\t\t\t\tdie(\"cannot opendir %s\", template);\n+\t\t\t\tdie_errno(\"cannot opendir '%s'\", template);\n \t\t\tpath[baselen_sub++] =\n \t\t\t\ttemplate[template_baselen_sub++] = '/';\n \t\t\tpath[baselen_sub] =\n@@ -91,16 +90,17 @@ static void copy_templates_1(char *path, int baselen,\n \t\t\tint len;\n \t\t\tlen = readlink(template, lnk, sizeof(lnk));\n \t\t\tif (len < 0)\n-\t\t\t\tdie(\"cannot readlink %s\", template);\n+\t\t\t\tdie_errno(\"cannot readlink '%s'\", template);\n \t\t\tif (sizeof(lnk) <= len)\n \t\t\t\tdie(\"insanely long symlink %s\", template);\n \t\t\tlnk[len] = 0;\n \t\t\tif (symlink(lnk, path))\n-\t\t\t\tdie(\"cannot symlink %s %s\", lnk, path);\n+\t\t\t\tdie_errno(\"cannot symlink '%s' '%s'\", lnk, path);\n \t\t}\n \t\telse if (S_ISREG(st_template.st_mode)) {\n \t\t\tif (copy_file(path, template, st_template.st_mode))\n-\t\t\t\tdie(\"cannot copy %s to %s\", template, path);\n+\t\t\t\tdie_errno(\"cannot copy '%s' to '%s'\", template,\n+\t\t\t\t\t  path);\n \t\t}\n \t\telse\n \t\t\terror(\"ignoring template %s\", template);\n@@ -350,7 +350,7 @@ static int guess_repository_type(const char *git_dir)\n \tif (!strcmp(\".\", git_dir))\n \t\treturn 1;\n \tif (!getcwd(cwd, sizeof(cwd)))\n-\t\tdie(\"cannot tell cwd\");\n+\t\tdie_errno(\"cannot tell cwd\");\n \tif (!strcmp(git_dir, cwd))\n \t\treturn 1;\n \t/*\n@@ -440,11 +440,11 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)\n \t\tif (!git_work_tree_cfg) {\n \t\t\tgit_work_tree_cfg = xcalloc(PATH_MAX, 1);\n \t\t\tif (!getcwd(git_work_tree_cfg, PATH_MAX))\n-\t\t\t\tdie (\"Cannot access current working directory.\");\n+\t\t\t\tdie_errno (\"Cannot access current working directory\");\n \t\t}\n \t\tif (access(get_git_work_tree(), X_OK))\n-\t\t\tdie (\"Cannot access work tree '%s'\",\n-\t\t\t     get_git_work_tree());\n+\t\t\tdie_errno (\"Cannot access work tree '%s'\",\n+\t\t\t\t   get_git_work_tree());\n \t}\n \n \tset_git_dir(make_absolute_path(git_dir));\ndiff --git a/builtin-log.c b/builtin-log.c\nindex 0d34050..750957c 100644\n--- a/builtin-log.c\n+++ b/builtin-log.c\n@@ -1013,8 +1013,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)\n \t\tif (use_stdout)\n \t\t\tdie(\"standard output, or directory, which one?\");\n \t\tif (mkdir(output_directory, 0777) < 0 && errno != EEXIST)\n-\t\t\tdie(\"Could not create directory %s\",\n-\t\t\t    output_directory);\n+\t\t\tdie_errno(\"Could not create directory '%s'\",\n+\t\t\t\t  output_directory);\n \t}\n \n \tif (rev.pending.nr == 1) {\ndiff --git a/builtin-mailsplit.c b/builtin-mailsplit.c\nindex 71f3b3b..f549234 100644\n--- a/builtin-mailsplit.c\n+++ b/builtin-mailsplit.c\n@@ -81,7 +81,7 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)\n \n \tfd = open(name, O_WRONLY | O_CREAT | O_EXCL, 0666);\n \tif (fd < 0)\n-\t\tdie(\"cannot open output file %s\", name);\n+\t\tdie_errno(\"cannot open output file '%s'\", name);\n \toutput = fdopen(fd, \"w\");\n \n \t/* Copy it out, while searching for a line that begins with\n@@ -91,15 +91,14 @@ static int split_one(FILE *mbox, const char *name, int allow_bare)\n \t\tint is_partial = len && buf[len-1] != '\\n';\n \n \t\tif (fwrite(buf, 1, len, output) != len)\n-\t\t\tdie(\"cannot write output\");\n-\n+\t\t\tdie_errno(\"cannot write output\");\n \t\tlen = read_line_with_nul(buf, sizeof(buf), mbox);\n \t\tif (len == 0) {\n \t\t\tif (feof(mbox)) {\n \t\t\t\tstatus = 1;\n \t\t\t\tbreak;\n \t\t\t}\n-\t\t\tdie(\"cannot read mbox\");\n+\t\t\tdie_errno(\"cannot read mbox\");\n \t\t}\n \t\tif (!is_partial && !is_bare && is_from_line(buf, len))\n \t\t\tbreak; /* done with one message */\ndiff --git a/builtin-merge.c b/builtin-merge.c\nindex a7e03ce..35f4520 100644\n--- a/builtin-merge.c\n+++ b/builtin-merge.c\n@@ -268,8 +268,7 @@ static void squash_message(void)\n \tprintf(\"Squash commit -- not updating HEAD\\n\");\n \tfd = open(git_path(\"SQUASH_MSG\"), O_WRONLY | O_CREAT, 0666);\n \tif (fd < 0)\n-\t\tdie(\"Could not write to %s\", git_path(\"SQUASH_MSG\"));\n-\n+\t\tdie_errno(\"Could not write to '%s'\", git_path(\"SQUASH_MSG\"));\n \tinit_revisions(&rev, NULL);\n \trev.ignore_merges = 1;\n \trev.commit_format = CMIT_FMT_MEDIUM;\n@@ -764,7 +763,8 @@ static int suggest_conflicts(void)\n \n \tfp = fopen(git_path(\"MERGE_MSG\"), \"a\");\n \tif (!fp)\n-\t\tdie(\"Could not open %s for writing\", git_path(\"MERGE_MSG\"));\n+\t\tdie_errno(\"Could not open '%s' for writing\",\n+\t\t\t  git_path(\"MERGE_MSG\"));\n \tfprintf(fp, \"\\nConflicts:\\n\");\n \tfor (pos = 0; pos < active_nr; pos++) {\n \t\tstruct cache_entry *ce = active_cache[pos];\n@@ -1186,27 +1186,32 @@ int cmd_merge(int argc, const char **argv, const char *prefix)\n \t\t\t\tsha1_to_hex(j->item->object.sha1));\n \t\tfd = open(git_path(\"MERGE_HEAD\"), O_WRONLY | O_CREAT, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\",\n-\t\t\t\tgit_path(\"MERGE_HEAD\"));\n+\t\t\tdie_errno(\"Could not open '%s' for writing\",\n+\t\t\t\t  git_path(\"MERGE_HEAD\"));\n \t\tif (write_in_full(fd, buf.buf, buf.len) != buf.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_HEAD\"));\n+\t\t\tdie_errno(\"Could not write to '%s'\",\n+\t\t\t\t  git_path(\"MERGE_HEAD\"));\n \t\tclose(fd);\n \t\tstrbuf_addch(&merge_msg, '\\n');\n \t\tfd = open(git_path(\"MERGE_MSG\"), O_WRONLY | O_CREAT, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\", git_path(\"MERGE_MSG\"));\n+\t\t\tdie_errno(\"Could not open '%s' for writing\",\n+\t\t\t\t  git_path(\"MERGE_MSG\"));\n \t\tif (write_in_full(fd, merge_msg.buf, merge_msg.len) !=\n \t\t\tmerge_msg.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_MSG\"));\n+\t\t\tdie_errno(\"Could not write to '%s'\",\n+\t\t\t\t  git_path(\"MERGE_MSG\"));\n \t\tclose(fd);\n \t\tfd = open(git_path(\"MERGE_MODE\"), O_WRONLY | O_CREAT | O_TRUNC, 0666);\n \t\tif (fd < 0)\n-\t\t\tdie(\"Could open %s for writing\", git_path(\"MERGE_MODE\"));\n+\t\t\tdie_errno(\"Could not open '%s' for writing\",\n+\t\t\t\t  git_path(\"MERGE_MODE\"));\n \t\tstrbuf_reset(&buf);\n \t\tif (!allow_fast_forward)\n \t\t\tstrbuf_addf(&buf, \"no-ff\");\n \t\tif (write_in_full(fd, buf.buf, buf.len) != buf.len)\n-\t\t\tdie(\"Could not write to %s\", git_path(\"MERGE_MODE\"));\n+\t\t\tdie_errno(\"Could not write to '%s'\",\n+\t\t\t    git_path(\"MERGE_MODE\"));\n \t\tclose(fd);\n \t}\n \ndiff --git a/builtin-rev-parse.c b/builtin-rev-parse.c\nindex 112d622..da26dbc 100644\n--- a/builtin-rev-parse.c\n+++ b/builtin-rev-parse.c\n@@ -592,7 +592,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)\n \t\t\t\t\tcontinue;\n \t\t\t\t}\n \t\t\t\tif (!getcwd(cwd, PATH_MAX))\n-\t\t\t\t\tdie(\"unable to get current working directory\");\n+\t\t\t\t\tdie_errno(\"unable to get current working directory\");\n \t\t\t\tprintf(\"%s/.git\\n\", cwd);\n \t\t\t\tcontinue;\n \t\t\t}\ndiff --git a/builtin-revert.c b/builtin-revert.c\nindex c87115a..151aa6a 100644\n--- a/builtin-revert.c\n+++ b/builtin-revert.c\n@@ -135,7 +135,7 @@ static void add_to_msg(const char *string)\n {\n \tint len = strlen(string);\n \tif (write_in_full(msg_fd, string, len) < 0)\n-\t\tdie (\"Could not write to MERGE_MSG\");\n+\t\tdie_errno (\"Could not write to MERGE_MSG\");\n }\n \n static void add_message_to_msg(const char *message)\ndiff --git a/builtin-stripspace.c b/builtin-stripspace.c\nindex d6e3896..1fd2205 100644\n--- a/builtin-stripspace.c\n+++ b/builtin-stripspace.c\n@@ -78,7 +78,7 @@ int cmd_stripspace(int argc, const char **argv, const char *prefix)\n \t\tstrip_comments = 1;\n \n \tif (strbuf_read(&buf, 0, 1024) < 0)\n-\t\tdie(\"could not read the input\");\n+\t\tdie_errno(\"could not read the input\");\n \n \tstripspace(&buf, strip_comments);\n \ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex 7b51095..165bec3 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -442,7 +442,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\telse {\n \t\t\tif (!strcmp(msgfile, \"-\")) {\n \t\t\t\tif (strbuf_read(&buf, 0, 1024) < 0)\n-\t\t\t\t\tdie(\"cannot read %s\", msgfile);\n+\t\t\t\t\tdie_errno(\"cannot read '%s'\", msgfile);\n \t\t\t} else {\n \t\t\t\tif (strbuf_read_file(&buf, msgfile, 1024) < 0)\n \t\t\t\t\tdie_errno(\"could not open or read '%s'\",\ndiff --git a/builtin-tar-tree.c b/builtin-tar-tree.c\nindex f88e721..8b3a35e 100644\n--- a/builtin-tar-tree.c\n+++ b/builtin-tar-tree.c\n@@ -91,7 +91,7 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)\n \n \tn = write_in_full(1, content + 11, 41);\n \tif (n < 41)\n-\t\tdie(\"git get-tar-commit-id: write error\");\n+\t\tdie_errno(\"git get-tar-commit-id: write error\");\n \n \treturn 0;\n }\ndiff --git a/combine-diff.c b/combine-diff.c\nindex 60d0367..bbf74fc 100644\n--- a/combine-diff.c\n+++ b/combine-diff.c\n@@ -746,7 +746,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,\n \n \t\t\tdone = read_in_full(fd, result, len);\n \t\t\tif (done < 0)\n-\t\t\t\tdie(\"read error '%s'\", elem->path);\n+\t\t\t\tdie_errno(\"read error '%s'\", elem->path);\n \t\t\telse if (done < len)\n \t\t\t\tdie(\"early EOF '%s'\", elem->path);\n \ndiff --git a/csum-file.c b/csum-file.c\nindex 9cc93ba..4d50cc5 100644\n--- a/csum-file.c\n+++ b/csum-file.c\n@@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result, unsigned int flags)\n \t\tif (flags & CSUM_FSYNC)\n \t\t\tfsync_or_die(f->fd, f->name);\n \t\tif (close(f->fd))\n-\t\t\tdie_errno(\"%s: sha1 file error on close\",\n-\t\t\t    f->name);\n+\t\t\tdie_errno(\"%s: sha1 file error on close\", f->name);\n \t\tfd = 0;\n \t} else\n \t\tfd = f->fd;\ndiff --git a/diff.c b/diff.c\nindex 48043f5..aec613f 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -1982,7 +1982,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \t\tsize = buf.len;\n \t}\n \tif (write_in_full(fd, blob, size) != size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie_errno(\"unable to write temp-file\");\n \tclose(fd);\n \ttemp->name = temp->tmp_path;\n \tstrcpy(temp->hex, sha1_to_hex(sha1));\n@@ -2026,7 +2026,7 @@ static void prep_temp_blob(const char *path, struct diff_tempfile *temp,\n \t\tif (S_ISLNK(st.st_mode)) {\n \t\t\tstruct strbuf sb = STRBUF_INIT;\n \t\t\tif (strbuf_readlink(&sb, name, st.st_size) < 0)\n-\t\t\t\tdie(\"readlink(%s)\", name);\n+\t\t\t\tdie_errno(\"readlink(%s)\", name);\n \t\t\tprep_temp_blob(name, temp, sb.buf, sb.len,\n \t\t\t\t       (one->sha1_valid ?\n \t\t\t\t\tone->sha1 : null_sha1),\n@@ -2219,7 +2219,7 @@ static void diff_fill_sha1_info(struct diff_filespec *one)\n \t\t\t\treturn;\n \t\t\t}\n \t\t\tif (lstat(one->path, &st) < 0)\n-\t\t\t\tdie(\"stat %s\", one->path);\n+\t\t\t\tdie_errno(\"stat '%s'\", one->path);\n \t\t\tif (index_path(one->sha1, one->path, &st, 0))\n \t\t\t\tdie(\"cannot hash %s\", one->path);\n \t\t}\ndiff --git a/entry.c b/entry.c\nindex 099eaf4..e9e396b 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -37,7 +37,7 @@ static void create_directories(const char *path, int path_len,\n \t\t\tif (errno == EEXIST && state->force &&\n \t\t\t    !unlink_or_warn(buf) && !mkdir(buf, 0777))\n \t\t\t\tcontinue;\n-\t\t\tdie(\"cannot create directory at %s\", buf);\n+\t\t\tdie_errno(\"cannot create directory at '%s'\", buf);\n \t\t}\n \t}\n \tfree(buf);\ndiff --git a/fast-import.c b/fast-import.c\nindex d31a4e8..7ef9865 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -905,10 +905,10 @@ static int oecmp (const void *a_, const void *b_)\n \n \tkeep_fd = odb_pack_keep(name, sizeof(name), pack_data->sha1);\n \tif (keep_fd < 0)\n-\t\tdie(\"cannot create keep file\");\n+\t\tdie_errno(\"cannot create keep file\");\n \twrite_or_die(keep_fd, keep_msg, strlen(keep_msg));\n \tif (close(keep_fd))\n-\t\tdie(\"failed to write keep file\");\n+\t\tdie_errno(\"failed to write keep file\");\n \n \tsnprintf(name, sizeof(name), \"%s/pack/pack-%s.pack\",\n \t\t get_object_directory(), sha1_to_hex(pack_data->sha1));\ndiff --git a/hash-object.c b/hash-object.c\nindex 47cf43c..9455dd0 100644\n--- a/hash-object.c\n+++ b/hash-object.c\n@@ -29,7 +29,7 @@ static void hash_object(const char *path, const char *type, int write_object,\n \tint fd;\n \tfd = open(path, O_RDONLY);\n \tif (fd < 0)\n-\t\tdie(\"Cannot open %s\", path);\n+\t\tdie_errno(\"Cannot open '%s'\", path);\n \thash_fd(fd, type, write_object, vpath);\n }\n \ndiff --git a/ll-merge.c b/ll-merge.c\nindex 81c02ad..caf22be 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -152,7 +152,7 @@ static void create_temp(mmfile_t *src, char *path)\n \tstrcpy(path, \".merge_file_XXXXXX\");\n \tfd = xmkstemp(path);\n \tif (write_in_full(fd, src->ptr, src->size) != src->size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie_errno(\"unable to write temp-file\");\n \tclose(fd);\n }\n \ndiff --git a/mktag.c b/mktag.c\nindex 99a356e..a609e3e 100644\n--- a/mktag.c\n+++ b/mktag.c\n@@ -165,7 +165,7 @@ int main(int argc, char **argv)\n \tsetup_git_directory();\n \n \tif (strbuf_read(&buf, 0, 4096) < 0) {\n-\t\tdie(\"could not read from stdin\");\n+\t\tdie_errno(\"could not read from stdin\");\n \t}\n \n \t/* Verify it for some basic sanity: it needs to start with\ndiff --git a/read-cache.c b/read-cache.c\nindex f76b5bb..4e3e272 100644\n--- a/read-cache.c\n+++ b/read-cache.c\n@@ -1265,7 +1265,7 @@ int read_index_from(struct index_state *istate, const char *path)\n \tmmap = xmmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);\n \tclose(fd);\n \tif (mmap == MAP_FAILED)\n-\t\tdie(\"unable to map index file\");\n+\t\tdie_errno(\"unable to map index file\");\n \n \thdr = mmap;\n \tif (verify_hdr(hdr, mmap_size) < 0)\ndiff --git a/setup.c b/setup.c\nindex 4d27f28..e3781b6 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -327,7 +327,7 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\t\t\treturn NULL;\n \t\t\tset_git_dir(make_absolute_path(gitdirenv));\n \t\t\tif (chdir(work_tree_env) < 0)\n-\t\t\t\tdie (\"Could not chdir to %s\", work_tree_env);\n+\t\t\t\tdie_errno (\"Could not chdir to '%s'\", work_tree_env);\n \t\t\tstrcat(buffer, \"/\");\n \t\t\treturn retval;\n \t\t}\n@@ -339,7 +339,7 @@ static int check_repository_format_gently(int *nongit_ok)\n \t}\n \n \tif (!getcwd(cwd, sizeof(cwd)-1))\n-\t\tdie(\"Unable to read current working directory\");\n+\t\tdie_errno(\"Unable to read current working directory\");\n \n \tceil_offset = longest_ancestor_length(cwd, env_ceiling_dirs);\n \tif (ceil_offset < 0 && has_dos_drive_prefix(cwd))\n@@ -382,7 +382,7 @@ static int check_repository_format_gently(int *nongit_ok)\n \t\tif (offset <= ceil_offset) {\n \t\t\tif (nongit_ok) {\n \t\t\t\tif (chdir(cwd))\n-\t\t\t\t\tdie(\"Cannot come back to cwd\");\n+\t\t\t\t\tdie_errno(\"Cannot come back to cwd\");\n \t\t\t\t*nongit_ok = 1;\n \t\t\t\treturn NULL;\n \t\t\t}\n@@ -493,10 +493,10 @@ int check_repository_format(void)\n \t\tstatic char buffer[PATH_MAX + 1];\n \t\tchar *rel;\n \t\tif (retval && chdir(retval))\n-\t\t\tdie (\"Could not jump back into original cwd\");\n+\t\t\tdie_errno (\"Could not jump back into original cwd\");\n \t\trel = get_relative_cwd(buffer, PATH_MAX, get_git_work_tree());\n \t\tif (rel && *rel && chdir(get_git_work_tree()))\n-\t\t\tdie (\"Could not jump to working directory\");\n+\t\t\tdie_errno (\"Could not jump to working directory\");\n \t\treturn rel && *rel ? strcat(rel, \"/\") : NULL;\n \t}\n \ndiff --git a/transport.c b/transport.c\nindex 17891d5..8decd66 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -158,7 +158,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)\n \n \tstrbuf_addstr(&temp_dir, git_path(\"rsync-refs-XXXXXX\"));\n \tif (!mkdtemp(temp_dir.buf))\n-\t\tdie (\"Could not make temporary directory\");\n+\t\tdie_errno (\"Could not make temporary directory\");\n \ttemp_dir_len = temp_dir.len;\n \n \tstrbuf_addstr(&buf, rsync_url(transport->url));\n@@ -321,7 +321,7 @@ static int rsync_transport_push(struct transport *transport,\n \n \tstrbuf_addstr(&temp_dir, git_path(\"rsync-refs-XXXXXX\"));\n \tif (!mkdtemp(temp_dir.buf))\n-\t\tdie (\"Could not make temporary directory\");\n+\t\tdie_errno (\"Could not make temporary directory\");\n \tstrbuf_addch(&temp_dir, '/');\n \n \tif (flags & TRANSPORT_PUSH_ALL) {\ndiff --git a/unpack-file.c b/unpack-file.c\nindex 75cd2f1..ac9cbf7 100644\n--- a/unpack-file.c\n+++ b/unpack-file.c\n@@ -17,7 +17,7 @@\n \tstrcpy(path, \".merge_file_XXXXXX\");\n \tfd = xmkstemp(path);\n \tif (write_in_full(fd, buf, size) != size)\n-\t\tdie(\"unable to write temp-file\");\n+\t\tdie_errno(\"unable to write temp-file\");\n \tclose(fd);\n \treturn path;\n }\n-- \n1.6.3.2.288.g40844\n"},{"id":"115665","messageId":"200906062231.24184.j6t@kdbg.org","threadId":"19644","inReplyTo":"095b4af080c11b4ad3fcfaefc9cdf49d383cb714.1244299302.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 2/3] Convert existing die(..., strerror(errno)) to die_errno()","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-06-06T20:31:24Z","receivedAt":"2009-06-06T20:31:24Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> Change calls to die(..., strerror(errno)) to use the new die_errno().\n>\n> In the process, also make slight style adjustments: at least state\n> _something_ about the function that failed (instead of just printing\n> the pathname), and put paths in single quotes.\n\n> @@ -428,8 +428,8 @@ static void merge_name(const char *remote, struct\n> strbuf *msg)\n>\n>  \t\tfp = fopen(git_path(\"FETCH_HEAD\"), \"r\");\n>  \t\tif (!fp)\n> -\t\t\tdie(\"could not open %s for reading: %s\",\n> -\t\t\t\tgit_path(\"FETCH_HEAD\"), strerror(errno));\n> +\t\t\tdie_errno(\"could not open %s for reading\",\n> +\t\t\t\t  git_path(\"FETCH_HEAD\"));\n\nYou said you added quotes, but you didn't do that here and in quite a few more \nother cases.\n\nIMHO, the quotes are not an improvement anyway, but that's really only my \npersonal taste.\n\n> --- a/connect.c\n> +++ b/connect.c\n> @@ -256,7 +256,7 @@ static int git_tcp_connect_sock(char *host, int flags)\n>  \tfreeaddrinfo(ai0);\n>\n>  \tif (sockfd < 0)\n> -\t\tdie(\"unable to connect a socket (%s)\", strerror(saved_errno));\n> +\t\tdie_errno(\"unable to connect a socket\");\n\nYou cannot convert this: We want strerror(saved_errno), but die_errno would \nprint strerror(errno).\n\n> @@ -345,7 +345,7 @@ static int git_tcp_connect_sock(char *host, int flags)\n>  \t}\n>\n>  \tif (sockfd < 0)\n> -\t\tdie(\"unable to connect a socket (%s)\", strerror(saved_errno));\n> +\t\tdie_errno(\"unable to connect a socket\");\n\nSame here.\n\n-- Hannes\n"},{"id":"115666","messageId":"200906062236.42858.j6t@kdbg.org","threadId":"19644","inReplyTo":"3672f22723a4c14c4a6d67278e9865424c0c68dc.1244299302.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-06-06T20:36:42Z","receivedAt":"2009-06-06T20:36:42Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> +void die_errno(const char *err, ...)\n> +{\n> +\tva_list params;\n> +\tchar msg[1024];\n> +\n> +\tva_start(params, err);\n> +\n> +\tvsnprintf(msg, sizeof(msg), err, params);\n> +\tdie(\"%s: %s\", msg, strerror(errno));\n\nCannot vsnprintf potentially modify errno?\n\n> +\n> +\tva_end(params);\n\nThis va_end should better be before die().\n\n-- Hannes\n"},{"id":"115668","messageId":"200906062256.34074.trast@student.ethz.ch","threadId":"19644","inReplyTo":"200906062236.42858.j6t@kdbg.org","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T20:56:31Z","receivedAt":"2009-06-06T20:56:31Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Johannes Sixt wrote:\n> On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> > +void die_errno(const char *err, ...)\n> > +{\n> > +\tva_list params;\n> > +\tchar msg[1024];\n> > +\n> > +\tva_start(params, err);\n> > +\n> > +\tvsnprintf(msg, sizeof(msg), err, params);\n> > +\tdie(\"%s: %s\", msg, strerror(errno));\n> \n> Cannot vsnprintf potentially modify errno?\n\nManpage turns up nothing, so AFAICT, no.\n\n> > +\n> > +\tva_end(params);\n> \n> This va_end should better be before die().\n\nNot that I object to changing it, but out of curiosity, what do I\nbreak by putting it after?\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"115669","messageId":"200906062302.08616.j6t@kdbg.org","threadId":"19644","inReplyTo":"62538974f2c0f4561428507e514daa87dbfcac01.1244299302.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-06-06T21:02:08Z","receivedAt":"2009-06-06T21:02:08Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> Lots of die() calls did not actually report the kind of error, which\n> can leave the user confused as to the real problem.  Use die_errno()\n> where we check a system/library call that sets errno on failure, or\n> one of the following that wrap such calls:\n>\n>   Function              Passes on error from\n>   --------              --------------------\n>   odb_pack_keep         open\n>   read_ancestry         fopen\n>   read_in_full          xread\n>   strbuf_read           xread\n>   strbuf_read_file      open or strbuf_read_file\n>   strbuf_readlink       readlink\n>   write_in_full         xwrite\n>\n> Signed-off-by: Thomas Rast <trast@student.ethz.ch>\n> ---\n\n> @@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char\n> *prefix)\n>\n>  \tif (revs_file && read_ancestry(revs_file))\n>  \t\tdie_errno(\"reading graft file '%s' failed\", revs_file);\n> -\n>  \tif (cmd_is_annotate) {\n>  \t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n>  \t\tblame_date_mode = DATE_ISO8601;\n\nUnrelated and not an improvement.\n\n> @@ -220,13 +220,12 @@ static void copy_or_link_directory(struct strbuf\n> *src, struct strbuf *dest)\n>\n>  \tdir = opendir(src->buf);\n>  \tif (!dir)\n> -\t\tdie(\"failed to open %s\", src->buf);\n> -\n> +\t\tdie_errno(\"failed to open '%s'\", src->buf);\n\nHere (and in other cases) you remote an empty line. I don't think that is an \nimprovement.\n\n> @@ -472,7 +472,6 @@ static int prepare_to_commit(const char *index_file,\n> const char *prefix) fp = fopen(git_path(commit_editmsg), \"w\");\n>  \tif (fp == NULL)\n>  \t\tdie_errno(\"could not open '%s'\", git_path(commit_editmsg));\n> -\n>  \tif (cleanup_mode != CLEANUP_NONE)\n>  \t\tstripspace(&sb, 0);\n>\n\nUnrelated.\n\n> @@ -496,7 +495,6 @@ static int prepare_to_commit(const char *index_file,\n> const char *prefix)\n>\n>  \tif (fwrite(sb.buf, 1, sb.len, fp) < sb.len)\n>  \t\tdie_errno(\"could not write commit template\");\n> -\n>  \tstrbuf_release(&sb);\n>\n>  \tdetermine_author_info();\n\nDitto.\n\n> @@ -1018,8 +1017,10 @@ int cmd_commit(int argc, const char **argv, const\n> char *prefix)\n>\n>  \tif (commit_index_files())\n>  \t\tdie (\"Repository has been updated, but unable to write\\n\"\n> -\t\t     \"new_index file. Check that disk is not full or quota is\\n\"\n> -\t\t     \"not exceeded, and then \\\"git reset HEAD\\\" to recover.\");\n> +\t\t     \"new_index file: %s.\\n\"\n> +\t\t     \"Check that disk is not full or quota is not exceeded,\\n\"\n> +\t\t     \"and then \\\"git reset HEAD\\\" to recover.\",\n> +\t\t     strerror(errno));\n\nThis change should probably not be in this patch.\n\n> @@ -452,7 +452,6 @@ static void import_marks(char *input_file)\n>  \tFILE *f = fopen(input_file, \"r\");\n>  \tif (!f)\n>  \t\tdie_errno(\"cannot read '%s'\", input_file);\n> -\n>  \twhile (fgets(line, sizeof(line), f)) {\n>  \t\tuint32_t mark;\n>  \t\tchar *line_end, *mark_end;\n\nUnrelated.\n\n> diff --git a/csum-file.c b/csum-file.c\n> index 9cc93ba..4d50cc5 100644\n> --- a/csum-file.c\n> +++ b/csum-file.c\n> @@ -55,8 +55,7 @@ int sha1close(struct sha1file *f, unsigned char *result,\n> unsigned int flags) if (flags & CSUM_FSYNC)\n>  \t\t\tfsync_or_die(f->fd, f->name);\n>  \t\tif (close(f->fd))\n> -\t\t\tdie_errno(\"%s: sha1 file error on close\",\n> -\t\t\t    f->name);\n> +\t\t\tdie_errno(\"%s: sha1 file error on close\", f->name);\n\nThis should be in 2/3.\n\n-- Hannes\n"},{"id":"115671","messageId":"200906062317.22172.j6t@kdbg.org","threadId":"19644","inReplyTo":"200906062256.34074.trast@student.ethz.ch","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2009-06-06T21:17:22Z","receivedAt":"2009-06-06T21:17:22Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> Johannes Sixt wrote:\n> > On Samstag, 6. Juni 2009, Thomas Rast wrote:\n> > > +\n> > > +\tva_end(params);\n> >\n> > This va_end should better be before die().\n>\n> Not that I object to changing it, but out of curiosity, what do I\n> break by putting it after?\n\nI don't know, and I suspect that in practice nothing breaks. It's just a \nmatter of style: va_start acquires a \"resource\", and va_end releases it, and \nyou should do that as soon as possible after the \"resource\" is no longer \nneeded.\n\n-- Hannes\n"},{"id":"115674","messageId":"20090606220916.GA30064@coredump.intra.peff.net","threadId":"19644","inReplyTo":"7vtz2vnogt.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH] diesys calls die and also reports strerror(errno)","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-06T22:09:16Z","receivedAt":"2009-06-06T22:09:16Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Jun 05, 2009 at 12:12:34AM -0700, Junio C Hamano wrote:\n\n> > Am I the only one who thinks that 'die_errno' would be a better name for\n> > this function?\n> \n> You are not alone.  I did find diesys() unreadable, but simply did not\n> think of an obviously better alternative like you did.\n\nIt was meant to be \"die with system error code\". But given two votes\n(and an implicit one from Thomas in his code), I am fine with die_errno.\n\n-Peff\n"},{"id":"115675","messageId":"20090606221320.GB30064@coredump.intra.peff.net","threadId":"19644","inReplyTo":"3672f22723a4c14c4a6d67278e9865424c0c68dc.1244299302.git.trast@student.ethz.ch","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-06T22:13:20Z","receivedAt":"2009-06-06T22:13:20Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jun 06, 2009 at 04:44:51PM +0200, Thomas Rast wrote:\n\n> Code by Jeff King and Alexander Potashev, name by Johannes Sixt.\n> [...]\n> +void die_errno(const char *err, ...)\n> +{\n> +\tva_list params;\n> +\tchar msg[1024];\n> +\n> +\tva_start(params, err);\n> +\n> +\tvsnprintf(msg, sizeof(msg), err, params);\n> +\tdie(\"%s: %s\", msg, strerror(errno));\n> +\n> +\tva_end(params);\n> +}\n> +\n\nNo, this approach is much more elegant than what I posted, so no need to\ncredit me, at least. ;)\n\nI do agree with Johannes, though. Style-wise, it reads much better as:\n\n  va_start(params, err);\n  vsnprintf(msg, sizeof(msg), err, params);\n  va_end(params);\n\n  die(\"%s: %s\", msg, strerror(errno));\n\nsince you can more easily see that params isn't leaked (and that die,\nwhich doesn't return, is the _last_ thing called).\n\n-Peff\n"},{"id":"115676","messageId":"200906070027.44136.trast@student.ethz.ch","threadId":"19644","inReplyTo":"200906062302.08616.j6t@kdbg.org","subject":"Re: [PATCH v2 3/3] Use die_errno() instead of die() when checking syscalls","fromName":"Thomas Rast","fromEmail":"trast@student.ethz.ch","sentAt":"2009-06-06T22:27:41Z","receivedAt":"2009-06-06T22:27:41Z","isPatch":true,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Johannes Sixt wrote:\n> > @@ -2262,7 +2262,6 @@ int cmd_blame(int argc, const char **argv, const char\n> > *prefix)\n> >\n> >  \tif (revs_file && read_ancestry(revs_file))\n> >  \t\tdie_errno(\"reading graft file '%s' failed\", revs_file);\n> > -\n> >  \tif (cmd_is_annotate) {\n> >  \t\toutput_option |= OUTPUT_ANNOTATE_COMPAT;\n> >  \t\tblame_date_mode = DATE_ISO8601;\n> \n> Unrelated and not an improvement.\n\nI used an Emacs macro to turn the die(..., strerror(errno)) [that I\nhad from v1] into die_errno, and obviously something went terribly\nwrong _and_ I missed it.  Sorry :-(\n\nI'll make a new version tomorrow.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"115677","messageId":"20090606224711.GC30064@coredump.intra.peff.net","threadId":"19644","inReplyTo":"200906062256.34074.trast@student.ethz.ch","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-06T22:47:11Z","receivedAt":"2009-06-06T22:47:11Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Jun 06, 2009 at 10:56:31PM +0200, Thomas Rast wrote:\n\n> > Cannot vsnprintf potentially modify errno?\n> \n> Manpage turns up nothing, so AFAICT, no.\n\nPOSIX seems to imply that it can:\n\n  http://www.opengroup.org/onlinepubs/009695399/functions/fprintf.html\n\nthough it looks like the conditions are fairly unlikely.\n\n-Peff\n"},{"id":"115695","messageId":"2325a7950906070412k3a440558h35db7511cc390e4b@mail.gmail.com","threadId":"19644","inReplyTo":"20090606221320.GB30064@coredump.intra.peff.net","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Alexander Potashev","fromEmail":"aspotashev@gmail.com","sentAt":"2009-06-07T11:12:39Z","receivedAt":"2009-06-07T11:12:39Z","isPatch":true,"sender":{"key":"aspotashev@gmail.com","avatar":null},"body":"2009/6/7 Jeff King <peff@peff.net>:\n> On Sat, Jun 06, 2009 at 04:44:51PM +0200, Thomas Rast wrote:\n>\n>> Code by Jeff King and Alexander Potashev, name by Johannes Sixt.\n>> [...]\n>> +void die_errno(const char *err, ...)\n>> +{\n>> +     va_list params;\n>> +     char msg[1024];\n>> +\n>> +     va_start(params, err);\n>> +\n>> +     vsnprintf(msg, sizeof(msg), err, params);\n>> +     die(\"%s: %s\", msg, strerror(errno));\n>> +\n>> +     va_end(params);\n>> +}\n>> +\n\nThis breaks theoretical usage of custom format string in custom die\nroutines:\n        1. A custom die routine might not support %s.\n        2. If the die routine adds a custom format specifier, vsnprintf\n                will fail.\n\nBut I'm not sure that passing a format string and a va_list to\ndie_routine/error_routine/warn_routine is really necessary. If there\nis no much external code depending on them, I would convert them to the\nstyle of usage_routine:\n        void (*usage_routine)(const char *err)\n\nCC'ing Petr Baudis <pasky@suse.cz>, see commit 39a3f5ea\n\n\n>\n> No, this approach is much more elegant than what I posted, so no need to\n> credit me, at least. ;)\n\nIt was your idea of using 1024-character buffer here ;)\n\n\n                                        Alexander\n"},{"id":"115716","messageId":"7vzlck9e3j.fsf@alter.siamese.dyndns.org","threadId":"19644","inReplyTo":"2325a7950906070412k3a440558h35db7511cc390e4b@mail.gmail.com","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2009-06-07T16:57:04Z","receivedAt":"2009-06-07T16:57:04Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Alexander Potashev <aspotashev@gmail.com> writes:\n\n> This breaks theoretical usage of custom format string in custom die\n> routines:\n>         1. A custom die routine might not support %s.\n>         2. If the die routine adds a custom format specifier, vsnprintf\n>                 will fail.\n\nI do not think that flies even as a theory.  The \"custom\" 39a3f5ea talks\nabout is more about \"Instead of sending it to stderr, let's pop up an info\nwindow and give the message there\" kind of customization.\n\nExisting die() that prints errno does so by giving strerror() to \"%s\", so\nno matter how custom your die routine is, you must support '%s' for its\noutput to make sense to humans.  If you \"not support %s\", then you will\nignore (or choke at) such strerror() result without this patch anyway.\n"},{"id":"115802","messageId":"20090608123608.GG13775@coredump.intra.peff.net","threadId":"19644","inReplyTo":"7vzlck9e3j.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-08T12:36:08Z","receivedAt":"2009-06-08T12:36:08Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sun, Jun 07, 2009 at 09:57:04AM -0700, Junio C Hamano wrote:\n\n> > This breaks theoretical usage of custom format string in custom die\n> > routines:\n> >         1. A custom die routine might not support %s.\n> >         2. If the die routine adds a custom format specifier, vsnprintf\n> >                 will fail.\n> \n> I do not think that flies even as a theory.  The \"custom\" 39a3f5ea talks\n> about is more about \"Instead of sending it to stderr, let's pop up an info\n> window and give the message there\" kind of customization.\n> \n> Existing die() that prints errno does so by giving strerror() to \"%s\", so\n> no matter how custom your die routine is, you must support '%s' for its\n> output to make sense to humans.  If you \"not support %s\", then you will\n> ignore (or choke at) such strerror() result without this patch anyway.\n\nMore than that, you must support arbitrary printf format strings,\nbecause the die routine is passed whatever goes to die() (a quick grep\nrevealed that we use at least %u and %c at various points). So it is an\nundocumented requirement that the die routine process its parameters as\nif it were from the printf family.\n\nI think what Thomas posted is fine.\n\n-Peff\n"},{"id":"115813","messageId":"2325a7950906080835h6d6d2d28j2c7261f2296a3da6@mail.gmail.com","threadId":"19644","inReplyTo":"20090608123608.GG13775@coredump.intra.peff.net","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Alexander Potashev","fromEmail":"aspotashev@gmail.com","sentAt":"2009-06-08T15:35:55Z","receivedAt":"2009-06-08T15:35:55Z","isPatch":true,"sender":{"key":"aspotashev@gmail.com","avatar":null},"body":"2009/6/8 Jeff King <peff@peff.net>:\n> On Sun, Jun 07, 2009 at 09:57:04AM -0700, Junio C Hamano wrote:\n>\n>> > This breaks theoretical usage of custom format string in custom die\n>> > routines:\n>> >         1. A custom die routine might not support %s.\n>> >         2. If the die routine adds a custom format specifier, vsnprintf\n>> >                 will fail.\n>>\n>> I do not think that flies even as a theory.  The \"custom\" 39a3f5ea talks\n>> about is more about \"Instead of sending it to stderr, let's pop up an info\n>> window and give the message there\" kind of customization.\n>>\n>> Existing die() that prints errno does so by giving strerror() to \"%s\", so\n>> no matter how custom your die routine is, you must support '%s' for its\n>> output to make sense to humans.  If you \"not support %s\", then you will\n>> ignore (or choke at) such strerror() result without this patch anyway.\n>\n> More than that, you must support arbitrary printf format strings,\n> because the die routine is passed whatever goes to die() (a quick grep\n> revealed that we use at least %u and %c at various points). So it is an\n> undocumented requirement that the die routine process its parameters as\n> if it were from the printf family.\n\nYour last statement is not quite true. A custom die routine may\nsupport all printf specifiers and some additional ones, but Thomas'\ndie_errno passes the format string (and arguments list) to vsnprintf\nanyway, so the additional specifiers would be lost.\n\n>\n> I think what Thomas posted is fine.\n>\n> -Peff\n>\n"},{"id":"115852","messageId":"20090608220423.GA29942@sigill.intra.peff.net","threadId":"19644","inReplyTo":"2325a7950906080835h6d6d2d28j2c7261f2296a3da6@mail.gmail.com","subject":"Re: [PATCH v2 1/3] Introduce die_errno() that appends strerror(errno) to die()","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2009-06-08T22:04:24Z","receivedAt":"2009-06-08T22:04:24Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jun 08, 2009 at 07:35:55PM +0400, Alexander Potashev wrote:\n\n> > More than that, you must support arbitrary printf format strings,\n> > because the die routine is passed whatever goes to die() (a quick grep\n> > revealed that we use at least %u and %c at various points). So it is an\n> > undocumented requirement that the die routine process its parameters as\n> > if it were from the printf family.\n> \n> Your last statement is not quite true. A custom die routine may\n> support all printf specifiers and some additional ones, but Thomas'\n> die_errno passes the format string (and arguments list) to vsnprintf\n> anyway, so the additional specifiers would be lost.\n\nBut if die() is called (_not_ die_errno), then the format is passed\nunchanged. So what I am saying is that anyone supplying a die_routine\n_already_ has to handle all printf format specifiers. So asking them to\nhandle just \"%s\" via die_errno is not introducing any additional\nrequirements.\n\n-Peff\n"}]}