mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-08 02:36:11 +00:00
Allow mkdir helper to skip parent errors
Our mkdir helper was failing is a parent directory was not accessible even if the child directory could be created. This changes the helper to keep trying child directories even when the parent is unwritable.
This commit is contained in:
parent
d28b2b7a5f
commit
668ae2ddf8
@ -355,8 +355,9 @@ int git_futils_mkdir(
|
||||
if (p_mkdir(make_path.ptr, mode) < 0) {
|
||||
int tmp_errno = giterr_system_last();
|
||||
|
||||
/* ignore error if directory already exists */
|
||||
if (p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode)) {
|
||||
/* ignore error if not at end or if directory already exists */
|
||||
if (lastch == '\0' &&
|
||||
(p_stat(make_path.ptr, &st) < 0 || !S_ISDIR(st.st_mode))) {
|
||||
giterr_system_set(tmp_errno);
|
||||
giterr_set(GITERR_OS, "Failed to make directory '%s'", make_path.ptr);
|
||||
goto done;
|
||||
@ -374,7 +375,8 @@ int git_futils_mkdir(
|
||||
if (((flags & GIT_MKDIR_CHMOD_PATH) != 0 ||
|
||||
(lastch == '\0' && (flags & GIT_MKDIR_CHMOD) != 0)) &&
|
||||
st.st_mode != mode &&
|
||||
(error = p_chmod(make_path.ptr, mode)) < 0) {
|
||||
(error = p_chmod(make_path.ptr, mode)) < 0 &&
|
||||
lastch == '\0') {
|
||||
giterr_set(GITERR_OS, "Failed to set permissions on '%s'", make_path.ptr);
|
||||
goto done;
|
||||
}
|
||||
|
@ -186,3 +186,34 @@ void test_core_mkdir__chmods(void)
|
||||
cl_git_pass(git_path_lstat("r/mode2/is2/important2.1", &st));
|
||||
check_mode(0777, st.st_mode);
|
||||
}
|
||||
|
||||
void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void)
|
||||
{
|
||||
struct stat st;
|
||||
mode_t *old;
|
||||
|
||||
/* FAT filesystems don't support exec bit, nor group/world bits */
|
||||
if (!cl_is_chmod_supported())
|
||||
return;
|
||||
|
||||
cl_assert((old = git__malloc(sizeof(mode_t))) != NULL);
|
||||
*old = p_umask(022);
|
||||
cl_set_cleanup(cleanup_chmod_root, old);
|
||||
|
||||
cl_git_pass(git_futils_mkdir("r", NULL, 0777, 0));
|
||||
cl_git_pass(git_futils_mkdir("mode/is/important", "r", 0777, GIT_MKDIR_PATH));
|
||||
cl_git_pass(git_path_lstat("r/mode", &st));
|
||||
check_mode(0755, st.st_mode);
|
||||
|
||||
cl_must_pass(p_chmod("r/mode", 0111));
|
||||
cl_git_pass(git_path_lstat("r/mode", &st));
|
||||
check_mode(0111, st.st_mode);
|
||||
|
||||
cl_git_pass(
|
||||
git_futils_mkdir("mode/is/okay/inside", "r", 0777, GIT_MKDIR_PATH));
|
||||
cl_git_pass(git_path_lstat("r/mode/is/okay/inside", &st));
|
||||
check_mode(0755, st.st_mode);
|
||||
|
||||
cl_must_pass(p_chmod("r/mode", 0777));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user