From: Junio C Hamano <gitster@pobox.com>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, Johannes Schindelin <Johannes.Schindelin@gmx.de>
Subject: Re: [RFC/PATCH] pipe_command(): mark stdin descriptor as non-blocking
Date: Tue, 02 Aug 2022 08:04:39 -0700 [thread overview]
Message-ID: <xmqqbkt2k7p4.fsf@gitster.g> (raw)
In-Reply-To: <YuikU//9OrdpKQcE@coredump.intra.peff.net> (Jeff King's message of "Tue, 2 Aug 2022 00:13:07 -0400")
Jeff King <peff@peff.net> writes:
> Our pipe_command() helper lets you both write to and read from a child
> process on its stdin/stdout. It's supposed to work without deadlocks
> because we use poll() to check when descriptors are ready for reading or
> writing. But there's a bug: if both the data to be written and the data
> to be read back exceed the pipe buffer, we'll deadlock.
> ...
> If you set add.interactive.useBuiltin to false, the problem goes away,
> because now we're not using pipe_command() anymore (instead, that part
> happens in perl). But this isn't a bug in the interactive code at all.
> It's the underlying pipe_command() code which is broken, and has been
> all along.
> ...
> The obvious fix is to put the descriptor into non-blocking mode, and
> indeed, that makes the problem go away. Callers shouldn't need to
> care, because they never see the descriptor (they hand us a buffer to
> feed into it).
Thanks for a very well reasoned and explained patch.
> - more importantly, I'm not sure of the portability implications of
> the fix. This is our first use of O_NONBLOCK outside of the
> compat/simple-ipc unix-socket code. Do we need to abstract this
> behind a compat/ layer for Windows?
Yup. A very good question to ask for the platform maintainer.
> run-command.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/run-command.c b/run-command.c
> index 14f17830f5..45bffb4b11 100644
> --- a/run-command.c
> +++ b/run-command.c
> @@ -1418,6 +1418,14 @@ static int pump_io(struct io_pump *slots, int nr)
> return 0;
> }
>
> +static int make_nonblock(int fd)
> +{
> + int flags = fcntl(fd, F_GETFL);
> + if (flags < 0)
> + return -1;
> + flags |= O_NONBLOCK;
> + return fcntl(fd, F_SETFL, flags);
> +}
>
> int pipe_command(struct child_process *cmd,
> const char *in, size_t in_len,
> @@ -1438,6 +1446,15 @@ int pipe_command(struct child_process *cmd,
> return -1;
>
> if (in) {
> + if (make_nonblock(cmd->in) < 0) {
> + error_errno("unable to make pipe non-blocking");
> + close(cmd->in);
> + if (out)
> + close(cmd->out);
> + if (err)
> + close(cmd->err);
> + return -1;
> + }
> io[nr].fd = cmd->in;
> io[nr].type = POLLOUT;
> io[nr].u.out.buf = in;
next prev parent reply other threads:[~2022-08-02 15:04 UTC|newest]
Thread overview: 44+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-02 4:13 [RFC/PATCH] pipe_command(): mark stdin descriptor as non-blocking Jeff King
2022-08-02 15:04 ` Junio C Hamano [this message]
2022-08-02 15:39 ` Jeff King
2022-08-02 16:16 ` Junio C Hamano
2022-08-03 3:53 ` [PATCH v2] " Jeff King
2022-08-03 16:45 ` René Scharfe
2022-08-03 17:20 ` Jeff King
2022-08-03 21:56 ` René Scharfe
2022-08-05 15:36 ` Jeff King
2022-08-05 21:13 ` René Scharfe
2022-08-07 10:15 ` René Scharfe
2022-08-07 17:41 ` Jeff King
2022-08-10 5:39 ` René Scharfe
2022-08-10 19:53 ` Jeff King
2022-08-10 22:35 ` René Scharfe
2022-08-11 8:52 ` Jeff King
2022-08-10 5:39 ` [PATCH] mingw: handle writes to non-blocking pipe René Scharfe
2022-08-10 9:07 ` Johannes Schindelin
2022-08-10 20:02 ` Jeff King
2022-08-10 22:34 ` René Scharfe
2022-08-11 8:47 ` Jeff King
2022-08-11 17:35 ` René Scharfe
2022-08-11 18:20 ` Jeff King
2022-08-14 15:37 ` René Scharfe
2022-08-17 5:39 ` Jeff King
2022-08-17 6:04 ` [PATCH v2 0/6] fix pipe_command() deadlock Jeff King
2022-08-17 6:04 ` [PATCH v2 1/6] compat: add function to enable nonblocking pipes Jeff King
2022-08-17 20:23 ` Junio C Hamano
2022-08-18 5:41 ` Jeff King
2022-08-17 6:05 ` [PATCH v2 2/6] nonblock: support Windows Jeff King
2022-08-17 6:06 ` [PATCH v2 3/6] git-compat-util: make MAX_IO_SIZE define globally available Jeff King
2022-08-17 6:08 ` [PATCH v2 4/6] pipe_command(): avoid xwrite() for writing to pipe Jeff King
2022-08-17 6:09 ` [PATCH v2 5/6] pipe_command(): handle ENOSPC when writing to a pipe Jeff King
2022-08-17 18:57 ` Junio C Hamano
2022-08-18 5:38 ` Jeff King
2022-08-17 6:10 ` [PATCH v2 6/6] pipe_command(): mark stdin descriptor as non-blocking Jeff King
2022-08-17 6:20 ` [PATCH v2 0/6] fix pipe_command() deadlock Jeff King
2022-08-19 21:19 ` René Scharfe
2022-08-20 7:04 ` Jeff King
2022-08-07 10:14 ` [PATCH v2] pipe_command(): mark stdin descriptor as non-blocking René Scharfe
2022-08-08 12:55 ` Johannes Schindelin
2022-08-08 12:59 ` Johannes Schindelin
2022-08-09 13:04 ` Jeff King
2022-08-09 22:10 ` Johannes Schindelin
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=xmqqbkt2k7p4.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=peff@peff.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.