summaryrefslogtreecommitdiff
path: root/sha1_file.c
diff options
context:
space:
mode:
authorSteven Walter <stevenrwalter@gmail.com>2013-03-17 10:09:27 -0400
committerJunio C Hamano <gitster@pobox.com>2013-03-26 21:07:42 -0700
commit928734d99370e2478e3b3881e5b0aa79745ac27c (patch)
tree02fc0e4df6299e6a0ad5899da422742469bd3444 /sha1_file.c
parent7e2010537e96d0a1144520222f20ba1dc3d61441 (diff)
downloadgit-928734d99370e2478e3b3881e5b0aa79745ac27c.tar.gz
safe_create_leading_directories: fix race that could give a false negative
If two processes are racing to create the same directory tree, they will both see that the directory doesn't exist, both try to mkdir(), and one of them will fail. This is okay, as we only care that the directory gets created. So, we add a check for EEXIST from mkdir, and continue when the directory exists, taking the same codepath as the case where the earlier stat() succeeds and finds a directory. Signed-off-by: Steven Walter <stevenrwalter@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'sha1_file.c')
-rw-r--r--sha1_file.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/sha1_file.c b/sha1_file.c
index 9152974642..964c4d44ab 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -122,8 +122,13 @@ int safe_create_leading_directories(char *path)
}
}
else if (mkdir(path, 0777)) {
- *pos = '/';
- return -1;
+ if (errno == EEXIST &&
+ !stat(path, &st) && S_ISDIR(st.st_mode)) {
+ ; /* somebody created it since we checked */
+ } else {
+ *pos = '/';
+ return -1;
+ }
}
else if (adjust_shared_perm(path)) {
*pos = '/';