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

[PATCH v2 4/5] pager: properly log pager exit code when signalled

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Feb 2, 2021, 02:00 UTC
Message-ID
<20210202020001.31601-5-avarab@gmail.com>
In-Reply-To
<20210201144921.8664-1-avarab@gmail.com>

When git invokes a pager that exits with non-zero the common case is that we'll already return the correct SIGPIPE failure from git itself, but the exit code logged in trace2 has always been incorrectly reported[1]. Fix that and log the correct exit code in the logs.

Since this gives us something to test outside of our recently-added tests needing a !MINGW prerequisite, let's refactor the test to run on MINGW and actually check for SIGPIPE outside of MINGW.

The wait_or_whine() is only called with a true "in_signal" from from finish_command_in_signal(), which in turn is only used in pager.c.

The "in_signal && !WIFEXITED(status)" case is not covered by tests. Let's log the default -1 in that case for good measure.

1. The incorrect logging of the exit code in was seemingly copy/pasted
   into finish_command_in_signal() in ee4512ed481 (trace2: create new
   combined trace facility, 2019-02-22)
Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 run-command.c    |  4 +++-
 t/t7006-pager.sh | 60 +++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 57 insertions(+), 7 deletions(-)
diff --git a/run-command.c b/run-command.c
index 00e68f37aba..509841bf273 100644
--- a/run-command.c
+++ b/run-command.c
@@ -552,7 +552,9 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal)
 	while ((waiting = waitpid(pid, &status, 0)) < 0 && errno == EINTR)
 		;	/* nothing */
 	if (in_signal) {
-		return 0;
+		if (WIFEXITED(status))
+			code = WEXITSTATUS(status);
+		return code;
 	}
 
 	if (waiting < 0) {
diff --git a/t/t7006-pager.sh b/t/t7006-pager.sh
index 0aa030962b1..0e7cf75435e 100755
--- a/t/t7006-pager.sh
+++ b/t/t7006-pager.sh
@@ -656,9 +656,17 @@ test_expect_success TTY 'git tag with auto-columns ' '
 	test_cmp expect actual
 '
 
+test_expect_success 'setup trace2' '
+	GIT_TRACE2_BRIEF=1 &&
+	export GIT_TRACE2_BRIEF
+'
+
 test_expect_success TTY 'git returns SIGPIPE on early pager exit' '
-	test_when_finished "rm pager-used" &&
+	test_when_finished "rm pager-used trace.normal" &&
 	test_config core.pager ">pager-used; head -n 1; exit 0" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -667,12 +675,19 @@ test_expect_success TTY 'git returns SIGPIPE on early pager exit' '
 	else
 		test_terminal git log
 	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:0 " child-exits &&
 	test_path_is_file pager-used
 '
 
 test_expect_success TTY 'git returns SIGPIPE on early pager non-zero exit' '
-	test_when_finished "rm pager-used" &&
+	test_when_finished "rm pager-used trace.normal" &&
 	test_config core.pager ">pager-used; head -n 1; exit 1" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -681,12 +696,19 @@ test_expect_success TTY 'git returns SIGPIPE on early pager non-zero exit' '
 	else
 		test_terminal git log
 	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:1 " child-exits &&
 	test_path_is_file pager-used
 '
 
 test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
-	test_when_finished "rm pager-used" &&
+	test_when_finished "rm pager-used trace.normal" &&
 	test_config core.pager "wc >pager-used; exit 1" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -695,12 +717,19 @@ test_expect_success TTY 'git discards pager non-zero exit without SIGPIPE' '
 	else
 		test_terminal git log
 	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:1 " child-exits &&
 	test_path_is_file pager-used
 '
 
 test_expect_success TTY 'git discards nonexisting pager without SIGPIPE' '
-	test_when_finished "rm pager-used" &&
+	test_when_finished "rm pager-used trace.normal" &&
 	test_config core.pager "wc >pager-used; does-not-exist" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -709,11 +738,19 @@ test_expect_success TTY 'git discards nonexisting pager without SIGPIPE' '
 	else
 		test_terminal git log
 	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:127 " child-exits &&
 	test_path_is_file pager-used
 '
 
 test_expect_success TTY 'git attempts to page to nonexisting pager command, gets SIGPIPE' '
+	test_when_finished "rm trace.normal" &&
 	test_config core.pager "does-not-exist" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -721,12 +758,19 @@ test_expect_success TTY 'git attempts to page to nonexisting pager command, gets
 		test_match_signal 13 "$OUT"
 	else
 		test_terminal git log
-	fi
+	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:-1 " child-exits
 '
 
 test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
-	test_when_finished "rm pager-used" &&
+	test_when_finished "rm pager-used trace.normal" &&
 	test_config core.pager ">pager-used; test-tool sigchain" &&
+	GIT_TRACE2="$(pwd)/trace.normal" &&
+	export GIT_TRACE2 &&
+	test_when_finished "unset GIT_TRACE2" &&
 
 	if test_have_prereq !MINGW
 	then
@@ -735,6 +779,10 @@ test_expect_success TTY 'git returns SIGPIPE on propagated signals from pager' '
 	else
 		test_terminal git log
 	fi &&
+
+	grep child_exit trace.normal >child-exits &&
+	test_line_count = 1 child-exits &&
+	grep " code:143 " child-exits &&
 	test_path_is_file pager-used
 '
 
-- 
2.30.0.284.gd98b1dd5eaa7
Previous: Johannes SixtNext: Johannes Sixt
Message 48 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.