Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144474636
D44167.id137723.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D44167.id137723.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D44167: script: handle terminal resize on SIGSWINCH
Attached
Detach File
Event Timeline
Log In to Comment