Beispiel #1
0
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;

	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));

	cl_git_pass(p_stat("./testrepo/a", &st));
	cl_assert_equal_i(st.st_mode & 0777, 0701);

	/* File-mode test, since we're on the 'dir' branch */
	cl_git_pass(p_stat("./testrepo/a/b.txt", &st));
	cl_assert_equal_i(st.st_mode & 0777, 0755);

	git_commit_free(commit);
#endif
}
Beispiel #2
0
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);
}
Beispiel #3
0
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);
}
Beispiel #4
0
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
}
Beispiel #5
0
bool cl_toggle_filemode(const char *filename)
{
	struct stat st1, st2;

	cl_must_pass(p_stat(filename, &st1));
	cl_must_pass(p_chmod(filename, st1.st_mode ^ 0100));
	cl_must_pass(p_stat(filename, &st2));

	return (st1.st_mode != st2.st_mode);
}
static bool is_chmod_supported(const char *file_path)
{
	struct stat st1, st2;

	if (p_stat(file_path, &st1) < 0)
		return false;

	if (p_chmod(file_path, st1.st_mode ^ S_IXUSR) < 0)
		return false;

	if (p_stat(file_path, &st2) < 0)
		return false;

	return (st1.st_mode != st2.st_mode);
}
Beispiel #7
0
void test_core_posix__utimes(void)
{
	struct timeval times[2];
	struct stat st;
	time_t curtime;
	int fd;

	/* test p_utimes */
	times[0].tv_sec = 1234567890;
	times[0].tv_usec = 0;
	times[1].tv_sec = 1234567890;
	times[1].tv_usec = 0;

	cl_git_mkfile("foo", "Dummy file.");
	cl_must_pass(p_utimes("foo", times));

	p_stat("foo", &st);
	cl_assert_equal_i(1234567890, st.st_atime);
	cl_assert_equal_i(1234567890, st.st_mtime);


	/* test p_futimes */
	times[0].tv_sec = 1414141414;
	times[0].tv_usec = 0;
	times[1].tv_sec = 1414141414;
	times[1].tv_usec = 0;

	cl_must_pass(fd = p_open("foo", O_RDWR));
	cl_must_pass(p_futimes(fd, times));
	p_close(fd);

	p_stat("foo", &st);
	cl_assert_equal_i(1414141414, st.st_atime);
	cl_assert_equal_i(1414141414, st.st_mtime);


	/* test p_utimes with current time, assume that
	 * it takes < 5 seconds to get the time...!
	 */
	cl_must_pass(p_utimes("foo", NULL));

	curtime = time(NULL);
	p_stat("foo", &st);
	cl_assert((st.st_atime - curtime) < 5);
	cl_assert((st.st_mtime - curtime) < 5);

	p_unlink("foo");
}
Beispiel #8
0
static
int
_isExecutable(const char* path)
{
    struct s_stat st;
    return ((p_stat(path, &st) == 0) && (st.st_mode & _S_IEXEC));
}
Beispiel #9
0
/* 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));
}
Beispiel #10
0
static void hack_index(char *files[])
{
	char *filename;
	struct stat statbuf;
	git_buf path = GIT_BUF_INIT;
	git_index_entry *entry;
	size_t i;

	/* Update the index to suggest that checkout placed these files on
	 * disk, keeping the object id but updating the cache, which will
	 * emulate a Git implementation's different filter.
	 */
	for (i = 0, filename = files[i]; filename; filename = files[++i]) {
		git_buf_clear(&path);

		cl_assert(entry = (git_index_entry *)
			git_index_get_bypath(repo_index, filename, 0));

		cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename));
		cl_git_pass(p_stat(path.ptr, &statbuf));

		entry->ctime.seconds = (git_time_t)statbuf.st_ctime;
		entry->ctime.nanoseconds = 0;
		entry->mtime.seconds = (git_time_t)statbuf.st_mtime;
		entry->mtime.nanoseconds = 0;
		entry->dev = statbuf.st_dev;
		entry->ino = statbuf.st_ino;
		entry->uid  = statbuf.st_uid;
		entry->gid  = statbuf.st_gid;
		entry->file_size = statbuf.st_size;
	}

	git_buf_free(&path);
}
Beispiel #11
0
int git_index_write(git_index *index)
{
	git_filebuf file;
	struct stat indexst;
	int error;

	git_vector_sort(&index->entries);

	if ((error = git_filebuf_open(&file, index->index_file_path, GIT_FILEBUF_HASH_CONTENTS)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to write index");

	if ((error = write_index(index, &file)) < GIT_SUCCESS) {
		git_filebuf_cleanup(&file);
		return git__rethrow(error, "Failed to write index");
	}

	if ((error = git_filebuf_commit(&file)) < GIT_SUCCESS)
		return git__rethrow(error, "Failed to write index");

	if (p_stat(index->index_file_path, &indexst) == 0) {
		index->last_modified = indexst.st_mtime;
		index->on_disk = 1;
	}

	return GIT_SUCCESS;
}
Beispiel #12
0
static int packfile_refresh_all(struct pack_backend *backend)
{
	int error;
	struct stat st;

	if (backend->pack_folder == NULL)
		return GIT_SUCCESS;

	if (p_stat(backend->pack_folder, &st) < 0 || !S_ISDIR(st.st_mode))
		return git__throw(GIT_ENOTFOUND, "Failed to refresh packfiles. Backend not found");

	if (st.st_mtime != backend->pack_folder_mtime) {
		char path[GIT_PATH_MAX];
		strcpy(path, backend->pack_folder);

		/* reload all packs */
		error = git_futils_direach(path, GIT_PATH_MAX, packfile_load__cb, (void *)backend);
		if (error < GIT_SUCCESS)
			return git__rethrow(error, "Failed to refresh packfiles");

		git_vector_sort(&backend->packs);
		backend->pack_folder_mtime = st.st_mtime;
	}

	return GIT_SUCCESS;
}
Beispiel #13
0
static void setup_race(void)
{
	git_buf path = GIT_BUF_INIT;
	git_index *index;
	git_index_entry *entry;
	struct stat st;

	/* Make sure we do have a timestamp */
	cl_git_pass(git_repository_index__weakptr(&index, g_repo));
	cl_git_pass(git_index_write(index));

	cl_git_pass(git_buf_joinpath(&path, git_repository_workdir(g_repo), "A"));

	cl_git_mkfile(path.ptr, "A");
	cl_git_pass(git_index_add_bypath(index, "A"));

	cl_git_mkfile(path.ptr, "B");
	cl_git_pass(git_index_write(index));

	cl_git_mkfile(path.ptr, "");

	cl_git_pass(p_stat(path.ptr, &st));
	cl_assert(entry = (git_index_entry *)git_index_get_bypath(index, "A", 0));

	/* force a race */
	entry->mtime.seconds = (int32_t)st.st_mtime;
	entry->mtime.nanoseconds = (int32_t)st.st_mtime_nsec;

	git_buf_dispose(&path);
}
Beispiel #14
0
void test_index_version__v4_uses_path_compression(void)
{
	git_index_entry entry;
	git_index *index;
	char path[250], buf[1];
	struct stat st;
	char i, j;

	memset(path, 'a', sizeof(path));
	memset(buf, 'a', sizeof(buf));

	memset(&entry, 0, sizeof(entry));
	entry.path = path;
	entry.mode = GIT_FILEMODE_BLOB;

	g_repo = cl_git_sandbox_init("indexv4");
	cl_git_pass(git_repository_index(&index, g_repo));

	/* write 676 paths of 250 bytes length */
	for (i = 'a'; i <= 'z'; i++) {
		for (j = 'a'; j < 'z'; j++) {
			path[ARRAY_SIZE(path) - 3] = i;
			path[ARRAY_SIZE(path) - 2] = j;
			path[ARRAY_SIZE(path) - 1] = '\0';
			cl_git_pass(git_index_add_frombuffer(index, &entry, buf, sizeof(buf)));
		}
	}

	cl_git_pass(git_index_write(index));
	cl_git_pass(p_stat(git_index_path(index), &st));

	/*
	 * Without path compression, the written paths would at
	 * least take
	 *
	 *    (entries * pathlen) = len
	 *    (676 * 250) = 169000
	 *
	 *  bytes. As index v4 uses suffix-compression and our
	 *  written paths only differ in the last two entries,
	 *  this number will be much smaller, e.g.
	 *
	 *    (1 * pathlen) + (675 * 2) = len
	 *    676 + 1350 = 2026
	 *
	 *    bytes.
	 *
	 *    Note that the above calculations do not include
	 *    additional metadata of the index, e.g. OIDs or
	 *    index extensions. Including those we get an index
	 *    of approx. 200kB without compression and 40kB with
	 *    compression. As this is a lot smaller than without
	 *    compression, we can verify that path compression is
	 *    used.
	 */
	cl_assert_(st.st_size < 75000, "path compression not enabled");

	git_index_free(index);
}
Beispiel #15
0
int git_futils_readbuffer_updated(git_fbuffer *obj, const char *path, time_t *mtime, int *updated)
{
	git_file fd;
	size_t len;
	struct stat st;
	unsigned char *buff;

	assert(obj && path && *path);

	if (updated != NULL)
		*updated = 0;

	if (p_stat(path, &st) < 0)
		return git__throw(GIT_ENOTFOUND, "Failed to stat file %s", path);

	if (S_ISDIR(st.st_mode))
		return git__throw(GIT_ERROR, "Can't read a dir into a buffer");

	/*
	 * If we were given a time, we only want to read the file if it
	 * has been modified.
	 */
	if (mtime != NULL && *mtime >= st.st_mtime)
		return GIT_SUCCESS;

	if (mtime != NULL)
		*mtime = st.st_mtime;
	if (!git__is_sizet(st.st_size+1))
		return git__throw(GIT_ERROR, "Failed to read file `%s`. An error occured while calculating its size", path);

	len = (size_t) st.st_size;

	if ((fd = p_open(path, O_RDONLY)) < 0)
		return git__throw(GIT_EOSERR, "Failed to open %s for reading", path);

	if ((buff = git__malloc(len + 1)) == NULL) {
		p_close(fd);
		return GIT_ENOMEM;
	}

	if (p_read(fd, buff, len) < 0) {
		p_close(fd);
		free(buff);
		return git__throw(GIT_ERROR, "Failed to read file `%s`", path);
	}
	buff[len] = '\0';

	p_close(fd);

	if (mtime != NULL)
		*mtime = st.st_mtime;
	if (updated != NULL)
		*updated = 1;

	obj->data = buff;
	obj->len  = len;

	return GIT_SUCCESS;
}
Beispiel #16
0
static bool try_create_file_with_nsec_timestamp(const char *path)
{
	struct stat st;
	int try;

	/* retry a few times to avoid nanos *actually* equal 0 race condition */
	for (try = 0; try < 3; try++) {
		cl_git_mkfile(path, "This is hopefully a file with nanoseconds!");

		cl_must_pass(p_stat(path, &st));

		if (st.st_ctime_nsec && st.st_mtime_nsec)
			return true;
	}

	return false;
}

/* try to determine if the underlying filesystem supports a resolution
 * higher than a single second.  (i'm looking at you, hfs+)
 */
static bool should_expect_nsecs(void)
{
	git_buf nsec_path = GIT_BUF_INIT;
	bool expect;

	git_buf_joinpath(&nsec_path, clar_sandbox_path(), "nsec_test");

	expect = try_create_file_with_nsec_timestamp(nsec_path.ptr);

	p_unlink(nsec_path.ptr);

	git_buf_clear(&nsec_path);

	return expect;
}

static bool has_nsecs(void)
{
	const git_index_entry *entry;
	size_t i;
	bool has_nsecs = false;

	for (i = 0; i < git_index_entrycount(repo_index); i++) {
		entry = git_index_get_byindex(repo_index, i);

		if (entry->ctime.nanoseconds || entry->mtime.nanoseconds) {
			has_nsecs = true;
			break;
		}
	}

	return has_nsecs;
}

void test_index_nsec__has_nanos(void)
{
	cl_assert_equal_b(true, has_nsecs());
}
Beispiel #17
0
bool git_path_isdir(const char *path)
{
	struct stat st;
	if (p_stat(path, &st) < 0)
		return false;

	return S_ISDIR(st.st_mode) != 0;
}
Beispiel #18
0
bool git_path_isfile(const char *path)
{
	struct stat st;

	assert(path);
	if (p_stat(path, &st) < 0)
		return false;

	return S_ISREG(st.st_mode) != 0;
}
Beispiel #19
0
static bool can_link(const char *src, const char *dst, int link)
{
#ifdef GIT_WIN32
	return false;
#else

	struct stat st_src, st_dst;

	if (!link)
		return false;

	if (p_stat(src, &st_src) < 0)
		return false;

	if (p_stat(dst, &st_dst) < 0)
		return false;

	return st_src.st_dev == st_dst.st_dev;
#endif
}
Beispiel #20
0
void test_repo_init__detect_ignorecase(void)
{
	struct stat st;
	bool found_without_match;

	cl_git_write2file("testCAPS", "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
	found_without_match = (p_stat("Testcaps", &st) == 0);
	cl_must_pass(p_unlink("testCAPS"));

	assert_config_entry_on_init(
		"core.ignorecase", found_without_match ? true : GIT_ENOTFOUND);
}
Beispiel #21
0
void test_checkout_index__options_override_file_modes(void)
{
#ifndef GIT_WIN32
	struct stat st;

	g_opts.file_mode = 0700;

	cl_git_pass(git_checkout_index(g_repo, &g_opts));

	cl_git_pass(p_stat("./testrepo/new.txt", &st));
	cl_assert_equal_i(st.st_mode & 0777, 0700);
#endif
}
Beispiel #22
0
void test_checkout_index__options_override_file_modes(void)
{
#ifndef GIT_WIN32
	git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
	struct stat st;

	opts.checkout_strategy = GIT_CHECKOUT_SAFE_CREATE;
	opts.file_mode = 0700;

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

	cl_git_pass(p_stat("./testrepo/new.txt", &st));
	cl_assert_equal_i(st.st_mode & 0777, 0700);
#endif
}
Beispiel #23
0
static void ensure_workdir_mode(const char *path, int mode)
{
#ifndef GIT_WIN32
	git_buf fullpath = GIT_BUF_INIT;
	struct stat st;

	cl_git_pass(
		git_buf_joinpath(&fullpath, git_repository_workdir(g_repo), path));

	cl_git_pass(p_stat(git_buf_cstr(&fullpath), &st));
	cl_assert_equal_i(mode, st.st_mode);

	git_buf_free(&fullpath);
#endif
}
Beispiel #24
0
GIT_INLINE(int) mkdir_validate_dir(
	const char *path,
	struct stat *st,
	mode_t mode,
	uint32_t flags,
	struct git_futils_mkdir_options *opts)
{
	/* with exclusive create, existing dir is an error */
	if ((flags & GIT_MKDIR_EXCL) != 0) {
		giterr_set(GITERR_FILESYSTEM,
			"failed to make directory '%s': directory exists", path);
		return GIT_EEXISTS;
	}

	if ((S_ISREG(st->st_mode) && (flags & GIT_MKDIR_REMOVE_FILES)) ||
		(S_ISLNK(st->st_mode) && (flags & GIT_MKDIR_REMOVE_SYMLINKS))) {
		if (p_unlink(path) < 0) {
			giterr_set(GITERR_OS, "failed to remove %s '%s'",
				S_ISLNK(st->st_mode) ? "symlink" : "file", path);
			return GIT_EEXISTS;
		}

		opts->perfdata.mkdir_calls++;

		if (p_mkdir(path, mode) < 0) {
			giterr_set(GITERR_OS, "failed to make directory '%s'", path);
			return GIT_EEXISTS;
		}
	}

	else if (S_ISLNK(st->st_mode)) {
		/* Re-stat the target, make sure it's a directory */
		opts->perfdata.stat_calls++;

		if (p_stat(path, st) < 0) {
			giterr_set(GITERR_OS, "failed to make directory '%s'", path);
			return GIT_EEXISTS;
		}
	}

	else if (!S_ISDIR(st->st_mode)) {
		giterr_set(GITERR_FILESYSTEM,
			"failed to make directory '%s': directory exists", path);
		return GIT_EEXISTS;
	}

	return 0;
}
Beispiel #25
0
static void hack_index(char *files[])
{
	char *filename;
	struct stat statbuf;
	git_buf path = GIT_BUF_INIT;
	git_index_entry *entry;
	struct timeval times[2];
	time_t now;
	size_t i;

	/* Update the index to suggest that checkout placed these files on
	 * disk, keeping the object id but updating the cache, which will
	 * emulate a Git implementation's different filter.
	 *
	 * We set the file's timestamp to before now to pretend that
	 * it was an old checkout so we don't trigger the racy
	 * protections would would check the content.
	 */

	now = time(NULL);
	times[0].tv_sec  = now - 5;
	times[0].tv_usec = 0;
	times[1].tv_sec  = now - 5;
	times[1].tv_usec = 0;

	for (i = 0, filename = files[i]; filename; filename = files[++i]) {
		git_buf_clear(&path);

		cl_assert(entry = (git_index_entry *)
			git_index_get_bypath(repo_index, filename, 0));

		cl_git_pass(git_buf_printf(&path, "%s/%s", TEST_REPO_PATH, filename));
		cl_git_pass(p_utimes(path.ptr, times));
		cl_git_pass(p_stat(path.ptr, &statbuf));

		entry->ctime.seconds = (git_time_t)statbuf.st_ctime;
		entry->ctime.nanoseconds = 0;
		entry->mtime.seconds = (git_time_t)statbuf.st_mtime;
		entry->mtime.nanoseconds = 0;
		entry->dev = statbuf.st_dev;
		entry->ino = statbuf.st_ino;
		entry->uid  = statbuf.st_uid;
		entry->gid  = statbuf.st_gid;
		entry->file_size = statbuf.st_size;
	}

	git_buf_free(&path);
}
Beispiel #26
0
int git_path_isfile(const char *path)
{
	struct stat st;
	int stat_error;

	assert(path);
	stat_error = p_stat(path, &st);

	if (stat_error < GIT_SUCCESS)
		return -1;

	if (!S_ISREG(st.st_mode))
		return -1;

	return 0;
}
Beispiel #27
0
void test_checkout_index__options_override_file_modes(void)
{
	git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT;
	struct stat st;

	if (!cl_is_chmod_supported())
		return;

	opts.checkout_strategy = GIT_CHECKOUT_SAFE | GIT_CHECKOUT_RECREATE_MISSING;
	opts.file_mode = 0700;

	cl_git_pass(git_checkout_index(g_repo, NULL, &opts));

	cl_git_pass(p_stat("./testrepo/new.txt", &st));
	cl_assert_equal_i_fmt(st.st_mode & GIT_MODE_PERMS_MASK, 0700, "%07o");
}
Beispiel #28
0
void test_repo_init__detect_precompose_unicode_required(void)
{
#ifdef GIT_USE_ICONV
	char *composed = "ḱṷṓn", *decomposed = "ḱṷṓn";
	struct stat st;
	bool found_with_nfd;

	cl_git_write2file(composed, "whatever\n", 0, O_CREAT | O_WRONLY, 0666);
	found_with_nfd = (p_stat(decomposed, &st) == 0);
	cl_must_pass(p_unlink(composed));

	assert_config_entry_on_init("core.precomposeunicode", found_with_nfd);
#else
	assert_config_entry_on_init("core.precomposeunicode", GIT_ENOTFOUND);
#endif
}
Beispiel #29
0
mode_t read_filemode(const char *path)
{
	git_buf fullpath = GIT_BUF_INIT;
	struct stat st;
	mode_t result;

	git_buf_joinpath(&fullpath, "testrepo", path);
	cl_must_pass(p_stat(fullpath.ptr, &st));

	result = GIT_PERMS_IS_EXEC(st.st_mode) ?
		GIT_FILEMODE_BLOB_EXECUTABLE : GIT_FILEMODE_BLOB;

	git_buf_free(&fullpath);

	return result;
}
Beispiel #30
0
int git_path_isdir(const char *path)
{
#ifdef GIT_WIN32
	DWORD attr = GetFileAttributes(path);
	if (attr == INVALID_FILE_ATTRIBUTES)
		return GIT_ERROR;

	return (attr & FILE_ATTRIBUTE_DIRECTORY) ? GIT_SUCCESS : GIT_ERROR;

#else
	struct stat st;
	if (p_stat(path, &st) < GIT_SUCCESS)
		return GIT_ERROR;

	return S_ISDIR(st.st_mode) ? GIT_SUCCESS : GIT_ERROR;
#endif
}