summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-17 15:56:27 (GMT)
committerJunio C Hamano <gitster@pobox.com>2008-03-19 05:18:57 (GMT)
commit971f229c50aeace83d6fd30de1de755f419d4cb8 (patch)
tree57f6caf0e971589afea7e25afa58ab4de4bbdbf4
parentc4758d3c9342ea2245ca51f30f1cbf27ecc16ced (diff)
downloadgit-971f229c50aeace83d6fd30de1de755f419d4cb8.zip
git-971f229c50aeace83d6fd30de1de755f419d4cb8.tar.gz
git-971f229c50aeace83d6fd30de1de755f419d4cb8.tar.bz2
Fix possible Solaris problem in 'checkout_entry()'
Currently when checking out an entry "path", we try to unlink(2) it first (because there could be stale file), and if there is a directory there, try to deal with it (typically we run recursive rmdir). We ignore the error return from this unlink because there may not even be any file there. However if you are root on Solaris, you can unlink(2) a directory successfully and corrupt your filesystem. This moves the code around and check the directory first, and then unlink(2). Also we check the error code from it. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--entry.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/entry.c b/entry.c
index 44f4b89..222aaa3 100644
--- a/entry.c
+++ b/entry.c
@@ -218,7 +218,6 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
* to emulate by hand - much easier to let the system
* just do the right thing)
*/
- unlink(path);
if (S_ISDIR(st.st_mode)) {
/* If it is a gitlink, leave it alone! */
if (S_ISGITLINK(ce->ce_mode))
@@ -226,7 +225,8 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
if (!state->force)
return error("%s is a directory", path);
remove_subtree(path);
- }
+ } else if (unlink(path))
+ return error("unable to unlink old '%s' (%s)", path, strerror(errno));
} else if (state->not_new)
return 0;
create_directories(path, state);