{
FILE *interactive;
- if (!is_directory(merge_dir()) && mkdir_in_gitdir(merge_dir()))
+ if (!is_directory(merge_dir()) &&
+ safe_create_dir_in_gitdir(the_repository, merge_dir()))
return error_errno(_("could not create temporary %s"), merge_dir());
refs_delete_reflog(get_main_ref_store(the_repository), "REBASE_HEAD");
return 0;
}
-
-int mkdir_in_gitdir(const char *path)
-{
- if (mkdir(path, 0777)) {
- int saved_errno = errno;
- struct stat st;
- struct strbuf sb = STRBUF_INIT;
-
- if (errno != EEXIST)
- return -1;
- /*
- * Are we looking at a path in a symlinked worktree
- * whose original repository does not yet have it?
- * e.g. .git/rr-cache pointing at its original
- * repository in which the user hasn't performed any
- * conflict resolution yet?
- */
- if (lstat(path, &st) || !S_ISLNK(st.st_mode) ||
- strbuf_readlink(&sb, path, st.st_size) ||
- !is_absolute_path(sb.buf) ||
- mkdir(sb.buf, 0777)) {
- strbuf_release(&sb);
- errno = saved_errno;
- return -1;
- }
- strbuf_release(&sb);
- }
- return adjust_shared_perm(the_repository, path);
-}
-
static enum scld_error safe_create_leading_directories_1(char *path, int share)
{
char *next_component = path + offset_1st_component(path);
struct strbuf dir = STRBUF_INIT;
strbuf_add(&dir, filename.buf, dirlen);
- if (mkdir_in_gitdir(dir.buf) && errno != EEXIST) {
+ if (safe_create_dir_in_gitdir(the_repository, dir.buf) &&
+ errno != EEXIST) {
err = error_errno(_("unable to create directory %s"), dir.buf);
strbuf_release(&dir);
goto cleanup;
enum scld_error safe_create_leading_directories_const(const char *path);
enum scld_error safe_create_leading_directories_no_share(char *path);
-int mkdir_in_gitdir(const char *path);
-
int git_open_cloexec(const char *name, int flags);
#define git_open(name) git_open_cloexec(name, O_RDONLY)
die(_("Could not make %s writable by group"), dir);
}
+int safe_create_dir_in_gitdir(struct repository *repo, const char *path)
+{
+ if (mkdir(path, 0777)) {
+ int saved_errno = errno;
+ struct stat st;
+ struct strbuf sb = STRBUF_INIT;
+
+ if (errno != EEXIST)
+ return -1;
+ /*
+ * Are we looking at a path in a symlinked worktree
+ * whose original repository does not yet have it?
+ * e.g. .git/rr-cache pointing at its original
+ * repository in which the user hasn't performed any
+ * conflict resolution yet?
+ */
+ if (lstat(path, &st) || !S_ISLNK(st.st_mode) ||
+ strbuf_readlink(&sb, path, st.st_size) ||
+ !is_absolute_path(sb.buf) ||
+ mkdir(sb.buf, 0777)) {
+ strbuf_release(&sb);
+ errno = saved_errno;
+ return -1;
+ }
+ strbuf_release(&sb);
+ }
+ return adjust_shared_perm(repo, path);
+}
+
static int have_same_root(const char *path1, const char *path2)
{
int is_abs1, is_abs2;
*/
void safe_create_dir(struct repository *repo, const char *dir, int share);
+/*
+ * Similar to `safe_create_dir()`, but with two differences:
+ *
+ * - It knows to resolve gitlink files for symlinked worktrees.
+ *
+ * - It always adjusts shared permissions.
+ *
+ * Returns a negative erorr code on error, 0 on success.
+ */
+int safe_create_dir_in_gitdir(struct repository *repo, const char *path);
+
# ifdef USE_THE_REPOSITORY_VARIABLE
# include "strbuf.h"
# include "repository.h"
string_list_insert(rr, path)->util = id;
/* Ensure that the directory exists. */
- mkdir_in_gitdir(rerere_path(&buf, id, NULL));
+ safe_create_dir_in_gitdir(the_repository, rerere_path(&buf, id, NULL));
}
for (i = 0; i < rr->nr; i++)
if (rerere_enabled < 0)
return rr_cache_exists;
- if (!rr_cache_exists && mkdir_in_gitdir(git_path_rr_cache()))
+ if (!rr_cache_exists &&
+ safe_create_dir_in_gitdir(the_repository, git_path_rr_cache()))
die(_("could not create directory '%s'"), git_path_rr_cache());
return 1;
}