From: Junio C Hamano <gitster@pobox.com>
To: Phillip Wood <phillip.wood123@gmail.com>
Cc: "Git Mailing List" <git@vger.kernel.org>,
"Phillip Wood" <phillip.wood@dunelm.org.uk>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>,
"Carlo Arenas" <carenas@gmail.com>,
"Johannes Schindelin" <Johannes.Schindelin@gmx.de>,
"Ramsay Jones" <ramsay@ramsayjones.plus.com>
Subject: Re: [PATCH v3 2/4] terminal: don't assume stdin is /dev/tty
Date: Tue, 15 Mar 2022 10:42:59 -0700 [thread overview]
Message-ID: <xmqqzglrdsd8.fsf@gitster.g> (raw)
In-Reply-To: <20220315105723.19398-3-phillip.wood123@gmail.com> (Phillip Wood's message of "Tue, 15 Mar 2022 10:57:21 +0000")
Phillip Wood <phillip.wood123@gmail.com> writes:
> diff --git a/compat/terminal.c b/compat/terminal.c
> index da2f788137..bfbde3c1af 100644
> --- a/compat/terminal.c
> +++ b/compat/terminal.c
> @@ -23,21 +23,28 @@ static void restore_term_on_signal(int sig)
> static int term_fd = -1;
The variable can be -1 to signal "no valid file descriptor".
> static struct termios old_term;
>
> +static void close_term_fd(void)
> +{
> + if (term_fd)
> + close(term_fd);
> + term_fd = -1;
> +}
> +
And we use that negative value after closing it.
The check before closing it is wrong. It should be
if (0 <= term_fd)
instead. Or we could mimick the beginning of restore_term(), i.e.
if (term_fd < 0)
return;
close(term_fd);
term_fd = -1;
> void restore_term(void)
> {
> if (term_fd < 0)
> return;
>
> tcsetattr(term_fd, TCSAFLUSH, &old_term);
> - close(term_fd);
> - term_fd = -1;
> + close_term_fd();
Because we come this far only when term_fd is valid, this change is
a no-op. If we are adding more calls to close_term_fd(), it may be
a good abstraction.
> sigchain_pop_common();
> }
>
> int save_term(enum save_term_flags flags)
> {
> if (term_fd < 0)
> - term_fd = open("/dev/tty", O_RDWR);
> + term_fd = (flags & SAVE_TERM_STDIN) ? 0
> + : open("/dev/tty", O_RDWR);
We can avoid overly long line by wrapping differently:
term_fd = ((flags & SAVE_TERM_STDIN)
? 0
: open("/dev/tty", O_RDWR));
We can turn our head sideways to see the parse tree this way.
> @@ -66,8 +73,7 @@ static int disable_bits(enum save_term_flags flags, tcflag_t bits)
>
> sigchain_pop_common();
> error:
> - close(term_fd);
> - term_fd = -1;
> + close_term_fd();
OK.
> @@ -362,7 +368,7 @@ int read_key_without_echo(struct strbuf *buf)
> static int warning_displayed;
> int ch;
>
> - if (warning_displayed || enable_non_canonical(0) < 0) {
> + if (warning_displayed || enable_non_canonical(SAVE_TERM_STDIN) < 0) {
> if (!warning_displayed) {
> warning("reading single keystrokes not supported on "
> "this platform; reading line instead");
The validity of this change is harder to see with only what we have
in the patch, but the control flow is
enable_non_canonical(bits)
-> disable_bits(bits, ...)
-> save_term(bits)
And we are passing SAVE_TERM_STDIN to say "reuse fd #0 and save the
terminal settings of it, instead of opening /dev/tty anew".
What happens if FD#0 is *not* connected to a tty, by the way?
tcgetattr() in save_term() would fail, without clearing term_fd
(i.e. term_fd is still 0 when save_term() returns a failure), and
goes to the error code path, where close_term_fd() is called.
Because we have the "if (term_fd)" bug in save_term(), this bug is
hidden, but I think save_term() upon seeing a failure from tcgetattr()
should clear term_fd to limit the damage, especially when it is trying
to futz with caller supplied FD#0, not the tty it opened itself?
> diff --git a/compat/terminal.h b/compat/terminal.h
> index aeb24c9478..79ed00cf61 100644
> --- a/compat/terminal.h
> +++ b/compat/terminal.h
> @@ -4,6 +4,8 @@
> enum save_term_flags {
> /* Save input and output settings */
> SAVE_TERM_DUPLEX = 1 << 0,
> + /* Save stdin rather than /dev/tty (fails if stdin is not a terminal) */
> + SAVE_TERM_STDIN = 1 << 1,
> };
>
> /*
next prev parent reply other threads:[~2022-03-15 17:43 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-04 13:11 [PATCH 0/4] builtin add -p: hopefully final readkey fixes Phillip Wood
2022-03-04 13:11 ` [PATCH 1/4] terminal: use flags for save_term() Phillip Wood
2022-03-04 20:40 ` Ramsay Jones
2022-03-07 11:11 ` Phillip Wood
2022-03-07 20:21 ` Ramsay Jones
2022-03-08 10:41 ` Phillip Wood
2022-03-05 14:02 ` Ævar Arnfjörð Bjarmason
2022-03-07 10:45 ` Phillip Wood
2022-03-07 12:06 ` Ævar Arnfjörð Bjarmason
2022-03-04 13:11 ` [PATCH 2/4] terminal: don't assume stdin is /dev/tty Phillip Wood
2022-03-04 20:42 ` Ramsay Jones
2022-03-04 13:11 ` [PATCH 3/4] terminal: work around macos poll() bug Phillip Wood
2022-03-04 13:11 ` [PATCH 4/4] terminal: restore settings on SIGTSTP Phillip Wood
2022-03-05 13:59 ` Ævar Arnfjörð Bjarmason
2022-03-07 10:53 ` Phillip Wood
2022-03-07 11:49 ` Ævar Arnfjörð Bjarmason
2022-03-07 13:49 ` Phillip Wood
2022-03-07 14:45 ` Ævar Arnfjörð Bjarmason
2022-03-08 10:54 ` Phillip Wood
2022-03-09 12:19 ` Johannes Schindelin
2022-03-10 16:06 ` Phillip Wood
2022-03-09 11:03 ` [PATCH v2 0/4] builtin add -p: hopefully final readkey fixes Phillip Wood
2022-03-09 11:03 ` [PATCH v2 1/4] terminal: use flags for save_term() Phillip Wood
2022-03-11 16:52 ` Carlo Arenas
2022-03-14 10:49 ` Phillip Wood
2022-03-09 11:03 ` [PATCH v2 2/4] terminal: don't assume stdin is /dev/tty Phillip Wood
2022-03-09 11:03 ` [PATCH v2 3/4] terminal: work around macos poll() bug Phillip Wood
2022-03-10 13:35 ` Ævar Arnfjörð Bjarmason
2022-03-10 16:02 ` Phillip Wood
2022-03-10 18:02 ` Junio C Hamano
2022-03-09 11:03 ` [PATCH v2 4/4] terminal: restore settings on SIGTSTP Phillip Wood
2022-03-09 23:10 ` [PATCH v2 0/4] builtin add -p: hopefully final readkey fixes Junio C Hamano
2022-03-09 23:37 ` Junio C Hamano
2022-03-10 13:28 ` Phillip Wood
2022-03-10 18:18 ` Phillip Wood
2022-03-10 18:53 ` Junio C Hamano
2022-03-10 13:25 ` Johannes Schindelin
2022-03-10 16:08 ` Phillip Wood
2022-03-15 10:57 ` [PATCH v3 " Phillip Wood
2022-03-15 10:57 ` [PATCH v3 1/4] terminal: use flags for save_term() Phillip Wood
2022-03-15 10:57 ` [PATCH v3 2/4] terminal: don't assume stdin is /dev/tty Phillip Wood
2022-03-15 17:42 ` Junio C Hamano [this message]
2022-03-15 18:01 ` rsbecker
2022-03-15 19:05 ` Junio C Hamano
2022-03-15 19:38 ` rsbecker
2022-03-15 10:57 ` [PATCH v3 3/4] terminal: work around macos poll() bug Phillip Wood
2022-03-15 10:57 ` [PATCH v3 4/4] terminal: restore settings on SIGTSTP Phillip Wood
2022-03-15 17:51 ` Junio C Hamano
2022-03-16 18:54 ` [PATCH v4 0/4] builtin add -p: hopefully final readkey fixes Phillip Wood
2022-03-16 18:54 ` [PATCH v4 1/4] terminal: use flags for save_term() Phillip Wood
2022-03-16 18:54 ` [PATCH v4 2/4] terminal: don't assume stdin is /dev/tty Phillip Wood
2022-03-16 18:54 ` [PATCH v4 3/4] terminal: work around macos poll() bug Phillip Wood
2022-03-16 18:54 ` [PATCH v4 4/4] terminal: restore settings on SIGTSTP Phillip Wood
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=xmqqzglrdsd8.fsf@gitster.g \
--to=gitster@pobox.com \
--cc=Johannes.Schindelin@gmx.de \
--cc=avarab@gmail.com \
--cc=carenas@gmail.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood123@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
--cc=ramsay@ramsayjones.plus.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 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.