Пример #1
0
int finish_connect(struct child_process *conn)
{
	int code;
	if (!conn || git_connection_is_socket(conn))
		return 0;

	code = finish_command(conn);
	free(conn);
	return code;
}
Пример #2
0
static void subprocess_exit_handler(struct child_process *process)
{
	sigchain_push(SIGPIPE, SIG_IGN);
	/* Closing the pipe signals the subprocess to initiate a shutdown. */
	close(process->in);
	close(process->out);
	sigchain_pop(SIGPIPE);
	/* Finish command will wait until the shutdown is complete. */
	finish_command(process);
}
Пример #3
0
static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
{
	const char *svc = rpc->service_name;
	struct strbuf buf = STRBUF_INIT;
	struct child_process client;
	int err = 0;

	memset(&client, 0, sizeof(client));
	client.in = -1;
	client.out = -1;
	client.git_cmd = 1;
	client.argv = rpc->argv;
	if (start_command(&client))
		exit(1);
	if (heads)
		write_or_die(client.in, heads->buf, heads->len);

	rpc->alloc = http_post_buffer;
	rpc->buf = xmalloc(rpc->alloc);
	rpc->in = client.in;
	rpc->out = client.out;
	strbuf_init(&rpc->result, 0);

	strbuf_addf(&buf, "%s%s", url, svc);
	rpc->service_url = strbuf_detach(&buf, NULL);

	strbuf_addf(&buf, "Content-Type: application/x-%s-request", svc);
	rpc->hdr_content_type = strbuf_detach(&buf, NULL);

	strbuf_addf(&buf, "Accept: application/x-%s-result", svc);
	rpc->hdr_accept = strbuf_detach(&buf, NULL);

	while (!err) {
		int n = packet_read_line(rpc->out, rpc->buf, rpc->alloc);
		if (!n)
			break;
		rpc->pos = 0;
		rpc->len = n;
		err |= post_rpc(rpc);
	}
	strbuf_read(&rpc->result, client.out, 0);

	close(client.in);
	close(client.out);
	client.in = -1;
	client.out = -1;

	err |= finish_command(&client);
	free(rpc->service_url);
	free(rpc->hdr_content_type);
	free(rpc->hdr_accept);
	free(rpc->buf);
	strbuf_release(&buf);
	return err;
}
Пример #4
0
/*
 * Make a pack stream and spit it out into file descriptor fd
 */
static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *extra, struct send_pack_args *args)
{
	/*
	 * The child becomes pack-objects --revs; we feed
	 * the revision parameters to it via its stdin and
	 * let its stdout go back to the other end.
	 */
	const char *argv[] = {
		"pack-objects",
		"--all-progress",
		"--revs",
		"--stdout",
		NULL,
		NULL,
		NULL,
	};
	struct child_process po;
	int i;

	i = 4;
	if (args->use_thin_pack)
		argv[i++] = "--thin";
	if (args->use_ofs_delta)
		argv[i++] = "--delta-base-offset";
	memset(&po, 0, sizeof(po));
	po.argv = argv;
	po.in = -1;
	po.out = fd;
	po.git_cmd = 1;
	if (start_command(&po))
		die_errno("git pack-objects failed");

	/*
	 * We feed the pack-objects we just spawned with revision
	 * parameters by writing to the pipe.
	 */
	for (i = 0; i < extra->nr; i++)
		if (!feed_object(extra->array[i], po.in, 1))
			break;

	while (refs) {
		if (!is_null_sha1(refs->old_sha1) &&
		    !feed_object(refs->old_sha1, po.in, 1))
			break;
		if (!is_null_sha1(refs->new_sha1) &&
		    !feed_object(refs->new_sha1, po.in, 0))
			break;
		refs = refs->next;
	}

	close(po.in);
	if (finish_command(&po))
		return error("pack-objects died with strange error");
	return 0;
}
Пример #5
0
/*
 * Run "gpg" to see if the payload matches the detached signature.
 * gpg_output, when set, receives the diagnostic output from GPG.
 * gpg_status, when set, receives the status output from GPG.
 */
int verify_signed_buffer(const char *payload, size_t payload_size,
			 const char *signature, size_t signature_size,
			 struct strbuf *gpg_output, struct strbuf *gpg_status)
{
	struct child_process gpg = CHILD_PROCESS_INIT;
	const char *args_gpg[] = {NULL, "--status-fd=1", "--verify", "FILE", "-", NULL};
	char path[PATH_MAX];
	int fd, ret;
	struct strbuf buf = STRBUF_INIT;
	struct strbuf *pbuf = &buf;

	args_gpg[0] = gpg_program;
	fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX");
	if (fd < 0)
		return error(_("could not create temporary file '%s': %s"),
			     path, strerror(errno));
	if (write_in_full(fd, signature, signature_size) < 0)
		return error(_("failed writing detached signature to '%s': %s"),
			     path, strerror(errno));
	close(fd);

	gpg.argv = args_gpg;
	gpg.in = -1;
	gpg.out = -1;
	if (gpg_output)
		gpg.err = -1;
	args_gpg[3] = path;
	if (start_command(&gpg)) {
		unlink(path);
		return error(_("could not run gpg."));
	}

	sigchain_push(SIGPIPE, SIG_IGN);
	write_in_full(gpg.in, payload, payload_size);
	close(gpg.in);

	if (gpg_output) {
		strbuf_read(gpg_output, gpg.err, 0);
		close(gpg.err);
	}
	if (gpg_status)
		pbuf = gpg_status;
	strbuf_read(pbuf, gpg.out, 0);
	close(gpg.out);

	ret = finish_command(&gpg);
	sigchain_pop(SIGPIPE);

	unlink_or_warn(path);

	ret |= !strstr(pbuf->buf, "\n[GNUPG:] GOODSIG ");
	strbuf_release(&buf); /* no matter it was used or not */

	return ret;
}
Пример #6
0
void subprocess_stop(struct hashmap *hashmap, struct subprocess_entry *entry)
{
	if (!entry)
		return;

	entry->process.clean_on_exit = 0;
	kill(entry->process.pid, SIGTERM);
	finish_command(&entry->process);

	hashmap_remove(hashmap, entry, NULL);
}
Пример #7
0
static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
{
	struct child_process proc = CHILD_PROCESS_INIT;
	struct async muxer;
	const char *argv[2];
	int code;

	argv[0] = find_hook(hook_name);
	if (!argv[0])
		return 0;

	argv[1] = NULL;

	proc.argv = argv;
	proc.in = -1;
	proc.stdout_to_stderr = 1;

	if (use_sideband) {
		memset(&muxer, 0, sizeof(muxer));
		muxer.proc = copy_to_sideband;
		muxer.in = -1;
		code = start_async(&muxer);
		if (code)
			return code;
		proc.err = muxer.in;
	}

	prepare_push_cert_sha1(&proc);

	code = start_command(&proc);
	if (code) {
		if (use_sideband)
			finish_async(&muxer);
		return code;
	}

	sigchain_push(SIGPIPE, SIG_IGN);

	while (1) {
		const char *buf;
		size_t n;
		if (feed(feed_state, &buf, &n))
			break;
		if (write_in_full(proc.in, buf, n) != n)
			break;
	}
	close(proc.in);
	if (use_sideband)
		finish_async(&muxer);

	sigchain_pop(SIGPIPE);

	return finish_command(&proc);
}
Пример #8
0
int finish_connect(struct child_process *conn)
{
	int code;
	if (!conn || conn == &no_fork)
		return 0;

	code = finish_command(conn);
	free(conn->argv);
	free(conn);
	return code;
}
Пример #9
0
static void changed_files(struct hashmap *result, const char *index_path,
			  const char *workdir)
{
	struct child_process update_index = CHILD_PROCESS_INIT;
	struct child_process diff_files = CHILD_PROCESS_INIT;
	struct strbuf index_env = STRBUF_INIT, buf = STRBUF_INIT;
	const char *git_dir = absolute_path(get_git_dir()), *env[] = {
		NULL, NULL
	};
	FILE *fp;

	strbuf_addf(&index_env, "GIT_INDEX_FILE=%s", index_path);
	env[0] = index_env.buf;

	argv_array_pushl(&update_index.args,
			 "--git-dir", git_dir, "--work-tree", workdir,
			 "update-index", "--really-refresh", "-q",
			 "--unmerged", NULL);
	update_index.no_stdin = 1;
	update_index.no_stdout = 1;
	update_index.no_stderr = 1;
	update_index.git_cmd = 1;
	update_index.use_shell = 0;
	update_index.clean_on_exit = 1;
	update_index.dir = workdir;
	update_index.env = env;
	/* Ignore any errors of update-index */
	run_command(&update_index);

	argv_array_pushl(&diff_files.args,
			 "--git-dir", git_dir, "--work-tree", workdir,
			 "diff-files", "--name-only", "-z", NULL);
	diff_files.no_stdin = 1;
	diff_files.git_cmd = 1;
	diff_files.use_shell = 0;
	diff_files.clean_on_exit = 1;
	diff_files.out = -1;
	diff_files.dir = workdir;
	diff_files.env = env;
	if (start_command(&diff_files))
		die("could not obtain raw diff");
	fp = xfdopen(diff_files.out, "r");
	while (!strbuf_getline_nul(&buf, fp)) {
		struct path_entry *entry;
		FLEX_ALLOC_STR(entry, path, buf.buf);
		hashmap_entry_init(entry, strhash(buf.buf));
		hashmap_add(result, entry);
	}
	fclose(fp);
	if (finish_command(&diff_files))
		die("diff-files did not exit properly");
	strbuf_release(&index_env);
	strbuf_release(&buf);
}
Пример #10
0
int cmd_upload_archive(int argc, const char **argv, const char *prefix)
{
	struct child_process writer = { argv };

	/*
	 * Set up sideband subprocess.
	 *
	 * We (parent) monitor and read from child, sending its fd#1 and fd#2
	 * multiplexed out to our fd#1.  If the child dies, we tell the other
	 * end over channel #3.
	 */
	argv[0] = "upload-archive--writer";
	writer.out = writer.err = -1;
	writer.git_cmd = 1;
	if (start_command(&writer)) {
		int err = errno;
		packet_write(1, "NACK unable to spawn subprocess\n");
		die("upload-archive: %s", strerror(err));
	}

	packet_write(1, "ACK\n");
	packet_flush(1);

	while (1) {
		struct pollfd pfd[2];

		pfd[0].fd = writer.out;
		pfd[0].events = POLLIN;
		pfd[1].fd = writer.err;
		pfd[1].events = POLLIN;
		if (poll(pfd, 2, -1) < 0) {
			if (errno != EINTR) {
				error("poll failed resuming: %s",
				      strerror(errno));
				sleep(1);
			}
			continue;
		}
		if (pfd[1].revents & POLLIN)
			/* Status stream ready */
			if (process_input(pfd[1].fd, 2))
				continue;
		if (pfd[0].revents & POLLIN)
			/* Data stream ready */
			if (process_input(pfd[0].fd, 1))
				continue;

		if (finish_command(&writer))
			error_clnt("%s", deadchild);
		packet_flush(1);
		break;
	}
	return 0;
}
Пример #11
0
static int run_credential_helper(struct credential *c,
				 const char *cmd,
				 int want_output)
{
	struct child_process helper = CHILD_PROCESS_INIT;
	const char *argv[] = { NULL, NULL };
	FILE *fp;

	argv[0] = cmd;
	helper.argv = argv;
	helper.use_shell = 1;
	helper.in = -1;
	if (want_output)
		helper.out = -1;
	else
		helper.no_stdout = 1;

	if (start_command(&helper) < 0)
		return -1;

	fp = xfdopen(helper.in, "w");
	sigchain_push(SIGPIPE, SIG_IGN);
	credential_write(c, fp);
	fclose(fp);
	sigchain_pop(SIGPIPE);

	if (want_output) {
		int r;
		fp = xfdopen(helper.out, "r");
		r = credential_read(c, fp);
		fclose(fp);
		if (r < 0) {
			finish_command(&helper);
			return -1;
		}
	}

	if (finish_command(&helper))
		return -1;
	return 0;
}
Пример #12
0
static char *shell_prompt(const char *prompt, int echo)
{
	const char *read_input[] = {
		/* Note: call 'bash' explicitly, as 'read -s' is bash-specific */
		"bash", "-c", echo ?
		"test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&"
		" read -r line </dev/tty && echo \"$line\"" :
		"test \"a$SHELL\" != \"a${SHELL%.exe}\" || exit 127; cat >/dev/tty &&"
		" read -r -s line </dev/tty && echo \"$line\" && echo >/dev/tty",
		NULL
	};
	struct child_process child = CHILD_PROCESS_INIT;
	static struct strbuf buffer = STRBUF_INIT;
	int prompt_len = strlen(prompt), len = -1, code;

	child.argv = read_input;
	child.in = -1;
	child.out = -1;
	child.silent_exec_failure = 1;

	if (start_command(&child))
		return NULL;

	if (write_in_full(child.in, prompt, prompt_len) != prompt_len) {
		error("could not write to prompt script");
		close(child.in);
		goto ret;
	}
	close(child.in);

	strbuf_reset(&buffer);
	len = strbuf_read(&buffer, child.out, 1024);
	if (len < 0) {
		error("could not read from prompt script");
		goto ret;
	}

	strbuf_strip_suffix(&buffer, "\n");
	strbuf_strip_suffix(&buffer, "\r");

ret:
	close(child.out);
	code = finish_command(&child);
	if (code) {
		if (code != 127)
			error("failed to execute prompt script (exit code %d)",
			      code);

		return NULL;
	}

	return len < 0 ? NULL : buffer.buf;
}
Пример #13
0
int run_command(struct child_process *cmd)
{
	int code;

	if (cmd->out < 0 || cmd->err < 0)
		die("BUG: run_command with a pipe can cause deadlock");

	code = start_command(cmd);
	if (code)
		return code;
	return finish_command(cmd);
}
Пример #14
0
static int run_credential_helper(struct credential *c,
				 const char *cmd,
				 int want_output)
{
	struct child_process helper;
	const char *argv[] = { NULL, NULL };
	FILE *fp;

	memset(&helper, 0, sizeof(helper));
	argv[0] = cmd;
	helper.argv = argv;
	helper.use_shell = 1;
	helper.in = -1;
	if (want_output)
		helper.out = -1;
	else
		helper.no_stdout = 1;

	if (start_command(&helper) < 0)
		return -1;

	fp = xfdopen(helper.in, "w");
	credential_write(c, fp);
	fclose(fp);

	if (want_output) {
		int r;
		fp = xfdopen(helper.out, "r");
		r = credential_read(c, fp);
		fclose(fp);
		if (r < 0) {
			finish_command(&helper);
			return -1;
		}
	}

	if (finish_command(&helper))
		return -1;
	return 0;
}
Пример #15
0
int stop_column_filter(void)
{
	if (fd_out == -1)
		return -1;

	fflush(stdout);
	close(1);
	finish_command(&column_process);
	dup2(fd_out, 1);
	close(fd_out);
	fd_out = -1;
	return 0;
}
Пример #16
0
int is_submodule_modified(const char *path)
{
	int len, i;
	struct child_process cp;
	const char *argv[] = {
		"status",
		"--porcelain",
		NULL,
	};
	const char *env[LOCAL_REPO_ENV_SIZE + 3];
	struct strbuf buf = STRBUF_INIT;

	for (i = 0; i < LOCAL_REPO_ENV_SIZE; i++)
		env[i] = local_repo_env[i];

	strbuf_addf(&buf, "%s/.git/", path);
	if (!is_directory(buf.buf)) {
		strbuf_release(&buf);
		/* The submodule is not checked out, so it is not modified */
		return 0;

	}
	strbuf_reset(&buf);

	strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
	env[i++] = strbuf_detach(&buf, NULL);
	strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
	env[i++] = strbuf_detach(&buf, NULL);
	env[i] = NULL;

	memset(&cp, 0, sizeof(cp));
	cp.argv = argv;
	cp.env = env;
	cp.git_cmd = 1;
	cp.no_stdin = 1;
	cp.out = -1;
	if (start_command(&cp))
		die("Could not run git status --porcelain");

	len = strbuf_read(&buf, cp.out, 1024);
	close(cp.out);

	if (finish_command(&cp))
		die("git status --porcelain failed");

	for (i = LOCAL_REPO_ENV_SIZE; env[i]; i++)
		free((char *)env[i]);
	strbuf_release(&buf);
	return len != 0;
}
Пример #17
0
int is_submodule_modified(const char *path)
{
	int len;
	struct child_process cp;
	const char *argv[] = {
		"status",
		"--porcelain",
		NULL,
	};
	char *env[4];
	struct strbuf buf = STRBUF_INIT;

	strbuf_addf(&buf, "%s/.git/", path);
	if (!is_directory(buf.buf)) {
		strbuf_release(&buf);
		/* The submodule is not checked out, so it is not modified */
		return 0;

	}
	strbuf_reset(&buf);

	strbuf_addf(&buf, "GIT_WORK_TREE=%s", path);
	env[0] = strbuf_detach(&buf, NULL);
	strbuf_addf(&buf, "GIT_DIR=%s/.git", path);
	env[1] = strbuf_detach(&buf, NULL);
	strbuf_addf(&buf, "GIT_INDEX_FILE");
	env[2] = strbuf_detach(&buf, NULL);
	env[3] = NULL;

	memset(&cp, 0, sizeof(cp));
	cp.argv = argv;
	cp.env = (const char *const *)env;
	cp.git_cmd = 1;
	cp.no_stdin = 1;
	cp.out = -1;
	if (start_command(&cp))
		die("Could not run git status --porcelain");

	len = strbuf_read(&buf, cp.out, 1024);
	close(cp.out);

	if (finish_command(&cp))
		die("git status --porcelain failed");

	free(env[0]);
	free(env[1]);
	free(env[2]);
	strbuf_release(&buf);
	return len != 0;
}
Пример #18
0
static int disconnect_helper(struct transport *transport)
{
	struct helper_data *data = transport->data;
	if (data->helper) {
		write_str_in_full(data->helper->in, "\n");
		close(data->helper->in);
		finish_command(data->helper);
		free((char *)data->helper->argv[0]);
		free(data->helper->argv);
		free(data->helper);
		data->helper = NULL;
	}
	return 0;
}
Пример #19
0
Файл: pager.c Проект: ovmine/git
static void wait_for_pager(int in_signal)
{
	if (!in_signal) {
		fflush(stdout);
		fflush(stderr);
	}
	/* signal EOF to pager */
	close(1);
	close(2);
	if (in_signal)
		finish_command_in_signal(&pager_process);
	else
		finish_command(&pager_process);
}
Пример #20
0
static void run_service(const char **argv)
{
	const char *encoding = getenv("HTTP_CONTENT_ENCODING");
	const char *user = getenv("REMOTE_USER");
	const char *host = getenv("REMOTE_ADDR");
	char *env[3];
	struct strbuf buf = STRBUF_INIT;
	int gzipped_request = 0;
	struct child_process cld;

	if (encoding && !strcmp(encoding, "gzip"))
		gzipped_request = 1;
	else if (encoding && !strcmp(encoding, "x-gzip"))
		gzipped_request = 1;

	if (!user || !*user)
		user = "******";
	if (!host || !*host)
		host = "(none)";

	memset(&env, 0, sizeof(env));
	strbuf_addf(&buf, "GIT_COMMITTER_NAME=%s", user);
	env[0] = strbuf_detach(&buf, NULL);

	strbuf_addf(&buf, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host);
	env[1] = strbuf_detach(&buf, NULL);
	env[2] = NULL;

	memset(&cld, 0, sizeof(cld));
	cld.argv = argv;
	cld.env = (const char *const *)env;
	if (gzipped_request)
		cld.in = -1;
	cld.git_cmd = 1;
	if (start_command(&cld))
		exit(1);

	close(1);
	if (gzipped_request)
		inflate_request(argv[0], cld.in);
	else
		close(0);

	if (finish_command(&cld))
		exit(1);
	free(env[0]);
	free(env[1]);
	strbuf_release(&buf);
}
Пример #21
0
static int run_service_command(struct child_process *cld)
{
	argv_array_push(&cld->args, ".");
	cld->git_cmd = 1;
	cld->err = -1;
	if (start_command(cld))
		return -1;

	close(0);
	close(1);

	copy_to_log(cld->err);

	return finish_command(cld);
}
Пример #22
0
static int run_child(const char *arg, const char *service)
{
	int r;
	struct child_process child;

	memset(&child, 0, sizeof(child));
	child.in = -1;
	child.out = -1;
	child.err = 0;
	child.argv = parse_argv(arg, service);

	if (start_command(&child) < 0)
		die("Can't run specified command");

	if (git_req)
		send_git_request(child.in, service, git_req, git_req_vhost);

	r = bidirectional_transfer_loop(child.out, child.in);
	if (!r)
		r = finish_command(&child);
	else
		finish_command(&child);
	return r;
}
Пример #23
0
static int run_and_feed_hook(const char *hook_name, feed_fn feed, void *feed_state)
{
	struct child_process proc;
	struct async muxer;
	const char *argv[2];
	int code;

	if (access(hook_name, X_OK) < 0)
		return 0;

	argv[0] = hook_name;
	argv[1] = NULL;

	memset(&proc, 0, sizeof(proc));
	proc.argv = argv;
	proc.in = -1;
	proc.stdout_to_stderr = 1;

	if (use_sideband) {
		memset(&muxer, 0, sizeof(muxer));
		muxer.proc = copy_to_sideband;
		muxer.in = -1;
		code = start_async(&muxer);
		if (code)
			return code;
		proc.err = muxer.in;
	}

	code = start_command(&proc);
	if (code) {
		if (use_sideband)
			finish_async(&muxer);
		return code;
	}

	while (1) {
		const char *buf;
		size_t n;
		if (feed(feed_state, &buf, &n))
			break;
		if (write_in_full(proc.in, buf, n) != n)
			break;
	}
	close(proc.in);
	if (use_sideband)
		finish_async(&muxer);
	return finish_command(&proc);
}
Пример #24
0
static void run_service(const char **argv, int buffer_input)
{
	const char *encoding = getenv("HTTP_CONTENT_ENCODING");
	const char *user = getenv("REMOTE_USER");
	const char *host = getenv("REMOTE_ADDR");
	int gzipped_request = 0;
	struct child_process cld = CHILD_PROCESS_INIT;
	ssize_t req_len = get_content_length();

	if (encoding && !strcmp(encoding, "gzip"))
		gzipped_request = 1;
	else if (encoding && !strcmp(encoding, "x-gzip"))
		gzipped_request = 1;

	if (!user || !*user)
		user = "******";
	if (!host || !*host)
		host = "(none)";

	if (!getenv("GIT_COMMITTER_NAME"))
		argv_array_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user);
	if (!getenv("GIT_COMMITTER_EMAIL"))
		argv_array_pushf(&cld.env_array,
				 "GIT_COMMITTER_EMAIL=%s@http.%s", user, host);

	cld.argv = argv;
	if (buffer_input || gzipped_request || req_len >= 0)
		cld.in = -1;
	cld.git_cmd = 1;
	cld.clean_on_exit = 1;
	cld.wait_after_clean = 1;
	if (start_command(&cld))
		exit(1);

	close(1);
	if (gzipped_request)
		inflate_request(argv[0], cld.in, buffer_input, req_len);
	else if (buffer_input)
		copy_request(argv[0], cld.in, req_len);
	else if (req_len >= 0)
		pipe_fixed_length(argv[0], cld.in, req_len);
	else
		close(0);

	if (finish_command(&cld))
		exit(1);
}
Пример #25
0
/*
 * If we feed all the commits we want to verify to this command
 *
 *  $ git rev-list --objects --stdin --not --all
 *
 * and if it does not error out, that means everything reachable from
 * these commits locally exists and is connected to our existing refs.
 * Note that this does _not_ validate the individual objects.
 *
 * Returns 0 if everything is connected, non-zero otherwise.
 */
int check_everything_connected(sha1_iterate_fn fn, int quiet, void *cb_data)
{
	struct child_process rev_list;
	const char *argv[] = {"rev-list", "--objects",
			      "--stdin", "--not", "--all", NULL, NULL};
	char commit[41];
	unsigned char sha1[20];
	int err = 0;

	if (fn(cb_data, sha1))
		return err;

	if (quiet)
		argv[5] = "--quiet";

	memset(&rev_list, 0, sizeof(rev_list));
	rev_list.argv = argv;
	rev_list.git_cmd = 1;
	rev_list.in = -1;
	rev_list.no_stdout = 1;
	rev_list.no_stderr = quiet;
	if (start_command(&rev_list))
		return error(_("Could not run 'git rev-list'"));

	sigchain_push(SIGPIPE, SIG_IGN);

	commit[40] = '\n';
	do {
		memcpy(commit, sha1_to_hex(sha1), 40);
		if (write_in_full(rev_list.in, commit, 41) < 0) {
			if (errno != EPIPE && errno != EINVAL)
				error(_("failed write to rev-list: %s"),
				      strerror(errno));
			err = -1;
			break;
		}
	} while (!fn(cb_data, sha1));

	if (close(rev_list.in)) {
		error(_("failed to close rev-list's stdin: %s"), strerror(errno));
		err = -1;
	}

	sigchain_pop(SIGPIPE);
	return finish_command(&rev_list) || err;
}
Пример #26
0
static int check_emacsclient_version(void)
{
	struct strbuf buffer = STRBUF_INIT;
	struct child_process ec_process;
	const char *argv_ec[] = { "emacsclient", "--version", NULL };
	int version;
	int ret = -1;

	/* emacsclient prints its version number on stderr */
	memset(&ec_process, 0, sizeof(ec_process));
	ec_process.argv = argv_ec;
	ec_process.err = -1;
	ec_process.stdout_to_stderr = 1;
	if (start_command(&ec_process)) {
		fprintf(stderr, "Failed to start emacsclient.\n");
		return -1;
	}
	if (strbuf_read(&buffer, ec_process.err, 20) < 0) {
		fprintf(stderr, "Failed to read emacsclient version\n");
		goto out;
	}
	close(ec_process.err);

	/*
	 * Don't bother checking return value, because "emacsclient --version"
	 * seems to always exits with code 1.
	 */
	finish_command(&ec_process);

	if (prefixcmp(buffer.buf, "emacsclient")) {
		fprintf(stderr, "Failed to parse emacsclient version.\n");
		goto out;
	}

	version = atoi(buffer.buf + strlen("emacsclient"));

	if (version < 22) {
		fprintf(stderr,
			"emacsclient version '%d' too old (< 22).\n",
			version);
	} else
		ret = 0;
out:
	strbuf_release(&buffer);
	return ret;
}
Пример #27
0
static int run_service_command(const char **argv)
{
	struct child_process cld = CHILD_PROCESS_INIT;

	cld.argv = argv;
	cld.git_cmd = 1;
	cld.err = -1;
	if (start_command(&cld))
		return -1;

	close(0);
	close(1);

	copy_to_log(cld.err);

	return finish_command(&cld);
}
Пример #28
0
static int run_service_command(const char **argv)
{
	struct child_process cld;

	memset(&cld, 0, sizeof(cld));
	cld.argv = argv;
	cld.git_cmd = 1;
	cld.err = -1;
	if (start_command(&cld))
		return -1;

	close(0);
	close(1);

	copy_to_log(cld.err);

	return finish_command(&cld);
}
Пример #29
0
int
use_selected()
{
    register SUBJECT *sp;
    register ARTICLE *ap;
    bool want_read;
    char *cmdstr;
    int len, ret = 1;
    int subj_mask = (sel_mode == SM_THREAD? (SF_THREAD|SF_VISIT) : SF_VISIT);

    if (!finish_command(TRUE))	/* get rest of command */
	return 0;
    if (!buf[1])
	return -1;
    cmdstr = savestr(buf+1);
    want_read = (sel_rereading || *cmdstr =='m');

    perform_cnt = 0;
    page_line = 1;
    len = strlen(cmdstr);

    /* A few commands can just loop through the subjects. */
    if ((len == 1 && (*cmdstr == 't' || *cmdstr == 'J'))
     || (len == 2
      && (((*cmdstr == '+' || *cmdstr == '-') && cmdstr[0] == cmdstr[1])
       || *cmdstr == 'T'))) {
	for (sp = first_subject; sp; sp = sp->next) {
	    if ((sp->flags & subj_mask) == subj_mask) {
		artp = first_art(sp);
		if (artp) {
		    art = article_num(artp);
		    if (perform(cmdstr, FALSE)) {
			fputs("\nInterrupted\n", stdout) FLUSH;
			goto break_out;
		    }
		}
#ifdef VERBOSE
		IF(verbose)
		    if (mode != 't' && *cmdstr != 't' && *cmdstr != 'T')
			putchar('\n') FLUSH;
#endif
	    }
	}
    } else if (strEQ(cmdstr, "E")) {
Пример #30
0
static void run_service(const char **argv)
{
	const char *encoding = getenv("HTTP_CONTENT_ENCODING");
	const char *user = getenv("REMOTE_USER");
	const char *host = getenv("REMOTE_ADDR");
	struct argv_array env = ARGV_ARRAY_INIT;
	int gzipped_request = 0;
	struct child_process cld;

	if (encoding && !strcmp(encoding, "gzip"))
		gzipped_request = 1;
	else if (encoding && !strcmp(encoding, "x-gzip"))
		gzipped_request = 1;

	if (!user || !*user)
		user = "******";
	if (!host || !*host)
		host = "(none)";

	if (!getenv("GIT_COMMITTER_NAME"))
		argv_array_pushf(&env, "GIT_COMMITTER_NAME=%s", user);
	if (!getenv("GIT_COMMITTER_EMAIL"))
		argv_array_pushf(&env, "GIT_COMMITTER_EMAIL=%s@http.%s",
				 user, host);

	memset(&cld, 0, sizeof(cld));
	cld.argv = argv;
	cld.env = env.argv;
	if (gzipped_request)
		cld.in = -1;
	cld.git_cmd = 1;
	if (start_command(&cld))
		exit(1);

	close(1);
	if (gzipped_request)
		inflate_request(argv[0], cld.in);
	else
		close(0);

	if (finish_command(&cld))
		exit(1);
	argv_array_clear(&env);
}