script: cleanup --echo

Permanently turn off current stdin ECHO when it is a terminal and enable setting slave ECHO instead.
Fix other minor typos, update documentation.

[kzak@redhat.com: - remove irrelevant changes
                  - keep --echo argument unchanged]

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Soumendra Ganguly 2020-08-27 11:50:25 +02:00 committed by Karel Zak
parent d3f21dca1e
commit 75ccd75a2f
4 changed files with 29 additions and 28 deletions

View File

@ -81,7 +81,7 @@ struct ul_pty {
struct timeval next_callback_time;
unsigned int isterm:1, /* is stdin terminal? */
slave_echo:1; /* keep ECHO on stdin */
slave_echo:1; /* keep ECHO on pty slave */
};
void ul_pty_init_debug(int mask);

View File

@ -146,7 +146,7 @@ static void pty_signals_cleanup(struct ul_pty *pty)
/* call me before fork() */
int ul_pty_setup(struct ul_pty *pty)
{
struct termios slave_attrs;
struct termios attrs;
sigset_t ourset;
int rc = 0;
@ -163,22 +163,22 @@ int ul_pty_setup(struct ul_pty *pty)
rc = -errno;
goto done;
}
attrs = pty->stdin_attrs;
if (pty->slave_echo)
attrs.c_lflag |= ECHO;
else
attrs.c_lflag &= ~ECHO;
ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&pty->win);
/* create master+slave */
rc = openpty(&pty->master, &pty->slave, NULL, &pty->stdin_attrs, &pty->win);
rc = openpty(&pty->master, &pty->slave, NULL, &attrs, &pty->win);
if (rc)
goto done;
/* set the current terminal to raw mode; pty_cleanup() reverses this change on exit */
slave_attrs = pty->stdin_attrs;
cfmakeraw(&slave_attrs);
if (pty->slave_echo)
slave_attrs.c_lflag |= ECHO;
else
slave_attrs.c_lflag &= ~ECHO;
tcsetattr(STDIN_FILENO, TCSANOW, &slave_attrs);
cfmakeraw(&attrs);
tcsetattr(STDIN_FILENO, TCSANOW, &attrs);
} else {
DBG(SETUP, ul_debugobj(pty, "create for non-terminal"));
@ -186,14 +186,14 @@ int ul_pty_setup(struct ul_pty *pty)
if (rc)
goto done;
tcgetattr(pty->slave, &slave_attrs);
tcgetattr(pty->slave, &attrs);
if (pty->slave_echo)
slave_attrs.c_lflag |= ECHO;
attrs.c_lflag |= ECHO;
else
slave_attrs.c_lflag &= ~ECHO;
attrs.c_lflag &= ~ECHO;
tcsetattr(pty->slave, TCSANOW, &slave_attrs);
tcsetattr(pty->slave, TCSANOW, &attrs);
}
sigfillset(&ourset);

View File

@ -91,20 +91,26 @@ the output of a program that behaves differently when its stdout is not a
tty.
.TP
\fB\-E\fR, \fB\-\-echo\fR \fIwhen\fR
This option controls the ECHO flag for the pseudoterminal within the session.
This option controls the ECHO flag for the slave end of the session's pseudoterminal.
The supported modes are
.IR always ,
.IR never ,
or
.IR auto .
.sp
The default is
.I auto
-- in this case, ECHO is disabled if the current standard input is a
terminal iin order to avoid double-echo,
and enabled if standard input is not a terminal
-- in this case, ECHO enabled for the pseudoterminal slave; if
the current standard input is a terminal, ECHO is disabled for it
to prevent double echo; if the current standard input is not a terminal
(for example pipe:
.BR "echo date | script" )
to avoid missing input in the session log.
then keeping ECHO enabled for the pseudoterminal slave enables the standard
input data to be viewed on screen while being recorded to session log
simultaneously.
.sp
Note that 'never' mode affects content of the session output log, because
users input is not repeated on output.
.TP
\fB\-e\fR, \fB\-\-return\fR
Return the exit status of the child process. Uses the same format as bash

View File

@ -208,7 +208,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_(" -e, --return return exit code of the child process\n"), out);
fputs(_(" -f, --flush run flush after each write\n"), out);
fputs(_(" --force use output file even when it is a link\n"), out);
fputs(_(" -E, --echo <when> echo input (auto, always or never)\n"), out);
fputs(_(" -E, --echo <when> echo input in session (auto, always or never)\n"), out);
fputs(_(" -o, --output-limit <size> terminate if output files exceed size\n"), out);
fputs(_(" -q, --quiet be quiet\n"), out);
@ -752,7 +752,7 @@ int main(int argc, char **argv)
.in = { .ident = 'I' },
};
struct ul_pty_callbacks *cb;
int ch, format = 0, caught_signal = 0, rc = 0, echo = 0;
int ch, format = 0, caught_signal = 0, rc = 0, echo = 1;
const char *outfile = NULL, *infile = NULL;
const char *timingfile = NULL, *shell = NULL, *command = NULL;
@ -798,12 +798,7 @@ int main(int argc, char **argv)
script_init_debug();
ON_DBG(PTY, ul_pty_init_debug(0xFFFF));
/* The default is to keep ECHO flag when stdin is not terminal. We need
* it to make stdin (in case of "echo foo | script") log-able and
* visible on terminal, and for backward compatibility.
*/
ctl.isterm = isatty(STDIN_FILENO);
echo = ctl.isterm ? 0 : 1;
while ((ch = getopt_long(argc, argv, "aB:c:eE:fI:O:o:qm:T:t::Vh", longopts, NULL)) != -1) {