Commit fe598f09 by Edward Thomson

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.
parent 1fbfcdfc
......@@ -93,6 +93,7 @@ typedef enum {
GITERR_CHERRYPICK,
GITERR_DESCRIBE,
GITERR_REBASE,
GITERR_FILESYSTEM
} git_error_t;
/**
......
......@@ -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;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment