From 1e60e5f42dbcf081ac7eece12a5eebab5871636f Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 7 Nov 2013 12:03:44 -0500 Subject: [PATCH] Allow callers to set mode on packfile creation --- include/git2/indexer.h | 2 ++ include/git2/pack.h | 2 ++ src/indexer.c | 7 +++-- src/odb_pack.c | 2 +- src/pack-objects.c | 3 ++- tests-clar/pack/indexer.c | 6 ++--- tests-clar/pack/packbuilder.c | 50 ++++++++++++++++++++++++++++++++--- 7 files changed, 62 insertions(+), 10 deletions(-) diff --git a/include/git2/indexer.h b/include/git2/indexer.h index fb55672a9..e4c03ad06 100644 --- a/include/git2/indexer.h +++ b/include/git2/indexer.h @@ -20,6 +20,7 @@ typedef struct git_indexer git_indexer; * * @param out where to store the indexer instance * @param path to the directory where the packfile should be stored + * @param mode permissions to use creating packfile or 0 for defaults * @param odb object database from which to read base objects when * fixing thin packs. Pass NULL if no thin pack is expected (an error * will be returned if there are bases missing) @@ -29,6 +30,7 @@ typedef struct git_indexer git_indexer; GIT_EXTERN(int) git_indexer_new( git_indexer **out, const char *path, + unsigned int mode, git_odb *odb, git_transfer_progress_callback progress_cb, void *progress_cb_payload); diff --git a/include/git2/pack.h b/include/git2/pack.h index 4632699d1..52e7adad2 100644 --- a/include/git2/pack.h +++ b/include/git2/pack.h @@ -119,6 +119,7 @@ GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid * * @param pb The packbuilder * @param path to the directory where the packfile and index should be stored + * @param mode permissions to use creating a packfile or 0 for defaults * @param progress_cb function to call with progress information from the indexer (optional) * @param progress_cb_payload payload for the progress callback (optional) * @@ -127,6 +128,7 @@ GIT_EXTERN(int) git_packbuilder_insert_commit(git_packbuilder *pb, const git_oid GIT_EXTERN(int) git_packbuilder_write( git_packbuilder *pb, const char *path, + unsigned int mode, git_transfer_progress_callback progress_cb, void *progress_cb_payload); diff --git a/src/indexer.c b/src/indexer.c index 90fb52187..df1ce7cfb 100644 --- a/src/indexer.c +++ b/src/indexer.c @@ -37,6 +37,7 @@ struct git_indexer { struct git_pack_header hdr; struct git_pack_file *pack; git_filebuf pack_file; + unsigned int mode; git_off_t off; git_off_t entry_start; git_packfile_stream stream; @@ -119,6 +120,7 @@ static int objects_cmp(const void *a, const void *b) int git_indexer_new( git_indexer **out, const char *prefix, + unsigned int mode, git_odb *odb, git_transfer_progress_callback progress_cb, void *progress_payload) @@ -133,6 +135,7 @@ int git_indexer_new( idx->odb = odb; idx->progress_cb = progress_cb; idx->progress_payload = progress_payload; + idx->mode = mode ? mode : GIT_PACK_FILE_MODE; git_hash_ctx_init(&idx->trailer); error = git_buf_joinpath(&path, prefix, suff); @@ -141,7 +144,7 @@ int git_indexer_new( error = git_filebuf_open(&idx->pack_file, path.ptr, GIT_FILEBUF_TEMPORARY | GIT_FILEBUF_DO_NOT_BUFFER, - GIT_PACK_FILE_MODE); + idx->mode); git_buf_free(&path); if (error < 0) goto cleanup; @@ -905,7 +908,7 @@ int git_indexer_commit(git_indexer *idx, git_transfer_progress *stats) return -1; if (git_filebuf_open(&index_file, filename.ptr, - GIT_FILEBUF_HASH_CONTENTS, GIT_PACK_FILE_MODE) < 0) + GIT_FILEBUF_HASH_CONTENTS, idx->mode) < 0) goto on_error; /* Write out the header */ diff --git a/src/odb_pack.c b/src/odb_pack.c index 12f4591ec..fd2ca0fd8 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -558,7 +558,7 @@ static int pack_backend__writepack(struct git_odb_writepack **out, GITERR_CHECK_ALLOC(writepack); if (git_indexer_new(&writepack->indexer, - backend->pack_folder, odb, progress_cb, progress_payload) < 0) { + backend->pack_folder, 0, odb, progress_cb, progress_payload) < 0) { git__free(writepack); return -1; } diff --git a/src/pack-objects.c b/src/pack-objects.c index 91811b954..9967cab1f 100644 --- a/src/pack-objects.c +++ b/src/pack-objects.c @@ -1248,6 +1248,7 @@ static int write_cb(void *buf, size_t len, void *payload) int git_packbuilder_write( git_packbuilder *pb, const char *path, + unsigned int mode, git_transfer_progress_callback progress_cb, void *progress_cb_payload) { @@ -1258,7 +1259,7 @@ int git_packbuilder_write( PREPARE_PACK; if (git_indexer_new( - &indexer, path, pb->odb, progress_cb, progress_cb_payload) < 0) + &indexer, path, mode, pb->odb, progress_cb, progress_cb_payload) < 0) return -1; ctx.indexer = indexer; diff --git a/tests-clar/pack/indexer.c b/tests-clar/pack/indexer.c index d7953300f..07963a9e7 100644 --- a/tests-clar/pack/indexer.c +++ b/tests-clar/pack/indexer.c @@ -48,7 +48,7 @@ void test_pack_indexer__out_of_order(void) git_indexer *idx; git_transfer_progress stats; - cl_git_pass(git_indexer_new(&idx, ".", NULL, NULL, NULL)); + cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL)); cl_git_pass(git_indexer_append(idx, out_of_order_pack, out_of_order_pack_len, &stats)); cl_git_pass(git_indexer_commit(idx, &stats)); @@ -75,7 +75,7 @@ void test_pack_indexer__fix_thin(void) git_oid_fromstr(&should_id, "e68fe8129b546b101aee9510c5328e7f21ca1d18"); cl_assert(!git_oid_cmp(&id, &should_id)); - cl_git_pass(git_indexer_new(&idx, ".", odb, NULL, NULL)); + cl_git_pass(git_indexer_new(&idx, ".", 0, odb, NULL, NULL)); cl_git_pass(git_indexer_append(idx, thin_pack, thin_pack_len, &stats)); cl_git_pass(git_indexer_commit(idx, &stats)); @@ -108,7 +108,7 @@ void test_pack_indexer__fix_thin(void) cl_git_pass(p_stat(name, &st)); - cl_git_pass(git_indexer_new(&idx, ".", NULL, NULL, NULL)); + cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL)); read = p_read(fd, buffer, sizeof(buffer)); cl_assert(read != -1); p_close(fd); diff --git a/tests-clar/pack/packbuilder.c b/tests-clar/pack/packbuilder.c index dd028a143..54d1e8022 100644 --- a/tests-clar/pack/packbuilder.c +++ b/tests-clar/pack/packbuilder.c @@ -1,5 +1,6 @@ #include "clar_libgit2.h" #include "fileops.h" +#include "pack.h" #include "hash.h" #include "iterator.h" #include "vector.h" @@ -92,7 +93,7 @@ void test_pack_packbuilder__create_pack(void) seed_packbuilder(); - cl_git_pass(git_indexer_new(&_indexer, ".", NULL, NULL, NULL)); + cl_git_pass(git_indexer_new(&_indexer, ".", 0, NULL, NULL, NULL)); cl_git_pass(git_packbuilder_foreach(_packbuilder, feed_indexer, &stats)); cl_git_pass(git_indexer_commit(_indexer, &stats)); @@ -134,12 +135,55 @@ void test_pack_packbuilder__get_hash(void) seed_packbuilder(); - git_packbuilder_write(_packbuilder, ".", NULL, NULL); + git_packbuilder_write(_packbuilder, ".", 0, NULL, NULL); git_oid_fmt(hex, git_packbuilder_hash(_packbuilder)); cl_assert_equal_s(hex, "80e61eb315239ef3c53033e37fee43b744d57122"); } +static void test_write_pack_permission(mode_t given, mode_t expected) +{ + struct stat statbuf; + mode_t mask, os_mask; + + seed_packbuilder(); + + git_packbuilder_write(_packbuilder, ".", given, NULL, NULL); + + /* Windows does not return group/user bits from stat, + * files are never executable. + */ +#ifdef GIT_WIN32 + os_mask = 0600; +#else + os_mask = 0777; +#endif + + mask = p_umask(0); + p_umask(mask); + + cl_git_pass(p_stat("pack-80e61eb315239ef3c53033e37fee43b744d57122.idx", &statbuf)); + cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask); + + cl_git_pass(p_stat("pack-80e61eb315239ef3c53033e37fee43b744d57122.pack", &statbuf)); + cl_assert_equal_i(statbuf.st_mode & os_mask, (expected & ~mask) & os_mask); +} + +void test_pack_packbuilder__permissions_standard(void) +{ + test_write_pack_permission(0, GIT_PACK_FILE_MODE); +} + +void test_pack_packbuilder__permissions_readonly(void) +{ + test_write_pack_permission(0444, 0444); +} + +void test_pack_packbuilder__permissions_readwrite(void) +{ + test_write_pack_permission(0666, 0666); +} + static git_transfer_progress stats; static int foreach_cb(void *buf, size_t len, void *payload) { @@ -153,7 +197,7 @@ void test_pack_packbuilder__foreach(void) git_indexer *idx; seed_packbuilder(); - cl_git_pass(git_indexer_new(&idx, ".", NULL, NULL, NULL)); + cl_git_pass(git_indexer_new(&idx, ".", 0, NULL, NULL, NULL)); cl_git_pass(git_packbuilder_foreach(_packbuilder, foreach_cb, idx)); cl_git_pass(git_indexer_commit(idx, &stats)); git_indexer_free(idx);