Page MenuHomeFreeBSD

D44167.id137723.diff
No OneTemporary

D44167.id137723.diff

diff --git a/usr.bin/script/script.1 b/usr.bin/script/script.1
--- a/usr.bin/script/script.1
+++ b/usr.bin/script/script.1
@@ -33,7 +33,7 @@
.Nd make typescript of terminal session
.Sh SYNOPSIS
.Nm
-.Op Fl aeFfkqr
+.Op Fl aeFfkqrw
.Op Fl t Ar time
.Op Ar file Op Ar command ...
.Nm
@@ -131,6 +131,9 @@
which is useful for both tools and humans to read, should be used.
Note that time-stamps will only be output when different from the
previous one.
+.It Fl w
+Forward terminal size changes on
+.Dv SIGWINCH .
.El
.Pp
The script ends when the forked shell (or command) exits (a
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -40,6 +40,7 @@
#include <sys/endian.h>
#include <dev/filemon/filemon.h>
+#include <assert.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -76,6 +77,7 @@
static int fflg, qflg, ttyflg;
static int usesleep, rawout, showexit;
static TAILQ_HEAD(, buf_elm) obuf_list = TAILQ_HEAD_INITIALIZER(obuf_list);
+static volatile sig_atomic_t doresize;
static struct termios tt;
@@ -93,40 +95,54 @@
static void consume(FILE *, off_t, char *, int);
static void playback(FILE *) __dead2;
static void usage(void) __dead2;
+static void resizeit(int);
int
main(int argc, char *argv[])
{
struct termios rtt, stt;
struct winsize win;
- struct timeval tv, *tvp;
+ struct timespec tv, *tvp;
time_t tvec, start;
char obuf[BUFSIZ];
char ibuf[BUFSIZ];
+ sigset_t *pselmask, selmask;
fd_set rfd, wfd;
struct buf_elm *be;
ssize_t cc;
- int aflg, Fflg, kflg, pflg, ch, k, n, fcm;
+ int aflg, Fflg, kflg, pflg, wflg, ch, k, n, fcm;
int flushtime, readstdin;
int fm_fd, fm_log;
- aflg = Fflg = kflg = pflg = 0;
+ aflg = Fflg = kflg = pflg = wflg = 0;
+ doresize = 0;
usesleep = 1;
rawout = 0;
flushtime = 30;
- fm_fd = -1; /* Shut up stupid "may be used uninitialized" GCC
- warning. (not needed w/clang) */
+ fm_fd = -1;
showexit = 0;
- while ((ch = getopt(argc, argv, "adeFfkpqrT:t:")) != -1)
- switch(ch) {
+ /*
+ * For normal operation, we'll leave pselmask == NULL so that pselect(2)
+ * leaves the signal mask alone. If -w is specified, we'll restore the
+ * process signal mask upon entry with SIGWINCH unblocked so that we can
+ * forward resize events properly.
+ */
+ sigemptyset(&selmask);
+ pselmask = NULL;
+
+ while ((ch = getopt(argc, argv, "adeFfkpqrT:t:w")) != -1)
+ switch (ch) {
case 'a':
aflg = 1;
break;
case 'd':
usesleep = 0;
break;
- case 'e': /* Default behavior, accepted for linux compat */
+ /*
+ * Default behavior, accepted for linux compat
+ */
+ case 'e':
break;
case 'F':
Fflg = 1;
@@ -156,6 +172,9 @@
if (strchr(optarg, '%'))
tstamp_fmt = optarg;
break;
+ case 'w':
+ wflg = 1;
+ break;
case '?':
default:
usage();
@@ -239,6 +258,11 @@
(void)tcsetattr(STDIN_FILENO, TCSAFLUSH, &rtt);
}
+ if (fflg)
+ assert(fm_fd >= 0);
+ else
+ assert(fm_fd == -1);
+
child = fork();
if (child < 0) {
warn("fork");
@@ -257,6 +281,23 @@
}
close(slave);
+ if (wflg) {
+ struct sigaction sa = { .sa_handler = resizeit };
+ sigset_t smask;
+
+ sigaction(SIGWINCH, &sa, NULL);
+
+ sigemptyset(&smask);
+ sigaddset(&smask, SIGWINCH);
+
+ if (sigprocmask(SIG_BLOCK, &smask, &selmask) != 0)
+ err(1, "Failed to block SIGWINCH");
+
+ /* Just in case SIGWINCH was blocked before we came in. */
+ sigdelset(&selmask, SIGWINCH);
+ pselmask = &selmask;
+ }
+
start = tvec = time(0);
readstdin = 1;
for (;;) {
@@ -269,19 +310,27 @@
FD_SET(master, &wfd);
if (!readstdin && ttyflg) {
tv.tv_sec = 1;
- tv.tv_usec = 0;
+ tv.tv_nsec = 0;
tvp = &tv;
readstdin = 1;
} else if (flushtime > 0) {
tv.tv_sec = flushtime - (tvec - start);
- tv.tv_usec = 0;
+ tv.tv_nsec = 0;
tvp = &tv;
} else {
tvp = NULL;
}
- n = select(master + 1, &rfd, &wfd, NULL, tvp);
+ n = pselect(master + 1, &rfd, &wfd, NULL, tvp, pselmask);
if (n < 0 && errno != EINTR)
break;
+
+ if (doresize) {
+ if (ioctl(STDIN_FILENO, TIOCGWINSZ, &win) != -1) {
+ ioctl(master, TIOCSWINSZ, &win);
+ }
+ doresize = 0;
+ }
+
if (n > 0 && FD_ISSET(STDIN_FILENO, &rfd)) {
cc = read(STDIN_FILENO, ibuf, BUFSIZ);
if (cc < 0)
@@ -331,7 +380,7 @@
}
}
if (n > 0 && FD_ISSET(master, &rfd)) {
- cc = read(master, obuf, sizeof (obuf));
+ cc = read(master, obuf, sizeof(obuf));
if (cc <= 0)
break;
(void)write(STDOUT_FILENO, obuf, cc);
@@ -356,7 +405,7 @@
usage(void)
{
(void)fprintf(stderr,
- "usage: script [-aeFfkpqr] [-t time] [file [command ...]]\n");
+ "usage: script [-aeFfkpqrw] [-t time] [file [command ...]]\n");
(void)fprintf(stderr,
" script -p [-deq] [-T fmt] [file]\n");
exit(1);
@@ -417,7 +466,7 @@
if (showexit)
(void)fprintf(fscript, "\nCommand exit status:"
" %d", eno);
- (void)fprintf(fscript,"\nScript done on %s",
+ (void)fprintf(fscript, "\nScript done on %s",
ctime(&tvec));
}
(void)printf("\nScript done, output file is %s\n", fname);
@@ -459,8 +508,7 @@
if (reg) {
if (fseeko(fp, len, SEEK_CUR) == -1)
err(1, NULL);
- }
- else {
+ } else {
while (len > 0) {
l = MIN(DEF_BUF, len);
if (fread(buf, sizeof(char), l, fp) != l)
@@ -603,3 +651,9 @@
(void)fclose(fp);
exit(0);
}
+
+static void
+resizeit(int signo __unused)
+{
+ doresize = 1;
+}

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 3:28 PM (7 h, 38 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28594151
Default Alt Text
D44167.id137723.diff (5 KB)

Event Timeline