From owner-freebsd-stable@FreeBSD.ORG Sun Sep 18 20:58:04 2011 Return-Path: Delivered-To: freebsd-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A8BF81065674; Sun, 18 Sep 2011 20:58:04 +0000 (UTC) (envelope-from to.my.trociny@gmail.com) Received: from mail-fx0-f54.google.com (mail-fx0-f54.google.com [209.85.161.54]) by mx1.freebsd.org (Postfix) with ESMTP id 9D9708FC14; Sun, 18 Sep 2011 20:58:03 +0000 (UTC) Received: by fxg9 with SMTP id 9so4500044fxg.13 for ; Sun, 18 Sep 2011 13:58:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:references:x-comment-to:sender:date:in-reply-to :message-id:user-agent:mime-version:content-type; bh=OF8v8ne3N2nzHA6ItKt+yuGoWRjjM0dvzJxBei8bWb8=; b=WStYlPE/xosqb06PMoNdDOkCeJp0FeXiPooX4m2KmeTsg1/8ZpG7Qp5mopjjVNKwGQ 9P2dJMo9R1dTFbMtJnj3AhmWyhcpmBzYRZQnkkco54yUho2uuoQ4/hz5BDkfO57LBpza h3/90RPH7d4NsUeJxydj1L/cHZrrIIUTrabwA= Received: by 10.223.37.81 with SMTP id w17mr3819883fad.91.1316379482704; Sun, 18 Sep 2011 13:58:02 -0700 (PDT) Received: from localhost ([95.69.173.122]) by mx.google.com with ESMTPS id a7sm19460202fam.22.2011.09.18.13.57.59 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 18 Sep 2011 13:58:00 -0700 (PDT) From: Mikolaj Golub To: Kostik Belousov References: <20110918045413.GA63773@DataIX.net> <20110918053901.GA31617@icarus.home.lan> <86d3eydsmf.fsf@kopusha.home.net> <868vpmdq11.fsf@kopusha.home.net> <20110918172423.GB1511@deviant.kiev.zoral.com.ua> X-Comment-To: Kostik Belousov Sender: Mikolaj Golub Date: Sun, 18 Sep 2011 23:57:57 +0300 In-Reply-To: <20110918172423.GB1511@deviant.kiev.zoral.com.ua> (Kostik Belousov's message of "Sun, 18 Sep 2011 20:24:23 +0300") Message-ID: <86zki1d0ve.fsf@kopusha.home.net> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (berkeley-unix) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Cc: "freebsd-stable@freebsd.org" , cperciva@freebsd.org, Jeremy Chadwick , Ronald Klop Subject: Re: /usr/bin/script eating 100% cpu with portupgrade and xargs X-BeenThere: freebsd-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Production branch of FreeBSD source code List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 18 Sep 2011 20:58:04 -0000 --=-=-= 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 #include #include +#include #include #include #include @@ -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 && --=-=-=--