Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 18 Sep 2011 23:57:57 +0300
From:      Mikolaj Golub <trociny@freebsd.org>
To:        Kostik Belousov <kostikbel@gmail.com>
Cc:        "freebsd-stable@freebsd.org" <freebsd-stable@freebsd.org>, cperciva@freebsd.org, Jeremy Chadwick <freebsd@jdc.parodius.com>, Ronald Klop <ronald-freebsd8@klop.yi.org>
Subject:   Re: /usr/bin/script eating 100% cpu with portupgrade and xargs
Message-ID:  <86zki1d0ve.fsf@kopusha.home.net>
In-Reply-To: <20110918172423.GB1511@deviant.kiev.zoral.com.ua> (Kostik Belousov's message of "Sun, 18 Sep 2011 20:24:23 %2B0300")
References:  <op.v1y8gdtf8527sy@pinky> <20110918045413.GA63773@DataIX.net> <20110918053901.GA31617@icarus.home.lan> <op.v1zrszht8527sy@pinky> <86d3eydsmf.fsf@kopusha.home.net> <op.v1z4ooot8527sy@pinky> <868vpmdq11.fsf@kopusha.home.net> <20110918172423.GB1511@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=


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


--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=script.c.1.patch

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 &&

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86zki1d0ve.fsf>