diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c index 98774ea4840d6..27b44421fb8ba 100644 --- a/usr.bin/script/script.c +++ b/usr.bin/script/script.c @@ -29,6 +29,11 @@ * SUCH DAMAGE. */ +/* + * 2020-07-31 Soumendra Ganguly + * - fixed playback of curses sessions + */ + #include #ifndef lint __COPYRIGHT("@(#) Copyright (c) 1980, 1992, 1993\ @@ -81,6 +86,7 @@ static int usesleep, rawout; static int quiet, flush; static const char *fname; +static int isterm; static struct termios tt; __dead static void done(void); @@ -327,20 +333,52 @@ record(FILE *fp, char *buf, size_t cc, int direction) err(1, "writev"); } +static void +termset() +{ + struct termios tattr; + + isterm = isatty(STDOUT_FILENO); + if (!isterm) + return; + + if (tcgetattr(STDOUT_FILENO, &tt) != 0) + err(1, "tcgetattr"); + + tattr = tt; + cfmakeraw(&tattr); + tattr.c_lflag |= ISIG; + if (tcsetattr(STDOUT_FILENO, TCSANOW, &tattr) != 0) + err(1, "tcsetattr"); +} + +static void +termreset() +{ + if (isterm) + tcsetattr(STDOUT_FILENO, TCSADRAIN, &tt); + + isterm = 0; +} + static void consume(FILE *fp, off_t len, char *buf, int reg) { size_t l; if (reg) { - if (fseeko(fp, len, SEEK_CUR) == -1) + if (fseeko(fp, len, SEEK_CUR) == -1) { + termreset(); err(1, NULL); + } } else { while (len > 0) { l = MIN(DEF_BUF, len); - if (fread(buf, sizeof(char), l, fp) != l) + if (fread(buf, sizeof(char), l, fp) != l) { + termreset(); err(1, "cannot read buffer"); + } len -= l; } } @@ -367,24 +405,29 @@ playback(FILE *fp) time_t tclock; int reg; + isterm = 0; + if (fstat(fileno(fp), &pst) == -1) - err(1, "fstat failed"); + err(1, "fstat failed"); reg = S_ISREG(pst.st_mode); for (nread = 0; !reg || nread < pst.st_size; nread += save_len) { if (fread(&stamp, sizeof(stamp), 1, fp) != 1) { - if (reg) + if (reg) { + termreset(); err(1, "reading playback header"); - else - break; + } + break; } swapstamp(stamp); save_len = sizeof(stamp); if (reg && stamp.scr_len > - (uint64_t)(pst.st_size - save_len) - nread) + (uint64_t)(pst.st_size - save_len) - nread) { + termreset(); errx(1, "invalid stamp"); + } save_len += stamp.scr_len; tclock = stamp.scr_sec; @@ -398,8 +441,10 @@ playback(FILE *fp) ctime(&tclock)); tsi = tso; (void)consume(fp, stamp.scr_len, buf, reg); + termset(); break; case 'e': + termreset(); if (!quiet) (void)printf("\nScript done on %s", ctime(&tclock)); @@ -421,17 +466,21 @@ playback(FILE *fp) tsi = tso; while (stamp.scr_len > 0) { l = MIN(DEF_BUF, stamp.scr_len); - if (fread(buf, sizeof(char), l, fp) != l) + if (fread(buf, sizeof(char), l, fp) != l) { + termreset(); err(1, "cannot read buffer"); + } (void)write(STDOUT_FILENO, buf, l); stamp.scr_len -= l; } break; default: + termreset(); errx(1, "invalid direction"); } } + termreset(); (void)fclose(fp); exit(0); }