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>
