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

[PATCH v10 04/14] run-command: add clean_on_exit_handler

From
larsxschneider@gmail.com <larsxschneider@gmail.com>
Date
Oct 8, 2016, 11:25 UTC
Message-ID
<20161008112530.15506-5-larsxschneider@gmail.com>
In-Reply-To
<20161008112530.15506-1-larsxschneider@gmail.com>
From: Lars Schneider <larsxschneider@gmail.com>

Some processes might want to perform cleanup tasks before Git kills them due to the 'clean_on_exit' flag. Let's give them an interface for doing this. The feature is used in a subsequent patch.

Please note, that the cleanup callback is not executed if Git dies of a signal. The reason is that only "async-signal-safe" functions would be allowed to be call in that case. Since we cannot control what functions the callback will use, we will not support the case. See 507d7804 for more details.

Helped-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Lars Schneider <larsxschneider@gmail.com>
---
 run-command.c | 19 +++++++++++++++----
 run-command.h |  2 ++
 2 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/run-command.c b/run-command.c
index 3269362..e5fd6ff 100644
--- a/run-command.c
+++ b/run-command.c
@@ -21,6 +21,7 @@ void child_process_clear(struct child_process *child)
 
 struct child_to_clean {
 	pid_t pid;
+	struct child_process *process;
 	struct child_to_clean *next;
 };
 static struct child_to_clean *children_to_clean;
@@ -31,6 +32,15 @@ static void cleanup_children(int sig, int in_signal)
 	while (children_to_clean) {
 		struct child_to_clean *p = children_to_clean;
 		children_to_clean = p->next;
+
+		if (p->process && !in_signal) {
+			struct child_process *process = p->process;
+			if (process->clean_on_exit_handler) {
+				trace_printf("trace: run_command: running exit handler for pid %d", p->pid);
+				process->clean_on_exit_handler(process);
+			}
+		}
+
 		kill(p->pid, sig);
 		if (!in_signal)
 			free(p);
@@ -49,10 +59,11 @@ static void cleanup_children_on_exit(void)
 	cleanup_children(SIGTERM, 0);
 }
 
-static void mark_child_for_cleanup(pid_t pid)
+static void mark_child_for_cleanup(pid_t pid, struct child_process *process)
 {
 	struct child_to_clean *p = xmalloc(sizeof(*p));
 	p->pid = pid;
+	p->process = process;
 	p->next = children_to_clean;
 	children_to_clean = p;
 
@@ -422,7 +433,7 @@ int start_command(struct child_process *cmd)
 	if (cmd->pid < 0)
 		error_errno("cannot fork() for %s", cmd->argv[0]);
 	else if (cmd->clean_on_exit)
-		mark_child_for_cleanup(cmd->pid);
+		mark_child_for_cleanup(cmd->pid, cmd);
 
 	/*
 	 * Wait for child's execvp. If the execvp succeeds (or if fork()
@@ -483,7 +494,7 @@ int start_command(struct child_process *cmd)
 	if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT))
 		error_errno("cannot spawn %s", cmd->argv[0]);
 	if (cmd->clean_on_exit && cmd->pid >= 0)
-		mark_child_for_cleanup(cmd->pid);
+		mark_child_for_cleanup(cmd->pid, cmd);
 
 	argv_array_clear(&nargv);
 	cmd->argv = sargv;
@@ -765,7 +776,7 @@ int start_async(struct async *async)
 		exit(!!async->proc(proc_in, proc_out, async->data));
 	}
 
-	mark_child_for_cleanup(async->pid);
+	mark_child_for_cleanup(async->pid, NULL);
 
 	if (need_in)
 		close(fdin[0]);
diff --git a/run-command.h b/run-command.h
index cf29a31..dd1c78c 100644
--- a/run-command.h
+++ b/run-command.h
@@ -43,6 +43,8 @@ struct child_process {
 	unsigned stdout_to_stderr:1;
 	unsigned use_shell:1;
 	unsigned clean_on_exit:1;
+	void (*clean_on_exit_handler)(struct child_process *process);
+	void *clean_on_exit_handler_cbdata;
 };
 
 #define CHILD_PROCESS_INIT { NULL, ARGV_ARRAY_INIT, ARGV_ARRAY_INIT }
-- 
2.10.0
Previous: larsxschneider@gmail.comNext: Johannes Schindelin
Message 5 of 34 in “Git filter protocol”
  1. 00/14 Git filter protocollarsxschneider@gmail.com, Oct 8, 2016
  2. 01/14 convert: quote filter names in error messageslarsxschneider@gmail.com, Oct 8, 2016
  3. 02/14 convert: modernize testslarsxschneider@gmail.com, Oct 8, 2016
  4. 03/14 run-command: move check_pipe() from write_or_die to run_commandlarsxschneider@gmail.com, Oct 8, 2016
  5. 04/14 run-command: add clean_on_exit_handlerlarsxschneider@gmail.com, Oct 8, 2016
  6. Johannes SchindelinOct 11, 2016
  7. Lars SchneiderOct 15, 2016
  8. Johannes SchindelinOct 16, 2016
  9. Lars SchneiderOct 16, 2016
  10. 05/14 pkt-line: rename packet_write() to packet_write_fmt()larsxschneider@gmail.com, Oct 8, 2016
  11. 07/14 pkt-line: add packet_write_fmt_gently()larsxschneider@gmail.com, Oct 8, 2016
  12. 08/14 pkt-line: add packet_flush_gently()larsxschneider@gmail.com, Oct 8, 2016
  13. 09/14 pkt-line: add packet_write_gently()larsxschneider@gmail.com, Oct 8, 2016
  14. 11/14 convert: make apply_filter() adhere to standard Git error handlinglarsxschneider@gmail.com, Oct 8, 2016
  15. 06/14 pkt-line: extract set_packet_header()larsxschneider@gmail.com, Oct 8, 2016
  16. 12/14 convert: prepare filter.<driver>.process optionlarsxschneider@gmail.com, Oct 8, 2016
  17. 13/14 convert: add filter.<driver>.process optionlarsxschneider@gmail.com, Oct 8, 2016
  18. Jakub NarębskiOct 8, 2016
  19. Torsten BögershausenOct 9, 2016
  20. Lars SchneiderOct 11, 2016
  21. Lars SchneiderOct 11, 2016
  22. Jakub NarębskiOct 12, 2016
  23. Lars SchneiderOct 15, 2016
  24. Jeff KingOct 15, 2016
  25. Jakub NarębskiOct 15, 2016
  26. Junio C HamanoOct 10, 2016
  27. Lars SchneiderOct 11, 2016
  28. Torsten BögershausenOct 11, 2016
  29. Lars SchneiderOct 16, 2016
  30. Junio C HamanoOct 17, 2016
  31. 10/14 pkt-line: add functions to read/write flush terminated packet streamslarsxschneider@gmail.com, Oct 8, 2016
  32. 14/14 contrib/long-running-filter: add long running filter examplelarsxschneider@gmail.com, Oct 8, 2016
  33. Torsten BögershausenOct 9, 2016
  34. Lars SchneiderOct 15, 2016

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.