diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h index d3dd733a8..4d772cab9 100644 --- a/include/git2/odb_backend.h +++ b/include/git2/odb_backend.h @@ -50,8 +50,8 @@ GIT_EXTERN(int) git_odb_backend_loose( const char *objects_dir, int compression_level, int do_fsync, - mode_t dir_mode, - mode_t file_mode); + unsigned int dir_mode, + unsigned int file_mode); /** * Create a backend out of a single packfile diff --git a/src/filebuf.c b/src/filebuf.c index 714a32395..de2944bbc 100644 --- a/src/filebuf.c +++ b/src/filebuf.c @@ -320,9 +320,13 @@ int git_filebuf_commit_at(git_filebuf *file, const char *path, mode_t mode) int git_filebuf_commit(git_filebuf *file, mode_t mode) { + mode_t mask; + /* temporary files cannot be committed */ assert(file && file->path_original); + p_umask(mask = p_umask(0)); + file->flush_mode = Z_FINISH; flush_buffer(file); @@ -338,7 +342,7 @@ int git_filebuf_commit(git_filebuf *file, mode_t mode) file->fd = -1; - if (p_chmod(file->path_lock, mode)) { + if (p_chmod(file->path_lock, (mode & ~mask))) { giterr_set(GITERR_OS, "Failed to set attributes for file at '%s'", file->path_lock); goto on_error; } diff --git a/src/odb_loose.c b/src/odb_loose.c index 0dfd78aee..3e52edf05 100644 --- a/src/odb_loose.c +++ b/src/odb_loose.c @@ -902,8 +902,8 @@ int git_odb_backend_loose( const char *objects_dir, int compression_level, int do_fsync, - mode_t dir_mode, - mode_t file_mode) + unsigned int dir_mode, + unsigned int file_mode) { loose_backend *backend; size_t objects_dirlen; diff --git a/tests-clar/core/filebuf.c b/tests-clar/core/filebuf.c index bf2167057..646d42c6e 100644 --- a/tests-clar/core/filebuf.c +++ b/tests-clar/core/filebuf.c @@ -90,3 +90,37 @@ void test_core_filebuf__5(void) cl_must_pass(p_unlink(test)); } + + +/* make sure git_filebuf_commit takes umask into account */ +void test_core_filebuf__umask(void) +{ + git_filebuf file = GIT_FILEBUF_INIT; + char test[] = "test"; + struct stat statbuf; + mode_t mask, os_mask; + +#ifdef GIT_WIN32 + os_mask = 0600; +#else + os_mask = 0777; +#endif + + p_umask(mask = p_umask(0)); + + cl_assert(file.buffer == NULL); + + cl_git_pass(git_filebuf_open(&file, test, 0)); + cl_assert(file.buffer != NULL); + cl_git_pass(git_filebuf_printf(&file, "%s\n", "libgit2 rocks")); + cl_assert(file.buffer != NULL); + + cl_git_pass(git_filebuf_commit(&file, 0666)); + cl_assert(file.buffer == NULL); + + cl_must_pass(p_stat("test", &statbuf)); + cl_assert_equal_i(statbuf.st_mode & os_mask, (0666 & ~mask) & os_mask); + + cl_must_pass(p_unlink(test)); +} +