summaryrefslogtreecommitdiff
path: root/src/fileops.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2015-01-13 11:18:02 -0600
committerEdward Thomson <ethomson@microsoft.com>2015-01-20 17:12:46 -0600
commitfe598f0903012e361eca53c4cb65c27e4e8dfac9 (patch)
treec14afd12de1992426911040015cae5457ea0187b /src/fileops.c
parent1fbfcdfcd0f3b87e95cea15b3c90808ccd5f9a79 (diff)
downloadlibgit2-fe598f0903012e361eca53c4cb65c27e4e8dfac9.tar.gz
mkdir: walk up tree to mkdir
Walk up the tree to mkdir, which is less immediately efficient, but allows us to look at intermediate directories that may need attention.
Diffstat (limited to 'src/fileops.c')
-rw-r--r--src/fileops.c36
1 files changed, 25 insertions, 11 deletions
diff --git a/src/fileops.c b/src/fileops.c
index 926813f5e..ea0f4e1f7 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -352,26 +352,40 @@ int git_futils_mkdir_withperf(
*tail = '\0';
st.st_mode = 0;
- /* make directory */
- perfdata->mkdir_calls++;
+ /* See what's going on with this path component */
+ perfdata->stat_calls++;
+
+ if (p_lstat(make_path.ptr, &st) < 0) {
+ perfdata->mkdir_calls++;
- if (p_mkdir(make_path.ptr, mode) < 0) {
- int tmp_errno = giterr_system_last();
+ 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;
+ goto done;
+ }
+
+ giterr_clear();
+ } else {
+ /* with exclusive create, existing dir is an error */
+ if ((flags & GIT_MKDIR_EXCL) != 0) {
+ giterr_set(GITERR_FILESYSTEM, "Failed to make directory '%s': directory exists", make_path.ptr);
+ error = GIT_EEXISTS;
+ goto done;
+ }
- /* ignore error if not at end or if directory already exists */
- if (lastch == '\0') {
+ if (S_ISLNK(st.st_mode)) {
perfdata->stat_calls++;
- if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
- giterr_system_set(tmp_errno);
+ /* Re-stat the target, make sure it's a directory */
+ if (p_stat(make_path.ptr, &st) < 0) {
giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
+ error = GIT_EEXISTS;
goto done;
}
}
- /* with exclusive create, existing dir is an error */
- if ((flags & GIT_MKDIR_EXCL) != 0) {
- giterr_set(GITERR_OS, "Directory already exists '%s'", make_path.ptr);
+ if (!S_ISDIR(st.st_mode)) {
+ giterr_set(GITERR_FILESYSTEM, "Failed to make directory '%s': directory exists", make_path.ptr);
error = GIT_EEXISTS;
goto done;
}