object-file: move safe_create_leading_directories() into "path.c"

The `safe_create_leading_directories()` function and its relatives are
located in "object-file.c", which is not a good fit as they provide
generic functionality not related to objects at all. Move them into
"path.c", which already hosts `safe_create_dir()` and its relative
`safe_create_dir_in_gitdir()`.

"path.c" is free of `the_repository`, but the moved functions depend on
`the_repository` to read the "core.sharedRepository" config. Adapt the
function signature to accept a repository as argument to fix the issue
and adjust callers accordingly.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Patrick Steinhardt
2025-04-15 11:38:15 +02:00
committed by Junio C Hamano
parent d1fa670de0
commit 1a99fe8010
27 changed files with 173 additions and 167 deletions

80
path.c
View File

@@ -931,6 +931,86 @@ int safe_create_dir_in_gitdir(struct repository *repo, const char *path)
return adjust_shared_perm(repo, path);
}
static enum scld_error safe_create_leading_directories_1(struct repository *repo,
char *path)
{
char *next_component = path + offset_1st_component(path);
enum scld_error ret = SCLD_OK;
while (ret == SCLD_OK && next_component) {
struct stat st;
char *slash = next_component, slash_character;
while (*slash && !is_dir_sep(*slash))
slash++;
if (!*slash)
break;
next_component = slash + 1;
while (is_dir_sep(*next_component))
next_component++;
if (!*next_component)
break;
slash_character = *slash;
*slash = '\0';
if (!stat(path, &st)) {
/* path exists */
if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
ret = SCLD_EXISTS;
}
} else if (mkdir(path, 0777)) {
if (errno == EEXIST &&
!stat(path, &st) && S_ISDIR(st.st_mode))
; /* somebody created it since we checked */
else if (errno == ENOENT)
/*
* Either mkdir() failed because
* somebody just pruned the containing
* directory, or stat() failed because
* the file that was in our way was
* just removed. Either way, inform
* the caller that it might be worth
* trying again:
*/
ret = SCLD_VANISHED;
else
ret = SCLD_FAILED;
} else if (repo && adjust_shared_perm(repo, path)) {
ret = SCLD_PERMS;
}
*slash = slash_character;
}
return ret;
}
enum scld_error safe_create_leading_directories(struct repository *repo,
char *path)
{
return safe_create_leading_directories_1(repo, path);
}
enum scld_error safe_create_leading_directories_no_share(char *path)
{
return safe_create_leading_directories_1(NULL, path);
}
enum scld_error safe_create_leading_directories_const(struct repository *repo,
const char *path)
{
int save_errno;
/* path points to cache entries, so xstrdup before messing with it */
char *buf = xstrdup(path);
enum scld_error result = safe_create_leading_directories(repo, buf);
save_errno = errno;
free(buf);
errno = save_errno;
return result;
}
static int have_same_root(const char *path1, const char *path2)
{
int is_abs1, is_abs2;