git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 14/14] Use the asyncronous function infrastructure to run the content filter.

From
Johannes Sixt <johannes.sixt@telecom.at>
Date
Oct 19, 2007, 19:48 UTC
Message-ID
<1192823286-9654-15-git-send-email-johannes.sixt@telecom.at>
In-Reply-To
<1192823286-9654-14-git-send-email-johannes.sixt@telecom.at>
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
 convert.c |   61 ++++++++++++++++++++++++++++---------------------------------
 1 files changed, 28 insertions(+), 33 deletions(-)
diff --git a/convert.c b/convert.c
index 8dc9965..4df7559 100644
--- a/convert.c
+++ b/convert.c
@@ -192,15 +192,21 @@ static int crlf_to_worktree(const char *path, const char *src, size_t len,
 	return 1;
 }
 
-static int filter_buffer(int fd, const char *src,
-			 unsigned long size, const char *cmd)
+struct filter_params {
+	const char *src;
+	unsigned long size;
+	const char *cmd;
+};
+
+static int filter_buffer(int fd, void *data)
 {
 	/*
 	 * Spawn cmd and feed the buffer contents through its stdin.
 	 */
 	struct child_process child_process;
+	struct filter_params *params = (struct filter_params *)data;
 	int write_err, status;
-	const char *argv[] = { "sh", "-c", cmd, NULL };
+	const char *argv[] = { "sh", "-c", params->cmd, NULL };
 
 	memset(&child_process, 0, sizeof(child_process));
 	child_process.argv = argv;
@@ -208,17 +214,17 @@ static int filter_buffer(int fd, const char *src,
 	child_process.out = fd;
 
 	if (start_command(&child_process))
-		return error("cannot fork to run external filter %s", cmd);
+		return error("cannot fork to run external filter %s", params->cmd);
 
-	write_err = (write_in_full(child_process.in, src, size) < 0);
+	write_err = (write_in_full(child_process.in, params->src, params->size) < 0);
 	if (close(child_process.in))
 		write_err = 1;
 	if (write_err)
-		error("cannot feed the input to external filter %s", cmd);
+		error("cannot feed the input to external filter %s", params->cmd);
 
 	status = finish_command(&child_process);
 	if (status)
-		error("external filter %s failed %d", cmd, -status);
+		error("external filter %s failed %d", params->cmd, -status);
 	return (write_err || status);
 }
 
@@ -231,47 +237,36 @@ static int apply_filter(const char *path, const char *src, size_t len,
 	 *
 	 * (child --> cmd) --> us
 	 */
-	int pipe_feed[2];
-	int status, ret = 1;
-	struct child_process child_process;
+	int ret = 1;
 	struct strbuf nbuf;
+	struct async async;
+	struct filter_params params;
 
 	if (!cmd)
 		return 0;
 
-	memset(&child_process, 0, sizeof(child_process));
-
-	if (pipe(pipe_feed) < 0) {
-		error("cannot create pipe to run external filter %s", cmd);
-		return 0;
-	}
+	memset(&async, 0, sizeof(async));
+	async.proc = filter_buffer;
+	async.data = &params;
+	params.src = src;
+	params.size = len;
+	params.cmd = cmd;
 
 	fflush(NULL);
-	child_process.pid = fork();
-	if (child_process.pid < 0) {
-		error("cannot fork to run external filter %s", cmd);
-		close(pipe_feed[0]);
-		close(pipe_feed[1]);
-		return 0;
-	}
-	if (!child_process.pid) {
-		close(pipe_feed[0]);
-		exit(filter_buffer(pipe_feed[1], src, len, cmd));
-	}
-	close(pipe_feed[1]);
+	if (start_async(&async))
+		return 0;	/* error was already reported */
 
 	strbuf_init(&nbuf, 0);
-	if (strbuf_read(&nbuf, pipe_feed[0], len) < 0) {
+	if (strbuf_read(&nbuf, async.out, len) < 0) {
 		error("read from external filter %s failed", cmd);
 		ret = 0;
 	}
-	if (close(pipe_feed[0])) {
+	if (close(async.out)) {
 		error("read from external filter %s failed", cmd);
 		ret = 0;
 	}
-	status = finish_command(&child_process);
-	if (status) {
-		error("external filter %s failed %d", cmd, -status);
+	if (finish_async(&async)) {
+		error("external filter %s failed", cmd);
 		ret = 0;
 	}
 
-- 
1.5.3.4.315.g2ce38
Previous: Johannes SixtNext: Shawn O. Pearce
Message 15 of 18 in “fork/exec removal series”
  1. 0/14 fork/exec removal seriesJohannes Sixt, Oct 19, 2007
  2. 01/14 Change git_connect() to return a struct child_process instead of a pid_t.Johannes Sixt, Oct 19, 2007
  3. 02/14 Use start_command() in git_connect() instead of explicit fork/exec.Johannes Sixt, Oct 19, 2007
  4. 03/14 Use start_command() to run content filters instead of explicit fork/exec.Johannes Sixt, Oct 19, 2007
  5. 04/14 Use run_command() to spawn external diff programs instead of fork/exec.Johannes Sixt, Oct 19, 2007
  6. 05/14 Use start_comand() in builtin-fetch-pack.c instead of explicit fork/exec.Johannes Sixt, Oct 19, 2007
  7. 06/14 Have start_command() create a pipe to read the stderr of the child.Johannes Sixt, Oct 19, 2007
  8. 07/14 upload-pack: Use start_command() to run pack-objects in create_pack_file().Johannes Sixt, Oct 19, 2007
  9. 08/14 Add infrastructure to run a function asynchronously.Johannes Sixt, Oct 19, 2007
  10. 09/14 Use the asyncronous function infrastructure in builtin-fetch-pack.c.Johannes Sixt, Oct 19, 2007
  11. 10/14 upload-pack: Move the revision walker into a separate function.Johannes Sixt, Oct 19, 2007
  12. 11/14 upload-pack: Run rev-list in an asynchronous function.Johannes Sixt, Oct 19, 2007
  13. 12/14 t0021-conversion.sh: Test that the clean filter really cleans content.Johannes Sixt, Oct 19, 2007
  14. 13/14 Avoid a dup2(2) in apply_filter() - start_command() can do it for us.Johannes Sixt, Oct 19, 2007
  15. 14/14 Use the asyncronous function infrastructure to run the content filter.Johannes Sixt, Oct 19, 2007
  16. Shawn O. PearceOct 20, 2007
  17. Johannes SixtOct 20, 2007
  18. Shawn O. PearceOct 21, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.