summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <tanoku@gmail.com>2015-03-19 18:38:13 +0100
committerVicent Marti <tanoku@gmail.com>2015-03-19 18:38:13 +0100
commitd88e6e9b3c9dd27644083b157bb28a42d670ed24 (patch)
treea520d900c86c60f58291d64aaf45f5facce89708
parent2c4e90f3fafd967d18c5b2f058cb6053dabafae0 (diff)
downloadlibgit2-vmg/mkdir-ext.tar.gz
mkdir-ext: Retry lstat on EEXIST racevmg/mkdir-ext
-rw-r--r--src/fileops.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/fileops.c b/src/fileops.c
index ec536bf29..993224686 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -399,6 +399,7 @@ int git_futils_mkdir_ext(
/* walk down tail of path making each directory */
for (tail = &make_path.ptr[root]; *tail; *tail = lastch) {
+ bool mkdir_attempted = false;
/* advance tail to include next path component */
while (*tail == '/')
@@ -417,16 +418,24 @@ int git_futils_mkdir_ext(
/* See what's going on with this path component */
opts->perfdata.stat_calls++;
+retry_lstat:
if (p_lstat(make_path.ptr, &st) < 0) {
- opts->perfdata.mkdir_calls++;
-
- if (errno != ENOENT || p_mkdir(make_path.ptr, mode) < 0) {
- giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
- error = GIT_EEXISTS;
+ if (mkdir_attempted || errno != ENOENT) {
+ giterr_set(GITERR_OS, "Cannot access component in path '%s'", make_path.ptr);
+ error = -1;
goto done;
}
giterr_clear();
+ opts->perfdata.mkdir_calls++;
+ mkdir_attempted = true;
+ if (p_mkdir(make_path.ptr, mode) < 0) {
+ if (errno == EEXIST)
+ goto retry_lstat;
+ giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
+ error = -1;
+ goto done;
+ }
} else {
/* with exclusive create, existing dir is an error */
if ((flags & GIT_MKDIR_EXCL) != 0) {