From e4029c5201ba86edd355266ea0a566995490dc1b Mon Sep 17 00:00:00 2001 From: nulltoken Date: Mon, 28 Feb 2011 12:33:47 +0100 Subject: [PATCH] Added copydir_recurs() to test_helpers.c Test helper function which recursively copies the content of a directory. This function has been tweaked to prevent stack overflows by reusing the same path buffers on all recursive calls. --- tests/t10-refs.c | 10 +++++++- tests/test_helpers.c | 57 +++++++++++++++++++++++++++++++++++++++----- tests/test_helpers.h | 1 + 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/tests/t10-refs.c b/tests/t10-refs.c index 4d4322156..20b05e3f6 100644 --- a/tests/t10-refs.c +++ b/tests/t10-refs.c @@ -297,9 +297,17 @@ END_TEST BEGIN_TEST("packrefs", create_packfile) git_repository *repo; - must_pass(git_repository_open(&repo, REPOSITORY_FOLDER)); + char temp_repo_path[GIT_PATH_MAX]; + + must_pass(copydir_recurs(REPOSITORY_FOLDER, TEMP_DIR)); + + git__joinpath(temp_repo_path, TEMP_DIR, TEST_REPOSITORY_NAME); + must_pass(git_repository_open(&repo, temp_repo_path)); must_pass(git_reference_packall(repo)); + git_repository_free(repo); + must_pass(rmdir_recurs(TEMP_DIR)); + END_TEST static int ensure_refname_normalized(int is_oid_ref, const char *input_refname, const char *expected_refname) diff --git a/tests/test_helpers.c b/tests/test_helpers.c index 60ef5b50d..4805fdcae 100644 --- a/tests/test_helpers.c +++ b/tests/test_helpers.c @@ -178,19 +178,19 @@ int cmp_files(const char *a, const char *b) static int remove_filesystem_element_recurs(void *GIT_UNUSED(nil), char *path) { - char temp_path[GIT_PATH_MAX]; int error = GIT_SUCCESS; GIT_UNUSED_ARG(nil); error = gitfo_isdir(path); - if (error == GIT_SUCCESS) - { - strcpy(temp_path, path); - error = gitfo_dirent(temp_path, sizeof(temp_path), remove_filesystem_element_recurs, NULL); + if (error == GIT_SUCCESS) { + size_t root_size = strlen(path); + + error = gitfo_dirent(path, GIT_PATH_MAX, remove_filesystem_element_recurs, NULL); if (error < GIT_SUCCESS) return error; + path[root_size] = 0; return rmdir(path); } @@ -199,5 +199,50 @@ static int remove_filesystem_element_recurs(void *GIT_UNUSED(nil), char *path) int rmdir_recurs(char *directory_path) { - return remove_filesystem_element_recurs(NULL, directory_path); + char buffer[GIT_PATH_MAX]; + strcpy(buffer, directory_path); + return remove_filesystem_element_recurs(NULL, buffer); +} + +typedef struct { + size_t src_len, dst_len; + char *dst; +} copydir_data; + +static int copy_filesystem_element_recurs(void *_data, char *source) +{ + const int mode = 0755; /* or 0777 ? */ + copydir_data *data = (copydir_data *)_data; + + data->dst[data->dst_len] = 0; + git__joinpath(data->dst, data->dst, source + data->src_len); + + if (gitfo_isdir(source) == GIT_SUCCESS) { + if (gitfo_mkdir(data->dst, mode) < GIT_SUCCESS) + return GIT_EOSERR; + + return gitfo_dirent(source, GIT_PATH_MAX, copy_filesystem_element_recurs, _data); + } + + return copy_file(source, data->dst); +} + +int copydir_recurs(char *source_directory_path, char *destination_directory_path) +{ + char source_buffer[GIT_PATH_MAX]; + char dest_buffer[GIT_PATH_MAX]; + copydir_data data; + + /* Source has to exist, Destination hast to _not_ exist */ + if (gitfo_isdir(source_directory_path) || !gitfo_isdir(destination_directory_path)) + return GIT_EINVALIDPATH; + + git__joinpath(source_buffer, source_directory_path, ""); + data.src_len = strlen(source_buffer); + + git__joinpath(dest_buffer, destination_directory_path, ""); + data.dst = dest_buffer; + data.dst_len = strlen(dest_buffer); + + return copy_filesystem_element_recurs(&data, source_buffer); } diff --git a/tests/test_helpers.h b/tests/test_helpers.h index 57152b550..af5a0a908 100644 --- a/tests/test_helpers.h +++ b/tests/test_helpers.h @@ -63,6 +63,7 @@ extern int remove_loose_object(const char *odb_dir, git_object *object); extern int cmp_files(const char *a, const char *b); extern int copy_file(const char *source, const char *dest); extern int rmdir_recurs(char *directory_path); +extern int copydir_recurs(char *source_directory_path, char *destination_directory_path); #endif /* INCLUDE_test_helpers_h__ */