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

[PATCH 4/4] pager: do wait_for_pager on signal death

From
Jeff King <peff@peff.net>
Date
Jan 11, 2009, 11:36 UTC
Message-ID
<20090111113649.GD29791@coredump.intra.peff.net>
In-Reply-To
<20090111112222.GA29656@coredump.intra.peff.net>

Since ea27a18 (spawn pager via run_command interface), the original git process actually does git work, and the pager is a child process (actually, on Windows it has always been that way, since Windows lacks fork). After spawning the pager, we register an atexit() handler that waits for the pager to finish.

Unfortunately, that handler does not always run. In particular, if git is killed by a signal, then we exit immediately. The calling shell then thinks that git is done; however, the pager is still trying to run and impact the terminal. The result can be seen by running a long git process with a pager (e.g., "git log -p") and hitting ^C. Depending on your config, you should see the shell prompt, but pressing a key causes the pager to do any terminal de-initialization sequence.

This patch just intercepts any death-dealing signals and waits for the pager before dying. Under typical less configuration, that means hitting ^C will cause git to stop generating output, but the pager will keep running.

Signed-off-by: Jeff King <peff@peff.net>
---
 pager.c |    9 +++++++++
 1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/pager.c b/pager.c
index f19ddbc..4921843 100644
--- a/pager.c
+++ b/pager.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "run-command.h"
+#include "sigchain.h"
 
 /*
  * This is split up from the rest of git so that we can do
@@ -38,6 +39,13 @@ static void wait_for_pager(void)
 	finish_command(&pager_process);
 }
 
+static void wait_for_pager_signal(int signo)
+{
+	wait_for_pager();
+	sigchain_pop(signo);
+	raise(signo);
+}
+
 void setup_pager(void)
 {
 	const char *pager = getenv("GIT_PAGER");
@@ -75,6 +83,7 @@ void setup_pager(void)
 	close(pager_process.in);
 
 	/* this makes sure that the parent terminates after the pager */
+	sigchain_push_common(wait_for_pager_signal);
 	atexit(wait_for_pager);
 }
 
-- 
1.6.1.84.g8150
Previous: Jeff KingNext: Junio C Hamano
Message 15 of 41 in “Funny: git -p submodule summary”
  1. Johannes SchindelinJan 8, 2009
  2. Johannes SchindelinJan 8, 2009
  3. Jeff KingJan 9, 2009
  4. Jeff KingJan 9, 2009
  5. Jeff KingJan 9, 2009
  6. Johannes SixtJan 9, 2009
  7. Jeff KingJan 9, 2009
  8. Johannes SixtJan 9, 2009
  9. Jeff KingJan 9, 2009
  10. Jeff KingJan 11, 2009
  11. 1/4 Makefile: clean up TEST_PROGRAMS definitionJeff King, Jan 11, 2009
  12. 2/4 chain kill signals for cleanup functionsJeff King, Jan 11, 2009
  13. Jeff KingJan 11, 2009
  14. 3/4 refactor signal handling for cleanup functionsJeff King, Jan 11, 2009
  15. 4/4 pager: do wait_for_pager on signal deathJeff King, Jan 11, 2009
  16. Junio C HamanoJan 11, 2009
  17. Johannes SixtJan 12, 2009
  18. Jeff KingJan 12, 2009
  19. Johannes SixtJan 12, 2009
  20. Jeff KingJan 12, 2009
  21. Johannes SixtJan 12, 2009
  22. Junio C HamanoJan 9, 2009
  23. Jeff KingJan 9, 2009
  24. Junio C HamanoJan 9, 2009
  25. 0/3 fix "Funny: git -p submodule summary"Jeff King, Jan 27, 2009
  26. 1/3 git: s/run_command/run_builtin/Jeff King, Jan 27, 2009
  27. 2/3 run_command: handle missing command errors more gracefullyJeff King, Jan 27, 2009
  28. 3/3 git: use run_command to execute dashed externalsJeff King, Jan 27, 2009
  29. Johannes SixtJan 27, 2009
  30. Jeff KingJan 27, 2009
  31. Johannes SixtJan 27, 2009
  32. Jeff KingJan 28, 2009
  33. Johannes SchindelinJan 27, 2009
  34. Jeff KingJan 28, 2009
  35. 1/4 git: s/run_command/run_builtin/Jeff King, Jan 28, 2009
  36. 2/4 run_command: handle missing command errors more gracefullyJeff King, Jan 28, 2009
  37. 3/4 run-command: help callers distinguish errorsJeff King, Jan 28, 2009
  38. Jeff KingJan 28, 2009
  39. Jeff KingJan 28, 2009
  40. 4/4 git: use run_command to execute dashed externalsJeff King, Jan 28, 2009
  41. Junio C HamanoJan 28, 2009

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.