summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usr.bin/script/script.19
-rw-r--r--usr.bin/script/script.c32
2 files changed, 29 insertions, 12 deletions
diff --git a/usr.bin/script/script.1 b/usr.bin/script/script.1
index 3aa03e5..cd3f800 100644
--- a/usr.bin/script/script.1
+++ b/usr.bin/script/script.1
@@ -166,3 +166,12 @@ The slave terminal mode is checked
for ECHO mode to check when to avoid manual echo logging.
This does not
work when in a raw mode where the program being run is doing manual echo.
+.Pp
+If the
+.Nm
+reads zero bytes from the terminal it switches to a mode when it probes read
+only once a second until it gets some data.
+This prevents the
+.Nm
+spinning on zero-byte reads, but might cause a 1-second delay in
+processing of the user input.
diff --git a/usr.bin/script/script.c b/usr.bin/script/script.c
index ad99721..ea5a1f6 100644
--- a/usr.bin/script/script.c
+++ b/usr.bin/script/script.c
@@ -86,6 +86,7 @@ main(int argc, char *argv[])
char ibuf[BUFSIZ];
fd_set rfd;
int flushtime = 30;
+ int readstdin;
aflg = kflg = 0;
while ((ch = getopt(argc, argv, "aqkt:")) != -1)
@@ -155,19 +156,21 @@ main(int argc, char *argv[])
doshell(argv);
close(slave);
- if (flushtime > 0)
- tvp = &tv;
- else
- tvp = NULL;
-
- start = time(0);
- FD_ZERO(&rfd);
+ start = tvec = time(0);
+ readstdin = 1;
for (;;) {
+ FD_ZERO(&rfd);
FD_SET(master, &rfd);
- FD_SET(STDIN_FILENO, &rfd);
- if (flushtime > 0) {
- tv.tv_sec = flushtime;
+ if (readstdin)
+ FD_SET(STDIN_FILENO, &rfd);
+ if ((!readstdin && ttyflg) || flushtime > 0) {
+ tv.tv_sec = !readstdin && ttyflg ? 1 :
+ flushtime - (tvec - start);
tv.tv_usec = 0;
+ tvp = &tv;
+ readstdin = 1;
+ } else {
+ tvp = NULL;
}
n = select(master + 1, &rfd, 0, 0, tvp);
if (n < 0 && errno != EINTR)
@@ -176,8 +179,13 @@ main(int argc, char *argv[])
cc = read(STDIN_FILENO, ibuf, BUFSIZ);
if (cc < 0)
break;
- if (cc == 0)
- (void)write(master, ibuf, 0);
+ if (cc == 0) {
+ if (tcgetattr(master, &stt) == 0 &&
+ (stt.c_lflag & ICANON) != 0) {
+ (void)write(master, &stt.c_cc[VEOF], 1);
+ }
+ readstdin = 0;
+ }
if (cc > 0) {
(void)write(master, ibuf, cc);
if (kflg && tcgetattr(master, &stt) >= 0 &&
OpenPOWER on IntegriCloud