From: Junio C Hamano <gitster@pobox.com>
To: "Michael Montalbo via GitGitGadget" <gitgitgadget@gmail.com>
Cc: git@vger.kernel.org, Michael Montalbo <mmontalbo@gmail.com>
Subject: Re: [PATCH] sub-process: use gentle handshake to avoid die() on startup failure
Date: Mon, 01 Jun 2026 15:43:13 +0900 [thread overview]
Message-ID: <xmqqo6hu92wu.fsf@gitster.g> (raw)
In-Reply-To: <pull.2133.git.1780287309846.gitgitgadget@gmail.com> (Michael Montalbo via GitGitGadget's message of "Mon, 01 Jun 2026 04:15:09 +0000")
"Michael Montalbo via GitGitGadget" <gitgitgadget@gmail.com> writes:
> diff --git a/sub-process.c b/sub-process.c
> index 83bf0a0e82..22c68bd10d 100644
> --- a/sub-process.c
> +++ b/sub-process.c
> @@ -132,18 +132,19 @@ static int handshake_version(struct child_process *process,
> if (packet_flush_gently(process->in))
> return error("Could not write flush packet");
>
> - if (!(line = packet_read_line(process->out, NULL)) ||
> + if (packet_read_line_gently(process->out, NULL, &line) <= 0 ||
> !skip_prefix(line, welcome_prefix, &p) ||
> strcmp(p, "-server"))
> return error("Unexpected line '%s', expected %s-server",
> line ? line : "<flush packet>", welcome_prefix);
If `packet_read_line_gently()` returns `< 0` (due to an EOF or read
error), `line` will be `NULL`. The error message printed will be:
`Unexpected line '<flush packet>', expected filter-server`
This is misleading when the remote process didn't send a flush
packet; it hung up or crashed.
> - if (!(line = packet_read_line(process->out, NULL)) ||
> + if (packet_read_line_gently(process->out, NULL, &line) <= 0 ||
> !skip_prefix(line, "version=", &p) ||
> strtol_i(p, 10, chosen_version))
> return error("Unexpected line '%s', expected version",
> line ? line : "<flush packet>");
Ditto.
> - if ((line = packet_read_line(process->out, NULL)))
> - return error("Unexpected line '%s', expected flush", line);
> + if (packet_read_line_gently(process->out, NULL, &line) < 0 || line)
> + return error("Unexpected line '%s', expected flush",
> + line ? line : "<read error>");
We catch error return (< 0) or a line with payload (!!line) and
report an error here, because we want to see <flush> here. OK.
> @@ -171,7 +172,7 @@ static int handshake_capabilities(struct child_process *process,
> if (packet_flush_gently(process->in))
> return error("Could not write flush packet");
>
> - while ((line = packet_read_line(process->out, NULL))) {
> + while (packet_read_line_gently(process->out, NULL, &line) > 0) {
> const char *p;
> if (!skip_prefix(line, "capability=", &p))
> continue;
While this correctly stops the loop if packet_read_line_gently()
returns a non-positive value, doesn't it introduce a subtle bug?
`packet_read_line_gently()` returns:
- `> 0` for a normal line (which keeps the loop running).
- `0` for a flush packet (which we expect as the normal terminator
of the capabilities list, stopping the loop).
- `< 0` for an EOF or read error (which also stops the loop).
In the original code, an EOF or read error would have caused
`packet_read_line()` to call `die()`, aborting the process.
With the new code, if the child process dies or closes its pipe
during the capabilities handshake, the loop will terminate, and the
function will return `0` (success). The parent process will proceed
as if the capabilities were successfully negotiated. Any further
communication with the child process would fail so the damage may
not be huge, but somebody must check if the loop terminated because
of a flush packet, or an error.
while (1) {
const char *p;
int len = packet_read_line_gently(process->out, NULL, &line);
if (len < 0)
return error(_("subprocess `%s` failed to give capabilities"),
process->args.v[0]);
if (!skip_prefix(line, "capability=", &p))
continue;
...
or something, perhaps?
next prev parent reply other threads:[~2026-06-01 6:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-01 4:15 [PATCH] sub-process: use gentle handshake to avoid die() on startup failure Michael Montalbo via GitGitGadget
2026-06-01 6:43 ` Junio C Hamano [this message]
2026-06-01 15:51 ` Michael Montalbo
2026-06-01 21:20 ` [PATCH v2] " Michael Montalbo via GitGitGadget
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=xmqqo6hu92wu.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
--cc=gitgitgadget@gmail.com \
--cc=mmontalbo@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox