{"thread":{"id":"19127","subject":"[PATCH 1/2] Introduce an unlink(2) wrapper which gives warning if unlink failed","startedAt":"2009-04-29T21:21:46Z","lastAt":"2009-04-29T21:22:56Z","messageCount":2,"participants":["Alex Riesen"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"112693","messageId":"20090429212146.GA12099@blimp.localdomain","threadId":"19127","inReplyTo":null,"subject":"[PATCH 1/2] Introduce an unlink(2) wrapper which gives warning if unlink failed","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2009-04-29T21:21:46Z","receivedAt":"2009-04-29T21:21:46Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"This seem to be a very common pattern in the current code.\n\nThe function prints a generic removal failure message, the file name\nwhich failed and readable errno presentation. The function preserves\nerrno and always returns the value unlink(2) returned, but prints\nno message for ENOENT, as it was the most often filtered out in the\ncode calling unlink. Besides, removing a file is anyway the purpose of\ncalling unlink.\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n git-compat-util.h |    6 ++++++\n wrapper.c         |   16 ++++++++++++++++\n 2 files changed, 22 insertions(+), 0 deletions(-)\n\ndiff --git a/git-compat-util.h b/git-compat-util.h\nindex 1ac16bd..d1d4eaf 100644\n--- a/git-compat-util.h\n+++ b/git-compat-util.h\n@@ -415,4 +415,10 @@ void git_qsort(void *base, size_t nmemb, size_t size,\n #define fstat_is_reliable() 1\n #endif\n \n+/*\n+ * Preserves errno, prints a message, but gives no warning for ENOENT.\n+ * Always returns the return value of unlink(2).\n+ */\n+int unlink_or_warn(const char *path);\n+\n #endif\ndiff --git a/wrapper.c b/wrapper.c\nindex d8efb13..7eb3218 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -289,3 +289,19 @@ int odb_pack_keep(char *name, size_t namesz, unsigned char *sha1)\n \tsafe_create_leading_directories(name);\n \treturn open(name, O_RDWR|O_CREAT|O_EXCL, 0600);\n }\n+\n+int unlink_or_warn(const char *file)\n+{\n+\tint rc = unlink(file);\n+\n+\tif (rc < 0) {\n+\t\tint err = errno;\n+\t\tif (ENOENT != err) {\n+\t\t\twarning(\"unable to unlink %s: %s\",\n+\t\t\t\tfile, strerror(errno));\n+\t\t\terrno = err;\n+\t\t}\n+\t}\n+\treturn rc;\n+}\n+\n-- \n1.6.3.rc3.39.g49fd5\n"},{"id":"112694","messageId":"20090429212256.GB12099@blimp.localdomain","threadId":"19127","inReplyTo":"20090429212146.GA12099@blimp.localdomain","subject":"[PATCH 2/2] replace direct calls to unlink(2) with unlink_or_warn","fromName":"Alex Riesen","fromEmail":"raa.lkml@gmail.com","sentAt":"2009-04-29T21:22:56Z","receivedAt":"2009-04-29T21:22:56Z","isPatch":true,"sender":{"key":"raa.lkml@gmail.com","avatar":"https://avatars.githubusercontent.com/u/324101?v=4"},"body":"This helps to notice when something's going wrong, especially on\nsystems which lock open files.\n\nI used the following criteria when selecting the code for replacement:\n- it was already printing a warning for the unlink failures\n- it is in a function which already printing something or is\n  called from such a function\n- it is in a static function, returning void and the function is only\n  called from a builtin main function (cmd_)\n- it is in a function which handles emergency exit (signal handlers)\n- it is in a function which is obvously cleaning up the lockfiles\n\nSigned-off-by: Alex Riesen <raa.lkml@gmail.com>\n---\n builtin-apply.c        |    4 ++--\n builtin-fetch-pack.c   |    2 +-\n builtin-prune-packed.c |    4 ++--\n builtin-prune.c        |    4 ++--\n builtin-receive-pack.c |    2 +-\n builtin-remote.c       |    4 ++--\n builtin-rerere.c       |    2 +-\n builtin-tag.c          |    2 +-\n builtin-verify-tag.c   |    2 +-\n diff.c                 |    2 +-\n entry.c                |    2 +-\n fast-import.c          |    4 ++--\n http-push.c            |   12 ++++++------\n http-walker.c          |   14 +++++++-------\n ll-merge.c             |    2 +-\n lockfile.c             |    4 ++--\n pack-refs.c            |    2 +-\n refs.c                 |   15 +++++----------\n rerere.c               |    2 +-\n server-info.c          |    2 +-\n sha1_file.c            |    2 +-\n transport.c            |    2 +-\n unpack-trees.c         |    2 +-\n 23 files changed, 44 insertions(+), 49 deletions(-)\n\ndiff --git a/builtin-apply.c b/builtin-apply.c\nindex 7b404ef..8a3771e 100644\n--- a/builtin-apply.c\n+++ b/builtin-apply.c\n@@ -2781,7 +2781,7 @@ static void remove_file(struct patch *patch, int rmdir_empty)\n \t\t\tif (rmdir(patch->old_name))\n \t\t\t\twarning(\"unable to remove submodule %s\",\n \t\t\t\t\tpatch->old_name);\n-\t\t} else if (!unlink(patch->old_name) && rmdir_empty) {\n+\t\t} else if (!unlink_or_warn(patch->old_name) && rmdir_empty) {\n \t\t\tremove_path(patch->old_name);\n \t\t}\n \t}\n@@ -2891,7 +2891,7 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned\n \t\t\tif (!try_create_file(newpath, mode, buf, size)) {\n \t\t\t\tif (!rename(newpath, path))\n \t\t\t\t\treturn;\n-\t\t\t\tunlink(newpath);\n+\t\t\t\tunlink_or_warn(newpath);\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tif (errno != EEXIST)\ndiff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c\nindex 5d134be..bd97cfd 100644\n--- a/builtin-fetch-pack.c\n+++ b/builtin-fetch-pack.c\n@@ -814,7 +814,7 @@ struct ref *fetch_pack(struct fetch_pack_args *my_args,\n \t\tfd = hold_lock_file_for_update(&lock, shallow,\n \t\t\t\t\t       LOCK_DIE_ON_ERROR);\n \t\tif (!write_shallow_commits(fd, 0)) {\n-\t\t\tunlink(shallow);\n+\t\t\tunlink_or_warn(shallow);\n \t\t\trollback_lock_file(&lock);\n \t\t} else {\n \t\t\tcommit_lock_file(&lock);\ndiff --git a/builtin-prune-packed.c b/builtin-prune-packed.c\nindex 4942892..00590b1 100644\n--- a/builtin-prune-packed.c\n+++ b/builtin-prune-packed.c\n@@ -28,8 +28,8 @@ static void prune_dir(int i, DIR *dir, char *pathname, int len, int opts)\n \t\tmemcpy(pathname + len, de->d_name, 38);\n \t\tif (opts & DRY_RUN)\n \t\t\tprintf(\"rm -f %s\\n\", pathname);\n-\t\telse if (unlink(pathname) < 0)\n-\t\t\terror(\"unable to unlink %s\", pathname);\n+\t\telse\n+\t\t\tunlink_or_warn(pathname);\n \t\tdisplay_progress(progress, i + 1);\n \t}\n \tpathname[len] = 0;\ndiff --git a/builtin-prune.c b/builtin-prune.c\nindex 545e9c1..145ba83 100644\n--- a/builtin-prune.c\n+++ b/builtin-prune.c\n@@ -27,7 +27,7 @@ static int prune_tmp_object(const char *path, const char *filename)\n \t}\n \tprintf(\"Removing stale temporary file %s\\n\", fullpath);\n \tif (!show_only)\n-\t\tunlink(fullpath);\n+\t\tunlink_or_warn(fullpath);\n \treturn 0;\n }\n \n@@ -47,7 +47,7 @@ static int prune_object(char *path, const char *filename, const unsigned char *s\n \t\t       (type > 0) ? typename(type) : \"unknown\");\n \t}\n \tif (!show_only)\n-\t\tunlink(fullpath);\n+\t\tunlink_or_warn(fullpath);\n \treturn 0;\n }\n \ndiff --git a/builtin-receive-pack.c b/builtin-receive-pack.c\nindex a970b39..035b723 100644\n--- a/builtin-receive-pack.c\n+++ b/builtin-receive-pack.c\n@@ -702,7 +702,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)\n \t\t\tunpack_status = unpack();\n \t\texecute_commands(unpack_status);\n \t\tif (pack_lockfile)\n-\t\t\tunlink(pack_lockfile);\n+\t\t\tunlink_or_warn(pack_lockfile);\n \t\tif (report_status)\n \t\t\treport(unpack_status);\n \t\trun_receive_hook(post_receive_hook);\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex 2ed752c..71abf68 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -525,8 +525,8 @@ static int migrate_file(struct remote *remote)\n \t\tpath = git_path(\"remotes/%s\", remote->name);\n \telse if (remote->origin == REMOTE_BRANCHES)\n \t\tpath = git_path(\"branches/%s\", remote->name);\n-\tif (path && unlink(path))\n-\t\twarning(\"failed to remove '%s'\", path);\n+\tif (path)\n+\t\tunlink_or_warn(path);\n \treturn 0;\n }\n \ndiff --git a/builtin-rerere.c b/builtin-rerere.c\nindex 020af73..adfb7b5 100644\n--- a/builtin-rerere.c\n+++ b/builtin-rerere.c\n@@ -116,7 +116,7 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)\n \t\t\tif (!has_rerere_resolution(name))\n \t\t\t\tunlink_rr_item(name);\n \t\t}\n-\t\tunlink(git_path(\"rr-cache/MERGE_RR\"));\n+\t\tunlink_or_warn(git_path(\"rr-cache/MERGE_RR\"));\n \t} else if (!strcmp(argv[1], \"gc\"))\n \t\tgarbage_collect(&merge_rr);\n \telse if (!strcmp(argv[1], \"status\"))\ndiff --git a/builtin-tag.c b/builtin-tag.c\nindex 01e7374..e544430 100644\n--- a/builtin-tag.c\n+++ b/builtin-tag.c\n@@ -338,7 +338,7 @@ static void create_tag(const unsigned char *object, const char *tag,\n \t\texit(128);\n \t}\n \tif (path) {\n-\t\tunlink(path);\n+\t\tunlink_or_warn(path);\n \t\tfree(path);\n \t}\n }\ndiff --git a/builtin-verify-tag.c b/builtin-verify-tag.c\nindex 729a159..7f7fda4 100644\n--- a/builtin-verify-tag.c\n+++ b/builtin-verify-tag.c\n@@ -55,7 +55,7 @@ static int run_gpg_verify(const char *buf, unsigned long size, int verbose)\n \tclose(gpg.in);\n \tret = finish_command(&gpg);\n \n-\tunlink(path);\n+\tunlink_or_warn(path);\n \n \treturn ret;\n }\ndiff --git a/diff.c b/diff.c\nindex 3ac7168..6802f5a 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -189,7 +189,7 @@ static void remove_tempfile(void)\n \tint i;\n \tfor (i = 0; i < ARRAY_SIZE(diff_temp); i++) {\n \t\tif (diff_temp[i].name == diff_temp[i].tmp_path)\n-\t\t\tunlink(diff_temp[i].name);\n+\t\t\tunlink_or_warn(diff_temp[i].name);\n \t\tdiff_temp[i].name = NULL;\n \t}\n }\ndiff --git a/entry.c b/entry.c\nindex 915514a..cc841ed 100644\n--- a/entry.c\n+++ b/entry.c\n@@ -35,7 +35,7 @@ static void create_directories(const char *path, int path_len,\n \t\t */\n \t\tif (mkdir(buf, 0777)) {\n \t\t\tif (errno == EEXIST && state->force &&\n-\t\t\t    !unlink(buf) && !mkdir(buf, 0777))\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}\ndiff --git a/fast-import.c b/fast-import.c\nindex 8d959af..6a618e9 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -931,7 +931,7 @@ static void unkeep_all_packs(void)\n \t\tstruct packed_git *p = all_packs[k];\n \t\tsnprintf(name, sizeof(name), \"%s/pack/pack-%s.keep\",\n \t\t\t get_object_directory(), sha1_to_hex(p->sha1));\n-\t\tunlink(name);\n+\t\tunlink_or_warn(name);\n \t}\n }\n \n@@ -981,7 +981,7 @@ static void end_packfile(void)\n \t}\n \telse {\n \t\tclose(old_p->pack_fd);\n-\t\tunlink(old_p->pack_name);\n+\t\tunlink_or_warn(old_p->pack_name);\n \t}\n \tfree(old_p);\n \ndiff --git a/http-push.c b/http-push.c\nindex 5138224..29e8ebf 100644\n--- a/http-push.c\n+++ b/http-push.c\n@@ -315,9 +315,9 @@ static void start_fetch_loose(struct transfer_request *request)\n \t\t \"%s.temp\", filename);\n \n \tsnprintf(prevfile, sizeof(prevfile), \"%s.prev\", request->filename);\n-\tunlink(prevfile);\n+\tunlink_or_warn(prevfile);\n \trename(request->tmpfile, prevfile);\n-\tunlink(request->tmpfile);\n+\tunlink_or_warn(request->tmpfile);\n \n \tif (request->local_fileno != -1)\n \t\terror(\"fd leakage in start: %d\", request->local_fileno);\n@@ -372,7 +372,7 @@ static void start_fetch_loose(struct transfer_request *request)\n \t\t} while (prev_read > 0);\n \t\tclose(prevlocal);\n \t}\n-\tunlink(prevfile);\n+\tunlink_or_warn(prevfile);\n \n \t/* Reset inflate/SHA1 if there was an error reading the previous temp\n \t   file; also rewind to the beginning of the local file. */\n@@ -784,7 +784,7 @@ static void finish_request(struct transfer_request *request)\n \t\t    request->http_code != 416) {\n \t\t\tif (stat(request->tmpfile, &st) == 0) {\n \t\t\t\tif (st.st_size == 0)\n-\t\t\t\t\tunlink(request->tmpfile);\n+\t\t\t\t\tunlink_or_warn(request->tmpfile);\n \t\t\t}\n \t\t} else {\n \t\t\tif (request->http_code == 416)\n@@ -793,9 +793,9 @@ static void finish_request(struct transfer_request *request)\n \t\t\tgit_inflate_end(&request->stream);\n \t\t\tgit_SHA1_Final(request->real_sha1, &request->c);\n \t\t\tif (request->zret != Z_STREAM_END) {\n-\t\t\t\tunlink(request->tmpfile);\n+\t\t\t\tunlink_or_warn(request->tmpfile);\n \t\t\t} else if (hashcmp(request->obj->sha1, request->real_sha1)) {\n-\t\t\t\tunlink(request->tmpfile);\n+\t\t\t\tunlink_or_warn(request->tmpfile);\n \t\t\t} else {\n \t\t\t\trequest->rename =\n \t\t\t\t\tmove_temp_to_file(\ndiff --git a/http-walker.c b/http-walker.c\nindex c5a3ea3..7321ccc 100644\n--- a/http-walker.c\n+++ b/http-walker.c\n@@ -111,9 +111,9 @@ static void start_object_request(struct walker *walker,\n \tstruct walker_data *data = walker->data;\n \n \tsnprintf(prevfile, sizeof(prevfile), \"%s.prev\", obj_req->filename);\n-\tunlink(prevfile);\n+\tunlink_or_warn(prevfile);\n \trename(obj_req->tmpfile, prevfile);\n-\tunlink(obj_req->tmpfile);\n+\tunlink_or_warn(obj_req->tmpfile);\n \n \tif (obj_req->local != -1)\n \t\terror(\"fd leakage in start: %d\", obj_req->local);\n@@ -177,7 +177,7 @@ static void start_object_request(struct walker *walker,\n \t\t} while (prev_read > 0);\n \t\tclose(prevlocal);\n \t}\n-\tunlink(prevfile);\n+\tunlink_or_warn(prevfile);\n \n \t/* Reset inflate/SHA1 if there was an error reading the previous temp\n \t   file; also rewind to the beginning of the local file. */\n@@ -238,18 +238,18 @@ static void finish_object_request(struct object_request *obj_req)\n \t} else if (obj_req->curl_result != CURLE_OK) {\n \t\tif (stat(obj_req->tmpfile, &st) == 0)\n \t\t\tif (st.st_size == 0)\n-\t\t\t\tunlink(obj_req->tmpfile);\n+\t\t\t\tunlink_or_warn(obj_req->tmpfile);\n \t\treturn;\n \t}\n \n \tgit_inflate_end(&obj_req->stream);\n \tgit_SHA1_Final(obj_req->real_sha1, &obj_req->c);\n \tif (obj_req->zret != Z_STREAM_END) {\n-\t\tunlink(obj_req->tmpfile);\n+\t\tunlink_or_warn(obj_req->tmpfile);\n \t\treturn;\n \t}\n \tif (hashcmp(obj_req->sha1, obj_req->real_sha1)) {\n-\t\tunlink(obj_req->tmpfile);\n+\t\tunlink_or_warn(obj_req->tmpfile);\n \t\treturn;\n \t}\n \tobj_req->rename =\n@@ -809,7 +809,7 @@ static void abort_object_request(struct object_request *obj_req)\n \t\tclose(obj_req->local);\n \t\tobj_req->local = -1;\n \t}\n-\tunlink(obj_req->tmpfile);\n+\tunlink_or_warn(obj_req->tmpfile);\n \tif (obj_req->slot) {\n \t\trelease_active_slot(obj_req->slot);\n \t\tobj_req->slot = NULL;\ndiff --git a/ll-merge.c b/ll-merge.c\nindex fa2ca52..81c02ad 100644\n--- a/ll-merge.c\n+++ b/ll-merge.c\n@@ -219,7 +219,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,\n \tclose(fd);\n  bad:\n \tfor (i = 0; i < 3; i++)\n-\t\tunlink(temp[i]);\n+\t\tunlink_or_warn(temp[i]);\n \tstrbuf_release(&cmd);\n \treturn status;\n }\ndiff --git a/lockfile.c b/lockfile.c\nindex 3dbb2d1..984eb32 100644\n--- a/lockfile.c\n+++ b/lockfile.c\n@@ -16,7 +16,7 @@ static void remove_lock_file(void)\n \t\t    lock_file_list->filename[0]) {\n \t\t\tif (lock_file_list->fd >= 0)\n \t\t\t\tclose(lock_file_list->fd);\n-\t\t\tunlink(lock_file_list->filename);\n+\t\t\tunlink_or_warn(lock_file_list->filename);\n \t\t}\n \t\tlock_file_list = lock_file_list->next;\n \t}\n@@ -259,7 +259,7 @@ void rollback_lock_file(struct lock_file *lk)\n \tif (lk->filename[0]) {\n \t\tif (lk->fd >= 0)\n \t\t\tclose(lk->fd);\n-\t\tunlink(lk->filename);\n+\t\tunlink_or_warn(lk->filename);\n \t}\n \tlk->filename[0] = 0;\n }\ndiff --git a/pack-refs.c b/pack-refs.c\nindex 2c76fb1..301fc60 100644\n--- a/pack-refs.c\n+++ b/pack-refs.c\n@@ -66,7 +66,7 @@ static void prune_ref(struct ref_to_prune *r)\n \tstruct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1);\n \n \tif (lock) {\n-\t\tunlink(git_path(\"%s\", r->name));\n+\t\tunlink_or_warn(git_path(\"%s\", r->name));\n \t\tunlock_ref(lock);\n \t}\n }\ndiff --git a/refs.c b/refs.c\nindex e65a3b4..2b1f0f0 100644\n--- a/refs.c\n+++ b/refs.c\n@@ -1002,12 +1002,10 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n \t\t} else {\n \t\t\tpath = git_path(\"%s\", refname);\n \t\t}\n-\t\terr = unlink(path);\n-\t\tif (err && errno != ENOENT) {\n+\t\terr = unlink_or_warn(path);\n+\t\tif (err && errno != ENOENT)\n \t\t\tret = 1;\n-\t\t\terror(\"unlink(%s) failed: %s\",\n-\t\t\t      path, strerror(errno));\n-\t\t}\n+\n \t\tif (!(delopt & REF_NODEREF))\n \t\t\tlock->lk->filename[i] = '.';\n \t}\n@@ -1017,10 +1015,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt)\n \t */\n \tret |= repack_without_ref(refname);\n \n-\terr = unlink(git_path(\"logs/%s\", lock->ref_name));\n-\tif (err && errno != ENOENT)\n-\t\twarning(\"unlink(%s) failed: %s\",\n-\t\t\tgit_path(\"logs/%s\", lock->ref_name), strerror(errno));\n+\tunlink_or_warn(git_path(\"logs/%s\", lock->ref_name));\n \tinvalidate_cached_refs();\n \tunlock_ref(lock);\n \treturn ret;\n@@ -1381,7 +1376,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master,\n \tif (adjust_shared_perm(git_HEAD)) {\n \t\terror(\"Unable to fix permissions on %s\", lockpath);\n \terror_unlink_return:\n-\t\tunlink(lockpath);\n+\t\tunlink_or_warn(lockpath);\n \terror_free_return:\n \t\tfree(git_HEAD);\n \t\treturn -1;\ndiff --git a/rerere.c b/rerere.c\nindex 713c6e1..87360dc 100644\n--- a/rerere.c\n+++ b/rerere.c\n@@ -173,7 +173,7 @@ static int handle_file(const char *path,\n \t\tgit_SHA1_Final(sha1, &ctx);\n \tif (hunk != RR_CONTEXT) {\n \t\tif (output)\n-\t\t\tunlink(output);\n+\t\t\tunlink_or_warn(output);\n \t\treturn error(\"Could not parse conflict hunks in %s\", path);\n \t}\n \tif (wrerror)\ndiff --git a/server-info.c b/server-info.c\nindex 66b0d9d..d096dc7 100644\n--- a/server-info.c\n+++ b/server-info.c\n@@ -246,7 +246,7 @@ int update_server_info(int force)\n \terrs = errs | update_info_packs(force);\n \n \t/* remove leftover rev-cache file if there is any */\n-\tunlink(git_path(\"info/rev-cache\"));\n+\tunlink_or_warn(git_path(\"info/rev-cache\"));\n \n \treturn errs;\n }\ndiff --git a/sha1_file.c b/sha1_file.c\nindex 11969fc..5620b71 100644\n--- a/sha1_file.c\n+++ b/sha1_file.c\n@@ -2247,7 +2247,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)\n \t\t\tgoto out;\n \t\tret = errno;\n \t}\n-\tunlink(tmpfile);\n+\tunlink_or_warn(tmpfile);\n \tif (ret) {\n \t\tif (ret != EEXIST) {\n \t\t\treturn error(\"unable to write sha1 filename %s: %s\\n\", filename, strerror(ret));\ndiff --git a/transport.c b/transport.c\nindex 3dfb03c..efecb65 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1069,7 +1069,7 @@ int transport_fetch_refs(struct transport *transport, const struct ref *refs)\n void transport_unlock_pack(struct transport *transport)\n {\n \tif (transport->pack_lockfile) {\n-\t\tunlink(transport->pack_lockfile);\n+\t\tunlink_or_warn(transport->pack_lockfile);\n \t\tfree(transport->pack_lockfile);\n \t\ttransport->pack_lockfile = NULL;\n \t}\ndiff --git a/unpack-trees.c b/unpack-trees.c\nindex e4eb8fa..aaacaf1 100644\n--- a/unpack-trees.c\n+++ b/unpack-trees.c\n@@ -61,7 +61,7 @@ static void unlink_entry(struct cache_entry *ce)\n {\n \tif (has_symlink_or_noent_leading_path(ce->name, ce_namelen(ce)))\n \t\treturn;\n-\tif (unlink(ce->name))\n+\tif (unlink_or_warn(ce->name))\n \t\treturn;\n \tschedule_dir_for_removal(ce->name, ce_namelen(ce));\n }\n-- \n1.6.3.rc3.39.g49fd5\n"}]}