Пример #1
0
int git_indexer_new(
		git_indexer **out,
		const char *prefix,
		unsigned int mode,
		git_odb *odb,
		git_transfer_progress_cb progress_cb,
		void *progress_payload)
{
	git_indexer *idx;
	git_buf path = GIT_BUF_INIT, tmp_path = GIT_BUF_INIT;
	static const char suff[] = "/pack";
	int error, fd = -1;

	idx = (git_indexer *) git__calloc(1, sizeof(git_indexer));
	GITERR_CHECK_ALLOC(idx);
	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->hash_ctx);
	git_hash_ctx_init(&idx->trailer);

	error = git_buf_joinpath(&path, prefix, suff);
	if (error < 0)
		goto cleanup;

	fd = git_futils_mktmp(&tmp_path, git_buf_cstr(&path), idx->mode);
	git_buf_free(&path);
	if (fd < 0)
		goto cleanup;

	error = git_packfile_alloc(&idx->pack, git_buf_cstr(&tmp_path));
	git_buf_free(&tmp_path);

	if (error < 0)
		goto cleanup;

	idx->pack->mwf.fd = fd;
	if ((error = git_mwindow_file_register(&idx->pack->mwf)) < 0)
		goto cleanup;

	*out = idx;
	return 0;

cleanup:
	if (fd != -1)
		p_close(fd);

	git_buf_free(&path);
	git_buf_free(&tmp_path);
	git__free(idx);
	return -1;
}
Пример #2
0
static bool are_symlinks_supported(const char *wd_path)
{
	git_buf path = GIT_BUF_INIT;
	int fd;
	struct stat st;
	int symlinks_supported = -1;

	if ((fd = git_futils_mktmp(&path, wd_path, 0666)) < 0 ||
		p_close(fd) < 0 ||
		p_unlink(path.ptr) < 0 ||
		p_symlink("testing", path.ptr) < 0 ||
		p_lstat(path.ptr, &st) < 0)
		symlinks_supported = false;
	else
		symlinks_supported = (S_ISLNK(st.st_mode) != 0);

	(void)p_unlink(path.ptr);
	git_buf_free(&path);

	return symlinks_supported;
}
Пример #3
0
int git_filebuf_open(git_filebuf *file, const char *path, int flags)
{
	int compression;
	size_t path_len;

	/* opening an already open buffer is a programming error;
	 * assert that this never happens instead of returning
	 * an error code */
	assert(file && path && file->buffer == NULL);

	memset(file, 0x0, sizeof(git_filebuf));

	if (flags & GIT_FILEBUF_DO_NOT_BUFFER)
		file->do_not_buffer = true;

	file->buf_size = WRITE_BUFFER_SIZE;
	file->buf_pos = 0;
	file->fd = -1;
	file->last_error = BUFERR_OK;

	/* Allocate the main cache buffer */
	if (!file->do_not_buffer) {
		file->buffer = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->buffer);
	}

	/* If we are hashing on-write, allocate a new hash context */
	if (flags & GIT_FILEBUF_HASH_CONTENTS) {
		file->digest = git_hash_new_ctx();
		GITERR_CHECK_ALLOC(file->digest);
	}

	compression = flags >> GIT_FILEBUF_DEFLATE_SHIFT;

	/* If we are deflating on-write, */
	if (compression != 0) {
		/* Initialize the ZLib stream */
		if (deflateInit(&file->zs, compression) != Z_OK) {
			giterr_set(GITERR_ZLIB, "Failed to initialize zlib");
			goto cleanup;
		}

		/* Allocate the Zlib cache buffer */
		file->z_buf = git__malloc(file->buf_size);
		GITERR_CHECK_ALLOC(file->z_buf);

		/* Never flush */
		file->flush_mode = Z_NO_FLUSH;
		file->write = &write_deflate;
	} else {
		file->write = &write_normal;
	}

	/* If we are writing to a temp file */
	if (flags & GIT_FILEBUF_TEMPORARY) {
		git_buf tmp_path = GIT_BUF_INIT;

		/* Open the file as temporary for locking */
		file->fd = git_futils_mktmp(&tmp_path, path);

		if (file->fd < 0) {
			git_buf_free(&tmp_path);
			goto cleanup;
		}
		file->fd_is_open = true;

		/* No original path */
		file->path_original = NULL;
		file->path_lock = git_buf_detach(&tmp_path);
		GITERR_CHECK_ALLOC(file->path_lock);
	} else {
		path_len = strlen(path);

		/* Save the original path of the file */
		file->path_original = git__strdup(path);
		GITERR_CHECK_ALLOC(file->path_original);

		/* create the locking path by appending ".lock" to the original */
		file->path_lock = git__malloc(path_len + GIT_FILELOCK_EXTLENGTH);
		GITERR_CHECK_ALLOC(file->path_lock);

		memcpy(file->path_lock, file->path_original, path_len);
		memcpy(file->path_lock + path_len, GIT_FILELOCK_EXTENSION, GIT_FILELOCK_EXTLENGTH);

		/* open the file for locking */
		if (lock_file(file, flags) < 0)
			goto cleanup;
	}

	return 0;

cleanup:
	git_filebuf_cleanup(file);
	return -1;
}