unofficial mirror of meta@public-inbox.org
 help / color / mirror / Atom feed
From: Eric Wong <e@80x24.org>
To: meta@public-inbox.org
Subject: [PATCH] lei: don't read --stdin terminals from daemon
Date: Sun, 12 Nov 2023 13:12:33 +0000	[thread overview]
Message-ID: <20231112131233.718614-1-e@80x24.org> (raw)

We must use a foreground process to read from terminals
on stdin, otherwise weird things like lost keystrokes and
EIO can happen.  So take advantage of ->send_exec_cmd to
spawn `cat' in the same way we spawn MUAs, pagers,
`git config --edit' and `git credential' from script/lei
---
 lib/PublicInbox/InputPipe.pm | 33 +--------------------------------
 lib/PublicInbox/LEI.pm       | 10 +++++++++-
 2 files changed, 10 insertions(+), 33 deletions(-)

diff --git a/lib/PublicInbox/InputPipe.pm b/lib/PublicInbox/InputPipe.pm
index 232f20e8..ee5bda59 100644
--- a/lib/PublicInbox/InputPipe.pm
+++ b/lib/PublicInbox/InputPipe.pm
@@ -6,31 +6,6 @@ package PublicInbox::InputPipe;
 use v5.12;
 use parent qw(PublicInbox::DS);
 use PublicInbox::Syscall qw(EPOLLIN);
-use POSIX ();
-use Carp qw(croak carp);
-
-# I'm not sure what I'm doing w.r.t terminals.
-# FIXME needs non-interactive tests
-sub unblock_tty ($) {
-	my ($self) = @_;
-	my $fd = fileno($self->{sock});
-	my $t = POSIX::Termios->new;
-	$t->getattr($fd) or croak("tcgetattr($fd): $!");
-	return if $t->getlflag & POSIX::ICANON; # line-oriented, good
-
-	# make noncanonical mode TTYs behave like a O_NONBLOCK pipe.
-	# O_NONBLOCK itself isn't well-defined, here, so rely on VMIN + VTIME
-	my ($vmin, $vtime) = ($t->getcc(POSIX::VMIN), $t->getcc(POSIX::VTIME));
-	return if $vmin == 1 && $vtime == 0;
-
-	$t->setcc(POSIX::VMIN, 1); # 1 byte minimum
-	$t->setcc(POSIX::VTIME, 0); # no timeout
-	$t->setattr($fd, POSIX::TCSANOW) or croak("tcsetattr($fd): $!");
-
-	$t->setcc(POSIX::VMIN, $vmin);
-	$t->setcc(POSIX::VTIME, $vtime);
-	$self->{restore_termios} = $t;
-}
 
 sub consume {
 	my ($in, $cb, @args) = @_;
@@ -41,18 +16,12 @@ sub consume {
 		$self->requeue;
 	} elsif (-p _ || -S _) { # O_NONBLOCK for sockets and pipes
 		$in->blocking(0);
-	} elsif (-t $in) { # isatty(3) can't use `_' stat cache
-		unblock_tty($self);
 	}
 	$self;
 }
 
 sub close { # idempotent
 	my ($self) = @_;
-	if (my $t = delete($self->{restore_termios})) {
-		my $fd = fileno($self->{sock} // return);
-		$t->setattr($fd, POSIX::TCSANOW) or carp("tcsetattr($fd): $!")
-	}
 	$self->{-need_rq} ? delete($self->{sock}) : $self->SUPER::close
 }
 
@@ -67,7 +36,7 @@ sub event_step {
 			$self->{cb}->($self, @{$self->{args}}, '');
 			$self->close
 		} elsif ($!{EAGAIN}) { # rely on EPOLLIN
-		} elsif ($!{EINTR}) { # rely on EPOLLIN for sockets/pipes/tty
+		} elsif ($!{EINTR}) { # rely on EPOLLIN for sockets/pipes
 			$self->requeue if $self->{-need_rq};
 		} else { # another error
 			$self->{cb}->($self, @{$self->{args}}, undef);
diff --git a/lib/PublicInbox/LEI.pm b/lib/PublicInbox/LEI.pm
index 681044c8..77acb5a1 100644
--- a/lib/PublicInbox/LEI.pm
+++ b/lib/PublicInbox/LEI.pm
@@ -1577,7 +1577,15 @@ sub _stdin_cb { # PublicInbox::InputPipe::consume callback for --stdin
 sub slurp_stdin {
 	my ($lei, $cb) = @_;
 	require PublicInbox::InputPipe;
-	PublicInbox::InputPipe::consume($lei->{0}, \&_stdin_cb, $lei, $cb);
+	my $in = $lei->{0};
+	if (-t $in) { # run cat via script/lei and read from it
+		$in = undef;
+		use autodie qw(pipe);
+		pipe($in, my $wr);
+		say { $lei->{2} } '# enter query, Ctrl-D when done';
+		send_exec_cmd($lei, [ $lei->{0}, $wr ], ['cat'], {});
+	}
+	PublicInbox::InputPipe::consume($in, \&_stdin_cb, $lei, $cb);
 }
 
 1;

                 reply	other threads:[~2023-11-12 13:12 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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

  List information: https://public-inbox.org/README

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20231112131233.718614-1-e@80x24.org \
    --to=e@80x24.org \
    --cc=meta@public-inbox.org \
    /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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).