PR/55531: Soumendra Ganguly:
- add more error handling - handle -p when not a terminal - call termreset() before printing script done, so that it is printed correctly Also: - use ssize_t/size_t instead of int - use EXIT_SUCCESS/EXIT_FAILURE - check result of fork() against -1
This commit is contained in:
parent
5c415852fa
commit
4f5bb74d62
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: script.c,v 1.22 2020/08/01 17:31:06 christos Exp $ */
|
||||
/* $NetBSD: script.c,v 1.23 2020/08/02 16:23:33 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1980, 1992, 1993
|
||||
|
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1992, 1993\
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)script.c 8.1 (Berkeley) 6/6/93";
|
||||
#endif
|
||||
__RCSID("$NetBSD: script.c,v 1.22 2020/08/01 17:31:06 christos Exp $");
|
||||
__RCSID("$NetBSD: script.c,v 1.23 2020/08/02 16:23:33 christos Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -76,7 +76,7 @@ struct stamp {
|
|||
static FILE *fscript;
|
||||
static int master, slave;
|
||||
static int child, subchild;
|
||||
static int outcc;
|
||||
static size_t outcc;
|
||||
static int usesleep, rawout;
|
||||
static int quiet, flush;
|
||||
static const char *fname;
|
||||
|
@ -97,7 +97,8 @@ __dead static void playback(FILE *);
|
|||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int cc;
|
||||
ssize_t scc;
|
||||
size_t cc;
|
||||
struct termios rtt;
|
||||
struct winsize win;
|
||||
int aflg, pflg, ch;
|
||||
|
@ -139,7 +140,7 @@ main(int argc, char *argv[])
|
|||
(void)fprintf(stderr,
|
||||
"Usage: %s [-c <command>][-adfpqr] [file]\n",
|
||||
getprogname());
|
||||
exit(1);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
@ -150,32 +151,43 @@ main(int argc, char *argv[])
|
|||
fname = "typescript";
|
||||
|
||||
if ((fscript = fopen(fname, pflg ? "r" : aflg ? "a" : "w")) == NULL)
|
||||
err(1, "fopen %s", fname);
|
||||
err(EXIT_FAILURE, "fopen %s", fname);
|
||||
|
||||
if (pflg)
|
||||
playback(fscript);
|
||||
|
||||
(void)tcgetattr(STDIN_FILENO, &tt);
|
||||
(void)ioctl(STDIN_FILENO, TIOCGWINSZ, &win);
|
||||
if (openpty(&master, &slave, NULL, &tt, &win) == -1)
|
||||
err(1, "openpty");
|
||||
isterm = isatty(STDIN_FILENO);
|
||||
if (isterm) {
|
||||
if (tcgetattr(STDIN_FILENO, &tt) == -1)
|
||||
err(EXIT_FAILURE, "tcgetattr");
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) == -1)
|
||||
err(EXIT_FAILURE, "ioctl");
|
||||
if (openpty(&master, &slave, NULL, &tt, &win) == -1)
|
||||
err(EXIT_FAILURE, "openpty");
|
||||
} else {
|
||||
if (openpty(&master, &slave, NULL, NULL, NULL) == -1)
|
||||
err(EXIT_FAILURE, "openpty");
|
||||
}
|
||||
|
||||
if (!quiet)
|
||||
(void)printf("Script started, output file is %s\n", fname);
|
||||
rtt = tt;
|
||||
cfmakeraw(&rtt);
|
||||
rtt.c_lflag &= ~ECHO;
|
||||
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
|
||||
|
||||
if (isterm) {
|
||||
rtt = tt;
|
||||
cfmakeraw(&rtt);
|
||||
rtt.c_lflag &= ~ECHO;
|
||||
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
|
||||
}
|
||||
|
||||
(void)signal(SIGCHLD, finish);
|
||||
child = fork();
|
||||
if (child < 0) {
|
||||
if (child == -1) {
|
||||
warn("fork");
|
||||
fail();
|
||||
}
|
||||
if (child == 0) {
|
||||
subchild = child = fork();
|
||||
if (child < 0) {
|
||||
if (child == -1) {
|
||||
warn("fork");
|
||||
fail();
|
||||
}
|
||||
|
@ -187,14 +199,15 @@ main(int argc, char *argv[])
|
|||
|
||||
if (!rawout)
|
||||
(void)fclose(fscript);
|
||||
while ((cc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) {
|
||||
while ((scc = read(STDIN_FILENO, ibuf, BUFSIZ)) > 0) {
|
||||
cc = (size_t)scc;
|
||||
if (rawout)
|
||||
record(fscript, ibuf, cc, 'i');
|
||||
(void)write(master, ibuf, cc);
|
||||
}
|
||||
done();
|
||||
/* NOTREACHED */
|
||||
return (0);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -215,7 +228,8 @@ static void
|
|||
dooutput(void)
|
||||
{
|
||||
struct itimerval value;
|
||||
int cc;
|
||||
ssize_t scc;
|
||||
size_t cc;
|
||||
time_t tvec;
|
||||
char obuf[BUFSIZ];
|
||||
|
||||
|
@ -232,9 +246,10 @@ dooutput(void)
|
|||
value.it_value = value.it_interval;
|
||||
(void)setitimer(ITIMER_REAL, &value, NULL);
|
||||
for (;;) {
|
||||
cc = read(master, obuf, sizeof (obuf));
|
||||
if (cc <= 0)
|
||||
scc = read(master, obuf, sizeof(obuf));
|
||||
if (scc <= 0)
|
||||
break;
|
||||
cc = (size_t)scc;
|
||||
(void)write(1, obuf, cc);
|
||||
if (rawout)
|
||||
record(fscript, obuf, cc, 'o');
|
||||
|
@ -301,11 +316,12 @@ done(void)
|
|||
(void)fclose(fscript);
|
||||
(void)close(master);
|
||||
} else {
|
||||
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt);
|
||||
if (isterm)
|
||||
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &tt);
|
||||
if (!quiet)
|
||||
(void)printf("Script done, output file is %s\n", fname);
|
||||
}
|
||||
exit(0);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -325,7 +341,7 @@ record(FILE *fp, char *buf, size_t cc, int direction)
|
|||
iov[1].iov_len = cc;
|
||||
iov[1].iov_base = buf;
|
||||
if (writev(fileno(fp), &iov[0], 2) == -1)
|
||||
err(1, "writev");
|
||||
err(EXIT_FAILURE, "writev");
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -335,13 +351,13 @@ consume(FILE *fp, off_t len, char *buf, int reg)
|
|||
|
||||
if (reg) {
|
||||
if (fseeko(fp, len, SEEK_CUR) == -1)
|
||||
err(1, NULL);
|
||||
err(EXIT_FAILURE, NULL);
|
||||
}
|
||||
else {
|
||||
while (len > 0) {
|
||||
l = MIN(DEF_BUF, len);
|
||||
if (fread(buf, sizeof(char), l, fp) != l)
|
||||
err(1, "cannot read buffer");
|
||||
err(EXIT_FAILURE, "cannot read buffer");
|
||||
len -= l;
|
||||
}
|
||||
}
|
||||
|
@ -365,21 +381,21 @@ termset(void)
|
|||
if (!isterm)
|
||||
return;
|
||||
|
||||
if (tcgetattr(STDOUT_FILENO, &tt) != 0)
|
||||
err(1, "tcgetattr");
|
||||
if (tcgetattr(STDOUT_FILENO, &tt) == -1)
|
||||
err(EXIT_FAILURE, "tcgetattr");
|
||||
|
||||
traw = tt;
|
||||
cfmakeraw(&traw);
|
||||
traw.c_lflag |= ISIG;
|
||||
if (tcsetattr(STDOUT_FILENO, TCSANOW, &traw) != 0)
|
||||
err(1, "tcsetattr");
|
||||
if (tcsetattr(STDOUT_FILENO, TCSANOW, &traw) == -1)
|
||||
err(EXIT_FAILURE, "tcsetattr");
|
||||
}
|
||||
|
||||
static void
|
||||
termreset(void)
|
||||
{
|
||||
if (isterm)
|
||||
tcsetattr(STDOUT_FILENO, TCSADRAIN, &tt);
|
||||
(void)tcsetattr(STDOUT_FILENO, TCSADRAIN, &tt);
|
||||
|
||||
isterm = 0;
|
||||
}
|
||||
|
@ -397,14 +413,14 @@ playback(FILE *fp)
|
|||
int reg;
|
||||
|
||||
if (fstat(fileno(fp), &pst) == -1)
|
||||
err(1, "fstat failed");
|
||||
err(EXIT_FAILURE, "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)
|
||||
err(1, "reading playback header");
|
||||
err(EXIT_FAILURE, "reading playback header");
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
@ -413,7 +429,7 @@ playback(FILE *fp)
|
|||
|
||||
if (reg && stamp.scr_len >
|
||||
(uint64_t)(pst.st_size - save_len) - nread)
|
||||
errx(1, "invalid stamp");
|
||||
errx(EXIT_FAILURE, "invalid stamp");
|
||||
|
||||
save_len += stamp.scr_len;
|
||||
tclock = stamp.scr_sec;
|
||||
|
@ -431,6 +447,7 @@ playback(FILE *fp)
|
|||
atexit(termreset);
|
||||
break;
|
||||
case 'e':
|
||||
termreset();
|
||||
if (!quiet)
|
||||
(void)printf("\nScript done on %s",
|
||||
ctime(&tclock));
|
||||
|
@ -453,16 +470,17 @@ playback(FILE *fp)
|
|||
while (stamp.scr_len > 0) {
|
||||
l = MIN(DEF_BUF, stamp.scr_len);
|
||||
if (fread(buf, sizeof(char), l, fp) != l)
|
||||
err(1, "cannot read buffer");
|
||||
err(EXIT_FAILURE, "cannot read buffer");
|
||||
|
||||
(void)write(STDOUT_FILENO, buf, l);
|
||||
stamp.scr_len -= l;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
errx(1, "invalid direction");
|
||||
errx(EXIT_FAILURE, "invalid direction %u",
|
||||
stamp.scr_direction);
|
||||
}
|
||||
}
|
||||
(void)fclose(fp);
|
||||
exit(0);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue