static void make_test_data(const char *reponame, const char **files) { const char **scan; size_t repolen = strlen(reponame) + 1; g_repo = cl_git_sandbox_init(reponame); for (scan = files; *scan != NULL; ++scan) { cl_git_pass(git_futils_mkdir_relative( *scan + repolen, reponame, 0777, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST, NULL)); cl_git_mkfile(*scan, "contents"); } }
int git_futils_mkdir( const char *path, mode_t mode, uint32_t flags) { git_buf make_path = GIT_BUF_INIT, parent_path = GIT_BUF_INIT; const char *relative; struct git_futils_mkdir_options opts = { 0 }; struct stat st; size_t depth = 0; int len = 0, root_len, error; if ((error = git_buf_puts(&make_path, path)) < 0 || (error = mkdir_canonicalize(&make_path, flags)) < 0 || (error = git_buf_puts(&parent_path, make_path.ptr)) < 0 || make_path.size == 0) goto done; root_len = git_path_root(make_path.ptr); /* find the first parent directory that exists. this will be used * as the base to dirname_relative. */ for (relative = make_path.ptr; parent_path.size; ) { error = p_lstat(parent_path.ptr, &st); if (error == 0) { break; } else if (errno != ENOENT) { giterr_set(GITERR_OS, "failed to stat '%s'", parent_path.ptr); goto done; } depth++; /* examine the parent of the current path */ if ((len = git_path_dirname_r(&parent_path, parent_path.ptr)) < 0) { error = len; goto done; } assert(len); /* we've walked all the given path's parents and it's either relative * or rooted. either way, give up and make the entire path. */ if ((len == 1 && parent_path.ptr[0] == '.') || len == root_len+1) { relative = make_path.ptr; break; } relative = make_path.ptr + len + 1; /* not recursive? just make this directory relative to its parent. */ if ((flags & GIT_MKDIR_PATH) == 0) break; } /* we found an item at the location we're trying to create, * validate it. */ if (depth == 0) { error = mkdir_validate_dir(make_path.ptr, &st, mode, flags, &opts); if (!error) error = mkdir_validate_mode( make_path.ptr, &st, true, mode, flags, &opts); goto done; } /* we already took `SKIP_LAST` and `SKIP_LAST2` into account when * canonicalizing `make_path`. */ flags &= ~(GIT_MKDIR_SKIP_LAST2 | GIT_MKDIR_SKIP_LAST); error = git_futils_mkdir_relative(relative, parent_path.size ? parent_path.ptr : NULL, mode, flags, &opts); done: git_buf_free(&make_path); git_buf_free(&parent_path); return error; }
static int object_mkdir(const git_buf *name, const loose_backend *be) { return git_futils_mkdir_relative( name->ptr + be->objects_dirlen, be->objects_dir, be->object_dir_mode, GIT_MKDIR_PATH | GIT_MKDIR_SKIP_LAST | GIT_MKDIR_VERIFY_DIR, NULL); }