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

[RFC PATCH v7 08/10] sub-process: add a gentle status read

From
Michael Montalbo <mmontalbo@gmail.com>
Date
Aug 1, 2026, 17:41 UTC
Message-ID
<20260801174156.2998808-9-mmontalbo@gmail.com>
In-Reply-To
<20260801174156.2998808-1-mmontalbo@gmail.com>

subprocess_read_status() reads "status=<key>" packets up to a flush with packet_read_line_gently(), which is gentle only about EOF. A malformed length header still dies inside pkt-line, and an empty packet is indistinguishable from the flush that ends the section. A protocol violation in a status section therefore either kills the whole command or silently truncates the section. That posture fits the filter protocol's callers, which treat their process as required infrastructure; the diff process consult added later in this series treats its process as optional, and any protocol error must degrade to the builtin diff rather than abort the command.

Add subprocess_read_status_gently(): the same status loop, reading through packet_read_with_status() with the gentle options, returning -1 on a truncated or malformed packet and on an empty packet where a status line or the terminating flush belongs. subprocess_read_status() and its callers are unchanged.

The handshake has its gentle counterpart in 061a68e443 (sub-process: use gentle handshake to avoid die() on startup failure, 2026-06-01), which turned truncated handshake reads into error returns for every caller. This series' base includes that commit, so a process that dies during the handshake feeds the same non-fatal fallback as a status failure here, and an optional diff process degrades to the builtin diff on either kind of protocol error.

Signed-off-by: Michael Montalbo <mmontalbo@gmail.com>
---
 sub-process.c | 24 ++++++++++++++++++++++++
 sub-process.h | 10 ++++++++++
 2 files changed, 34 insertions(+)
diff --git a/sub-process.c b/sub-process.c
index 3cef42b088..33bd789618 100644
--- a/sub-process.c
+++ b/sub-process.c
@@ -49,6 +49,30 @@ int subprocess_read_status(int fd, struct strbuf *status)
 	return (len < 0) ? len : 0;
 }
 
+int subprocess_read_status_gently(int fd, struct strbuf *status)
+{
+	for (;;) {
+		int pktlen = -1;
+		enum packet_read_status rs;
+		const char *value;
+
+		rs = packet_read_with_status(fd, NULL, NULL, packet_buffer,
+					     sizeof(packet_buffer), &pktlen,
+					     PACKET_READ_CHOMP_NEWLINE |
+					     PACKET_READ_GENTLE_ON_EOF |
+					     PACKET_READ_GENTLE_ON_READ_ERROR);
+		if (rs == PACKET_READ_FLUSH)
+			return 0;
+		if (rs != PACKET_READ_NORMAL || !pktlen)
+			return -1;
+		if (skip_prefix(packet_buffer, "status=", &value)) {
+			/* the last "status=<foo>" line wins */
+			strbuf_reset(status);
+			strbuf_addstr(status, value);
+		}
+	}
+}
+
 void subprocess_stop_command(struct subprocess_entry *entry)
 {
 	if (!entry)
diff --git a/sub-process.h b/sub-process.h
index 45f1b8e5e3..8655b38897 100644
--- a/sub-process.h
+++ b/sub-process.h
@@ -101,4 +101,14 @@ int subprocess_handshake(struct subprocess_entry *entry,
 
 int subprocess_read_status(int fd, struct strbuf *status);
 
+/*
+ * Like subprocess_read_status(), but a malformed status section fails
+ * instead of dying: a truncated or malformed packet, and an empty
+ * packet where a status line or the terminating flush belongs, return
+ * -1 and leave the stream unusable.  subprocess_read_status() cannot
+ * tell an empty packet from the flush that ends the section, and dies
+ * on a framing error inside packet_read_line_gently().
+ */
+int subprocess_read_status_gently(int fd, struct strbuf *status);
+
 #endif
-- 
2.54.0
Previous: Michael MontalboNext: Michael Montalbo
Message 74 of 81 in “[RFC] diff: add diff.<driver>.process for external hunk providers”
  1. 0/5 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, May 22, 2026
  2. 1/5 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, May 22, 2026
  3. Junio C HamanoMay 22, 2026
  4. Michael MontalboMay 22, 2026
  5. Junio C HamanoMay 24, 2026
  6. Michael MontalboMay 24, 2026
  7. 2/5 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, May 22, 2026
  8. 3/5 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, May 22, 2026
  9. 4/5 blame: consult diff process for zero-hunk detectionMichael Montalbo via GitGitGadget, May 22, 2026
  10. 5/5 diff-process-normalize: add built-in whitespace normalizerMichael Montalbo via GitGitGadget, May 22, 2026
  11. Junio C HamanoMay 22, 2026
  12. Michael MontalboMay 22, 2026
  13. 0/4 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, May 25, 2026
  14. 1/4 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, May 25, 2026
  15. 2/4 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, May 25, 2026
  16. 3/4 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, May 25, 2026
  17. Junio C HamanoMay 26, 2026
  18. Michael MontalboMay 29, 2026
  19. Junio C HamanoMay 26, 2026
  20. Michael MontalboMay 29, 2026
  21. 4/4 blame: consult diff process for zero-hunk detectionMichael Montalbo via GitGitGadget, May 25, 2026
  22. 0/6 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, May 29, 2026
  23. 1/6 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, May 29, 2026
  24. 2/6 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, May 29, 2026
  25. 3/6 sub-process: separate process lifecycle from hashmap managementMichael Montalbo via GitGitGadget, May 29, 2026
  26. 4/6 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, May 29, 2026
  27. Johannes SchindelinJun 7, 2026
  28. Michael MontalboJun 7, 2026
  29. Junio C HamanoJun 8, 2026
  30. Michael MontalboJun 7, 2026
  31. Junio C HamanoJun 8, 2026
  32. Junio C HamanoJun 8, 2026
  33. 5/6 diff: bypass diff process with --no-ext-diff and in format-patchMichael Montalbo via GitGitGadget, May 29, 2026
  34. 6/6 blame: consult diff process for no-hunk detectionMichael Montalbo via GitGitGadget, May 29, 2026
  35. Junio C HamanoMay 31, 2026
  36. Michael MontalboJun 1, 2026
  37. 0/6 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, Jun 14, 2026
  38. 1/6 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, Jun 14, 2026
  39. 2/6 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, Jun 14, 2026
  40. 3/6 sub-process: separate process lifecycle from hashmap managementMichael Montalbo via GitGitGadget, Jun 14, 2026
  41. 4/6 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, Jun 14, 2026
  42. 5/6 diff: bypass diff process with --no-ext-diff and in format-patchMichael Montalbo via GitGitGadget, Jun 14, 2026
  43. 6/6 blame: consult diff process for no-hunk detectionMichael Montalbo via GitGitGadget, Jun 14, 2026
  44. 0/9 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, Jul 15, 2026
  45. 1/9 gitattributes: document how external diff drivers relate to diff featuresMichael Montalbo via GitGitGadget, Jul 15, 2026
  46. 2/9 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, Jul 15, 2026
  47. 3/9 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, Jul 15, 2026
  48. 4/9 sub-process: separate process lifecycle from hashmap managementMichael Montalbo via GitGitGadget, Jul 15, 2026
  49. 5/9 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, Jul 15, 2026
  50. 6/9 diff: bypass diff process with --no-ext-diff and in format-patchMichael Montalbo via GitGitGadget, Jul 15, 2026
  51. 7/9 blame: consult diff process for no-hunk detectionMichael Montalbo via GitGitGadget, Jul 15, 2026
  52. 8/9 diff: consult diff process for --stat countsMichael Montalbo via GitGitGadget, Jul 15, 2026
  53. 9/9 line-log: consult diff process for range trackingMichael Montalbo via GitGitGadget, Jul 15, 2026
  54. Junio C HamanoJul 16, 2026
  55. Michael MontalboJul 16, 2026
  56. 0/9 [RFC] diff: add diff.<driver>.process for external hunk providersMichael Montalbo via GitGitGadget, Jul 26, 2026
  57. 1/9 gitattributes: document how external diff drivers relate to diff featuresMichael Montalbo via GitGitGadget, Jul 26, 2026
  58. 2/9 xdiff: support external hunks via xpparam_tMichael Montalbo via GitGitGadget, Jul 26, 2026
  59. 3/9 userdiff: add diff.<driver>.process configMichael Montalbo via GitGitGadget, Jul 26, 2026
  60. 4/9 sub-process: separate process lifecycle from hashmap managementMichael Montalbo via GitGitGadget, Jul 26, 2026
  61. 5/9 diff: add long-running diff process via diff.<driver>.processMichael Montalbo via GitGitGadget, Jul 26, 2026
  62. 6/9 diff: bypass diff process with --no-ext-diff and in format-patchMichael Montalbo via GitGitGadget, Jul 26, 2026
  63. 7/9 blame: consult diff process for no-hunk detectionMichael Montalbo via GitGitGadget, Jul 26, 2026
  64. 8/9 diff: consult diff process for --stat countsMichael Montalbo via GitGitGadget, Jul 26, 2026
  65. 9/9 line-log: consult diff process for range trackingMichael Montalbo via GitGitGadget, Jul 26, 2026
  66. 0/10 diff: add provider interface and initial providersMichael Montalbo, Aug 1, 2026
  67. 01/10 gitattributes: document how external diff drivers relate to diff featuresMichael Montalbo, Aug 1, 2026
  68. 02/10 diff: introduce a hunk provider interfaceMichael Montalbo, Aug 1, 2026
  69. 03/10 diff-hunks: add the store format, library, and commandMichael Montalbo, Aug 1, 2026
  70. 04/10 diff: record precomputed hunks during stat outputMichael Montalbo, Aug 1, 2026
  71. 05/10 diff: read precomputed hunks for stat outputMichael Montalbo, Aug 1, 2026
  72. 06/10 blame: read precomputed hunksMichael Montalbo, Aug 1, 2026
  73. 07/10 sub-process: separate process lifecycle from hashmap managementMichael Montalbo, Aug 1, 2026
  74. 08/10 sub-process: add a gentle status readMichael Montalbo, Aug 1, 2026
  75. 09/10 userdiff: add diff.<driver>.process configMichael Montalbo, Aug 1, 2026
  76. 10/10 diff: consult oid-only hunk providers via diff.<driver>.processMichael Montalbo, Aug 1, 2026
  77. Michael MontalboAug 4, 2026
  78. Junio C HamanoAug 13, 2026
  79. Phillip WoodAug 4, 2026
  80. Michael MontalboAug 23, 2026
  81. Michael MontalboJun 15, 2026

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.