int git_futils_mktmp(git_buf *path_out, const char *filename, mode_t mode) { int fd; mode_t mask; p_umask(mask = p_umask(0)); git_buf_sets(path_out, filename); git_buf_puts(path_out, "_git2_XXXXXX"); if (git_buf_oom(path_out)) return -1; if ((fd = p_mkstemp(path_out->ptr)) < 0) { giterr_set(GITERR_OS, "Failed to create temporary file '%s'", path_out->ptr); return -1; } if (p_chmod(path_out->ptr, (mode & ~mask))) { giterr_set(GITERR_OS, "Failed to set permissions on file '%s'", path_out->ptr); return -1; } return fd; }
void test_write_object_permission( mode_t dir_mode, mode_t file_mode, mode_t expected_dir_mode, mode_t expected_file_mode) { git_odb *odb; git_odb_backend *backend; git_oid oid; struct stat statbuf; mode_t mask, os_mask; /* 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(git_odb_new(&odb)); cl_git_pass(git_odb_backend_loose(&backend, "test-objects", -1, 0, dir_mode, file_mode)); cl_git_pass(git_odb_add_backend(odb, backend, 1)); cl_git_pass(git_odb_write(&oid, odb, "Test data\n", 10, GIT_OBJECT_BLOB)); cl_git_pass(p_stat("test-objects/67", &statbuf)); cl_assert_equal_i(statbuf.st_mode & os_mask, (expected_dir_mode & ~mask) & os_mask); cl_git_pass(p_stat("test-objects/67/b808feb36201507a77f85e6d898f0a2836e4a5", &statbuf)); cl_assert_equal_i(statbuf.st_mode & os_mask, (expected_file_mode & ~mask) & os_mask); git_odb_free(odb); }
void test_checkout_index__options_dir_modes(void) { #ifndef GIT_WIN32 git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT; struct stat st; git_oid oid; git_commit *commit; mode_t um; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); reset_index_to_treeish((git_object *)commit); opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE; opts.dir_mode = 0701; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); /* umask will influence actual directory creation mode */ (void)p_umask(um = p_umask(022)); cl_git_pass(p_stat("./testrepo/a", &st)); cl_assert_equal_i_fmt(st.st_mode, (GIT_FILEMODE_TREE | 0701) & ~um, "%07o"); /* File-mode test, since we're on the 'dir' branch */ cl_git_pass(p_stat("./testrepo/a/b.txt", &st)); cl_assert_equal_i_fmt(st.st_mode, GIT_FILEMODE_BLOB_EXECUTABLE, "%07o"); git_commit_free(commit); #endif }
void test_checkout_index__options_dir_modes(void) { git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; struct stat st; git_oid oid; git_commit *commit; mode_t um; if (!cl_is_chmod_supported()) return; cl_git_pass(git_reference_name_to_id(&oid, g_repo, "refs/heads/dir")); cl_git_pass(git_commit_lookup(&commit, g_repo, &oid)); reset_index_to_treeish((git_object *)commit); opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING; opts.dir_mode = 0701; cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); /* umask will influence actual directory creation mode */ (void)p_umask(um = p_umask(022)); cl_git_pass(p_stat("./testrepo/a", &st)); /* Haiku & Hurd use other mode bits, so we must mask them out */ cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), (GIT_FILEMODE_TREE | 0701) & ~um, "%07o"); /* File-mode test, since we're on the 'dir' branch */ cl_git_pass(p_stat("./testrepo/a/b.txt", &st)); cl_assert_equal_i_fmt(st.st_mode & (S_IFMT | 07777), GIT_FILEMODE_BLOB_EXECUTABLE & ~um, "%07o"); git_commit_free(commit); }
/* 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, 0666)); 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)); 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)); }
void test_repo_init__initialize(void) { _repo = NULL; /* load umask if not already loaded */ if (!g_umask) { g_umask = p_umask(022); (void)p_umask(g_umask); } }
void test_repo_init__initialize(void) { _repo = NULL; /* load umask if not already loaded */ if (!g_umask) { g_umask = p_umask(022); (void)p_umask(g_umask); } git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &_global_path); }
void test_core_mkdir__chmods(void) { struct stat st; mode_t *old = git__malloc(sizeof(mode_t)); *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_git_pass(git_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_path_lstat("r/mode/is/important", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_futils_mkdir("mode2/is2/important2", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD)); cl_git_pass(git_path_lstat("r/mode2", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_path_lstat("r/mode2/is2", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_path_lstat("r/mode2/is2/important2", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_futils_mkdir("mode3/is3/important3", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH)); cl_git_pass(git_path_lstat("r/mode3", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_path_lstat("r/mode3/is3", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_path_lstat("r/mode3/is3/important3", &st)); check_mode(0777, st.st_mode); /* test that we chmod existing dir */ cl_git_pass(git_futils_mkdir("mode/is/important", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD)); cl_git_pass(git_path_lstat("r/mode", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_path_lstat("r/mode/is", &st)); check_mode(0755, st.st_mode); cl_git_pass(git_path_lstat("r/mode/is/important", &st)); check_mode(0777, st.st_mode); /* test that we chmod even existing dirs if CHMOD_PATH is set */ cl_git_pass(git_futils_mkdir("mode2/is2/important2.1", "r", 0777, GIT_MKDIR_PATH | GIT_MKDIR_CHMOD_PATH)); cl_git_pass(git_path_lstat("r/mode2", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_path_lstat("r/mode2/is2", &st)); check_mode(0777, st.st_mode); cl_git_pass(git_path_lstat("r/mode2/is2/important2.1", &st)); check_mode(0777, st.st_mode); }
static void cleanup_chmod_root(void *ref) { mode_t *mode = ref; if (*mode != 0) { (void)p_umask(*mode); git__free(mode); } git_futils_rmdir_r("r", NULL, GIT_RMDIR_EMPTY_HIERARCHY); }
int main(int GIT_UNUSED(argc), char *GIT_UNUSED(argv[])) { unsigned int i, failures; GIT_UNUSED_ARG(argc); GIT_UNUSED_ARG(argv); p_umask(0); failures = 0; for (i = 0; i < GIT_SUITE_COUNT; ++i) failures += git_testsuite_run(suite_methods[i]()); return failures ? -1 : 0; }