script: ensure typescript and timing errors do not break terminal

Earlier when typescript file failed new line after the error did not cause
carriage return.  Here is an example how prompt> travels to wrong place:

prompt> script 0500-perms/typescript
Script started, file is 0500-perms/typescript
script: cannot open 0500-perms/typescript: Permission denied
                                                            prompt>

But that wasn't quite as bad as what happen with timing file, that at
failure left terminal to state where a reset(1) run was needed.

[kzak@redhat.com: - move code to restore_tty()]

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Sami Kerola 2017-06-24 11:48:08 +01:00 committed by Karel Zak
parent 83893f2678
commit 8198052c9e
1 changed files with 22 additions and 7 deletions

View File

@ -190,12 +190,23 @@ static void die_if_link(const struct script_control *ctl)
"Program not started."), ctl->fname);
}
static void restore_tty(struct script_control *ctl, int mode)
{
struct termios rtt;
if (!ctl->isterm)
return;
rtt = ctl->attrs;
tcsetattr(STDIN_FILENO, mode, &rtt);
}
static void __attribute__((__noreturn__)) done(struct script_control *ctl)
{
DBG(MISC, ul_debug("done!"));
if (ctl->isterm)
tcsetattr(STDIN_FILENO, TCSADRAIN, &ctl->attrs);
restore_tty(ctl, TCSADRAIN);
if (!ctl->quiet && ctl->typescriptfp)
printf(_("Script done, file is %s\n"), ctl->fname);
#ifdef HAVE_LIBUTEMPTER
@ -423,15 +434,19 @@ static void do_io(struct script_control *ctl)
if ((ctl->typescriptfp =
fopen(ctl->fname, ctl->append ? "a" UL_CLOEXECSTR : "w" UL_CLOEXECSTR)) == NULL) {
restore_tty(ctl, TCSANOW);
warn(_("cannot open %s"), ctl->fname);
fail(ctl);
}
if (ctl->timing) {
if (!ctl->tname) {
if (!(ctl->timingfp = fopen("/dev/stderr", "w" UL_CLOEXECSTR)))
err(EXIT_FAILURE, _("cannot open %s"), "/dev/stderr");
} else if (!(ctl->timingfp = fopen(ctl->tname, "w" UL_CLOEXECSTR)))
err(EXIT_FAILURE, _("cannot open %s"), ctl->tname);
const char *tname = ctl->tname ? ctl->tname : "/dev/stderr";
if (!(ctl->timingfp = fopen(tname, "w" UL_CLOEXECSTR))) {
restore_tty(ctl, TCSANOW);
warn(_("cannot open %s"), tname);
fail(ctl);
}
}