Commit 0862ec2e by Edward Thomson

core::mkdir tests: ensure we don't stomp symlinks in mkdir

In `mkdir` and `mkdir_r`, ensure that we don't try to remove symlinks
that are in our way.
parent 08df6630
...@@ -526,6 +526,17 @@ bool git_path_isfile(const char *path) ...@@ -526,6 +526,17 @@ bool git_path_isfile(const char *path)
return S_ISREG(st.st_mode) != 0; return S_ISREG(st.st_mode) != 0;
} }
bool git_path_islink(const char *path)
{
struct stat st;
assert(path);
if (p_lstat(path, &st) < 0)
return false;
return S_ISLNK(st.st_mode) != 0;
}
#ifdef GIT_WIN32 #ifdef GIT_WIN32
bool git_path_is_empty_dir(const char *path) bool git_path_is_empty_dir(const char *path)
......
...@@ -169,6 +169,12 @@ extern bool git_path_isdir(const char *path); ...@@ -169,6 +169,12 @@ extern bool git_path_isdir(const char *path);
extern bool git_path_isfile(const char *path); extern bool git_path_isfile(const char *path);
/** /**
* Check if the given path points to a symbolic link.
* @return true or false
*/
extern bool git_path_islink(const char *path);
/**
* Check if the given path is a directory, and is empty. * Check if the given path is a directory, and is empty.
*/ */
extern bool git_path_is_empty_dir(const char *path); extern bool git_path_is_empty_dir(const char *path);
......
...@@ -222,6 +222,40 @@ void test_core_mkdir__chmods(void) ...@@ -222,6 +222,40 @@ void test_core_mkdir__chmods(void)
check_mode(0777, st.st_mode); check_mode(0777, st.st_mode);
} }
void test_core_mkdir__keeps_parent_symlinks(void)
{
#ifndef GIT_WIN32
git_buf path = GIT_BUF_INIT;
cl_set_cleanup(cleanup_basic_dirs, NULL);
/* make a directory */
cl_assert(!git_path_isdir("d0"));
cl_git_pass(git_futils_mkdir("d0", 0755, 0));
cl_assert(git_path_isdir("d0"));
cl_must_pass(symlink("d0", "d1"));
cl_assert(git_path_islink("d1"));
cl_git_pass(git_futils_mkdir("d1/foo/bar", 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS));
cl_assert(git_path_islink("d1"));
cl_assert(git_path_isdir("d1/foo/bar"));
cl_assert(git_path_isdir("d0/foo/bar"));
cl_must_pass(symlink("d0", "d2"));
cl_assert(git_path_islink("d2"));
git_buf_joinpath(&path, clar_sandbox_path(), "d2/other/dir");
cl_git_pass(git_futils_mkdir(path.ptr, 0755, GIT_MKDIR_PATH|GIT_MKDIR_REMOVE_SYMLINKS));
cl_assert(git_path_islink("d2"));
cl_assert(git_path_isdir("d2/other/dir"));
cl_assert(git_path_isdir("d0/other/dir"));
git_buf_free(&path);
#endif
}
void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void) void test_core_mkdir__mkdir_path_inside_unwriteable_parent(void)
{ {
struct stat st; struct stat st;
......
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