On Sun, 18 Sep 2011 20:24:23 +0300 Kostik Belousov wrote: KB> On Sun, Sep 18, 2011 at 02:54:34PM +0300, Mikolaj Golub wrote: >> >> On Sun, 18 Sep 2011 13:25:26 +0200 Ronald Klop wrote: >> >> RK> It is a while since I programmed C, but why will writing 0 bytes give >> RK> the reader an end-of-file? Shouldn't the fd be closed to indicate >> RK> end-of-file? >> >> AFAIR, this trick with writing 0 to emulate EOF because we can't close the >> fd >> -- we still want to read from it. Poor shutdown(2) for non-socket :-). >> >> Colin might tell more...
KB> Please note that interpreting the receiving of 0 bytes on the terminal KB> as EOF is only a convention. If done absolutely properly, script shall KB> not interpret zero-byte read as EOF. Might be, the reasonable thing to KB> do would be to only look at the stdin once in a second after receiving KB> zero-bytes, and switching it back to normal mode if something is read. Ok. I see. Below is the patch that does something like this. -- Mikolaj Golub
Index: usr.bin/script/script.c =================================================================== --- usr.bin/script/script.c (revision 225653) +++ usr.bin/script/script.c (working copy) @@ -53,6 +53,7 @@ static const char sccsid[] = "@(#)script.c 8.1 (Be #include <libutil.h> #include <paths.h> #include <signal.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -86,6 +87,7 @@ main(int argc, char *argv[]) char ibuf[BUFSIZ]; fd_set rfd; int flushtime = 30; + bool readstdin; aflg = kflg = 0; while ((ch = getopt(argc, argv, "aqkt:")) != -1) @@ -155,19 +157,20 @@ 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 = true; 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 || flushtime > 0) { + tv.tv_sec = !readstdin ? 1 : flushtime - (tvec - start); tv.tv_usec = 0; + tvp = &tv; + readstdin = true; + } else { + tvp = NULL; } n = select(master + 1, &rfd, 0, 0, tvp); if (n < 0 && errno != EINTR) @@ -176,8 +179,10 @@ main(int argc, char *argv[]) cc = read(STDIN_FILENO, ibuf, BUFSIZ); if (cc < 0) break; - if (cc == 0) + if (cc == 0) { (void)write(master, ibuf, 0); + readstdin = false; + } if (cc > 0) { (void)write(master, ibuf, cc); if (kflg && tcgetattr(master, &stt) >= 0 &&
_______________________________________________ freebsd-stable@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-stable To unsubscribe, send any mail to "freebsd-stable-unsubscr...@freebsd.org"