From 75ccd75a2fa1194c6415c47b0024a438e26f1ad7 Mon Sep 17 00:00:00 2001 From: Soumendra Ganguly Date: Thu, 27 Aug 2020 11:50:25 +0200 Subject: [PATCH] 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 --- include/pty-session.h | 2 +- lib/pty-session.c | 30 +++++++++++++++--------------- term-utils/script.1 | 16 +++++++++++----- term-utils/script.c | 9 ++------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/include/pty-session.h b/include/pty-session.h index 19656f908..0c9ccc6f0 100644 --- a/include/pty-session.h +++ b/include/pty-session.h @@ -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); diff --git a/lib/pty-session.c b/lib/pty-session.c index e41d7bd33..06b2a49d6 100644 --- a/lib/pty-session.c +++ b/lib/pty-session.c @@ -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); diff --git a/term-utils/script.1 b/term-utils/script.1 index 49ba58224..67c8f0c13 100644 --- a/term-utils/script.1 +++ b/term-utils/script.1 @@ -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 diff --git a/term-utils/script.c b/term-utils/script.c index b91c037d0..c7f3250de 100644 --- a/term-utils/script.c +++ b/term-utils/script.c @@ -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 echo input (auto, always or never)\n"), out); + fputs(_(" -E, --echo echo input in session (auto, always or never)\n"), out); fputs(_(" -o, --output-limit 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) {