]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
script: ensure typescript and timing errors do not break terminal
authorSami Kerola <kerolasa@iki.fi>
Sat, 24 Jun 2017 10:48:08 +0000 (11:48 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 26 Jun 2017 13:23:31 +0000 (15:23 +0200)
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>
term-utils/script.c

index f2fc2f59c6684c7ccdd8172bba766fb3628b35d8..19e9976d92539ac97ac0b7b96aa1d17d7e4a3b36 100644 (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);
+               }
        }