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

[PATCH] pager: exit without error on SIGPIPE

From
Denton Liu <liu.denton@gmail.com>
Date
Jan 29, 2021, 23:48 UTC
Message-ID
<bc88492979fee215d5be06ccbc246ae0171a9ced.1611910122.git.liu.denton@gmail.com>
In-Reply-To
<YAG/vzctP4JwSp5x@zira.vinc17.org>

If the pager closes before the git command feeding the pager finishes, git is killed by a SIGPIPE and the corresponding exit code is 141. Since the pipe is just an implementation detail, it does not make sense for this error code to be user-facing.

Handle SIGPIPEs by simply calling exit(0) in wait_for_pager_signal().

Introduce `test-tool pager` which infinitely prints `y` to the pager in order to test the new behavior. This cannot be tested with any existing git command because there are no other commands which produce infinite output. Without the change to pager.c, the newly introduced test fails.

Reported-by: Vincent Lefevre <vincent@vinc17.net>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
---
Sorry for the resend, it seems like vger has dropped the first patch.
 Makefile              |  1 +
 pager.c               |  2 ++
 t/helper/test-pager.c | 12 ++++++++++++
 t/helper/test-tool.c  |  1 +
 t/helper/test-tool.h  |  1 +
 t/t7006-pager.sh      |  4 ++++
 6 files changed, 21 insertions(+)
 create mode 100644 t/helper/test-pager.c
diff --git a/Makefile b/Makefile
index 4edfda3e00..38a1a20f31 100644
--- a/Makefile
+++ b/Makefile
@@ -719,6 +719,7 @@ TEST_BUILTINS_OBJS += test-mktemp.o
 TEST_BUILTINS_OBJS += test-oid-array.o
 TEST_BUILTINS_OBJS += test-oidmap.o
 TEST_BUILTINS_OBJS += test-online-cpus.o
+TEST_BUILTINS_OBJS += test-pager.o
 TEST_BUILTINS_OBJS += test-parse-options.o
 TEST_BUILTINS_OBJS += test-parse-pathspec-file.o
 TEST_BUILTINS_OBJS += test-path-utils.o
diff --git a/pager.c b/pager.c
index ee435de675..5922d99dc8 100644
--- a/pager.c
+++ b/pager.c
@@ -34,6 +34,8 @@ static void wait_for_pager_atexit(void)
 static void wait_for_pager_signal(int signo)
 {
 	wait_for_pager(1);
+	if (signo == SIGPIPE)
+		exit(0);
 	sigchain_pop(signo);
 	raise(signo);
 }
diff --git a/t/helper/test-pager.c b/t/helper/test-pager.c
new file mode 100644
index 0000000000..feb68b8643
--- /dev/null
+++ b/t/helper/test-pager.c
@@ -0,0 +1,12 @@
+#include "test-tool.h"
+#include "cache.h"
+
+int cmd__pager(int argc, const char **argv)
+{
+	if (argc > 1)
+		usage("\ttest-tool pager");
+
+	setup_pager();
+	for (;;)
+		puts("y");
+}
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
index 9d6d14d929..88269a7156 100644
--- a/t/helper/test-tool.c
+++ b/t/helper/test-tool.c
@@ -43,6 +43,7 @@ static struct test_cmd cmds[] = {
 	{ "oid-array", cmd__oid_array },
 	{ "oidmap", cmd__oidmap },
 	{ "online-cpus", cmd__online_cpus },
+	{ "pager", cmd__pager },
 	{ "parse-options", cmd__parse_options },
 	{ "parse-pathspec-file", cmd__parse_pathspec_file },
 	{ "path-utils", cmd__path_utils },
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
index a6470ff62c..78900f7938 100644
--- a/t/helper/test-tool.h
+++ b/t/helper/test-tool.h
@@ -32,6 +32,7 @@ int cmd__mergesort(int argc, const char **argv);
 int cmd__mktemp(int argc, const char **argv);
 int cmd__oidmap(int argc, const char **argv);
 int cmd__online_cpus(int argc, const char **argv);
+int cmd__pager(int argc, const char **argv);
 int cmd__parse_options(int argc, const char **argv);
 int cmd__parse_pathspec_file(int argc, const char** argv);
 int cmd__path_utils(int argc, const char **argv);
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index fdb450e446..2eb89e8f75 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -656,4 +656,8 @@ test_expect_success TTY 'git tag with auto-columns ' '
 	test_cmp expect actual
 '
 
+test_expect_success TTY 'SIGPIPE from pager returns success' '
+	test_terminal env PAGER=true test-tool pager
+'
+
 test_done
-- 
2.30.0.478.g8a0d178c01
Previous: Vincent LefevreNext: Johannes Sixt
Message 2 of 60 in “git fails with a broken pipe when one quits the pager”
  1. Vincent LefevreJan 15, 2021
  2. pager: exit without error on SIGPIPEDenton Liu, Jan 29, 2021
  3. Johannes SixtJan 30, 2021
  4. Johannes SixtJan 30, 2021
  5. Ævar Arnfjörð BjarmasonFeb 1, 2021
  6. Junio C HamanoFeb 1, 2021
  7. Ævar Arnfjörð BjarmasonFeb 1, 2021
  8. Junio C HamanoFeb 1, 2021
  9. Ævar Arnfjörð BjarmasonFeb 2, 2021
  10. Junio C HamanoFeb 2, 2021
  11. Junio C HamanoFeb 2, 2021
  12. Johannes SixtFeb 2, 2021
  13. Junio C HamanoFeb 2, 2021
  14. Johannes SixtFeb 2, 2021
  15. Junio C HamanoFeb 2, 2021
  16. Johannes SixtFeb 3, 2021
  17. Junio C HamanoFeb 3, 2021
  18. Vincent LefevreFeb 4, 2021
  19. Ævar Arnfjörð BjarmasonFeb 3, 2021
  20. Junio C HamanoFeb 3, 2021
  21. Ævar Arnfjörð BjarmasonFeb 3, 2021
  22. Johannes SixtFeb 3, 2021
  23. Ævar Arnfjörð BjarmasonJan 31, 2021
  24. Vincent LefevreJan 31, 2021
  25. Vincent LefevreJan 31, 2021
  26. Ævar Arnfjörð BjarmasonJan 31, 2021
  27. Vincent LefevreFeb 1, 2021
  28. Chris TorekFeb 1, 2021
  29. Vincent LefevreFeb 1, 2021
  30. Chris TorekFeb 1, 2021
  31. Vincent LefevreFeb 1, 2021
  32. Ævar Arnfjörð BjarmasonFeb 1, 2021
  33. Ævar Arnfjörð BjarmasonFeb 1, 2021
  34. 3/3 pager: properly log pager exit code when signalledÆvar Arnfjörð Bjarmason, Feb 1, 2021
  35. Junio C HamanoFeb 1, 2021
  36. Ævar Arnfjörð BjarmasonFeb 1, 2021
  37. Junio C HamanoFeb 1, 2021
  38. Ævar Arnfjörð BjarmasonFeb 1, 2021
  39. 2/3 pager: refactor wait_for_pager() functionÆvar Arnfjörð Bjarmason, Feb 1, 2021
  40. 1/3 pager: test for exit codeÆvar Arnfjörð Bjarmason, Feb 1, 2021
  41. 0/3 pager: test for exit behavior & trace2 bug fixÆvar Arnfjörð Bjarmason, Feb 1, 2021
  42. 1/5 pager: refactor wait_for_pager() functionÆvar Arnfjörð Bjarmason, Feb 2, 2021
  43. 0/5 pager: test for exit behavior & trace2 bug fixÆvar Arnfjörð Bjarmason, Feb 2, 2021
  44. 3/5 run-command: add braces for "if" block in wait_or_whine()Ævar Arnfjörð Bjarmason, Feb 2, 2021
  45. 2/5 pager: test for exit code with and without SIGPIPEÆvar Arnfjörð Bjarmason, Feb 2, 2021
  46. Denton LiuFeb 2, 2021
  47. Johannes SixtFeb 5, 2021
  48. 4/5 pager: properly log pager exit code when signalledÆvar Arnfjörð Bjarmason, Feb 2, 2021
  49. Johannes SixtFeb 5, 2021
  50. Junio C HamanoFeb 5, 2021
  51. 5/5 WIP pager: respect exit code of pager over SIGPIPEÆvar Arnfjörð Bjarmason, Feb 2, 2021
  52. Vincent LefevreFeb 1, 2021
  53. Ævar Arnfjörð BjarmasonFeb 1, 2021
  54. Johannes SixtFeb 1, 2021
  55. Ævar Arnfjörð BjarmasonFeb 3, 2021
  56. Johannes SixtFeb 3, 2021
  57. Vincent LefevreFeb 3, 2021
  58. Ævar Arnfjörð BjarmasonFeb 4, 2021
  59. Vincent LefevreFeb 4, 2021
  60. Johannes SixtFeb 1, 2021

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.