From owner-freebsd-bugs@FreeBSD.ORG Wed Jan 16 03:00:04 2008 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 265F416A418 for ; Wed, 16 Jan 2008 03:00:04 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id E46C013C4CE for ; Wed, 16 Jan 2008 03:00:03 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id m0G303UK087853 for ; Wed, 16 Jan 2008 03:00:03 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id m0G303Tm087852; Wed, 16 Jan 2008 03:00:03 GMT (envelope-from gnats) Resent-Date: Wed, 16 Jan 2008 03:00:03 GMT Resent-Message-Id: <200801160300.m0G303Tm087852@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Giorgos Keramidas Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 8EE7516A46B for ; Wed, 16 Jan 2008 02:56:05 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from mx-out.forthnet.gr (mx-out.forthnet.gr [193.92.150.104]) by mx1.freebsd.org (Postfix) with ESMTP id F376113C461 for ; Wed, 16 Jan 2008 02:56:04 +0000 (UTC) (envelope-from keramida@ceid.upatras.gr) Received: from mx-av-03.forthnet.gr (mx-av.forthnet.gr [193.92.150.27]) by mx-out-02.forthnet.gr (8.14.0/8.14.0) with ESMTP id m0G2u3Ip004311; Wed, 16 Jan 2008 04:56:03 +0200 Received: from MX-IN-04.forthnet.gr (mx-in-04.forthnet.gr [193.92.150.163]) by mx-av-03.forthnet.gr (8.14.1/8.14.1) with ESMTP id m0G2u2bE003759; Wed, 16 Jan 2008 04:56:02 +0200 Received: from kobe.laptop (ppp176-5.adsl.forthnet.gr [62.1.179.5]) by MX-IN-04.forthnet.gr (8.14.2/8.14.2) with ESMTP id m0G2u1ol010222; Wed, 16 Jan 2008 04:56:02 +0200 Received: from kobe.laptop (kobe.laptop [127.0.0.1]) by kobe.laptop (8.14.2/8.14.2) with ESMTP id m0G2u0N1004215; Wed, 16 Jan 2008 04:56:01 +0200 (EET) (envelope-from keramida@kobe.laptop) Received: (from keramida@localhost) by kobe.laptop (8.14.2/8.14.2/Submit) id m0G2u0US004214; Wed, 16 Jan 2008 04:56:00 +0200 (EET) (envelope-from keramida) Message-Id: <200801160256.m0G2u0US004214@kobe.laptop> Date: Wed, 16 Jan 2008 04:56:00 +0200 (EET) From: Giorgos Keramidas To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Bruce Evans Subject: bin/119705: [PATCH] make iostat a bit smarter about the number of tty rows X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Giorgos Keramidas List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 Jan 2008 03:00:04 -0000 >Number: 119705 >Category: bin >Synopsis: [PATCH] make iostat a bit smarter about the number of tty rows >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Wed Jan 16 03:00:03 UTC 2008 >Closed-Date: >Last-Modified: >Originator: Giorgos Keramidas >Release: FreeBSD 8.0-CURRENT i386 >Organization: >Environment: System: FreeBSD kobe 8.0-CURRENT FreeBSD 8.0-CURRENT #0: \ Tue Jan 15 21:10:19 EET 2008 build@kobe:/home/build/obj/home/build/src/sys/KOBE i386 >Description: The current iostat(8) utility repeats the header line every 20 lines, and this number is hardcoded in the source of iostat. This means that with very short xterm windows, iostat may not display one header per terminal, and when the window size changes, it doesn't detect this and update its internal row count. The attached patch modifies iostat() to trap SIGWINCH, and use it to update its internal 'max rows' limit of output lines. It also forces a new header to be prepended to the output on every SIGWINCH, and it changes the hardcoded '20' lines of output to 'wrows - 3' (two rows are needed for the header itself, and one for the cursor below the last output line of each screenful). >How-To-Repeat: Resize an xterm window to 80x10 lines, and watch the output of iostat for a while, using: % iostat 1 >Fix: --- iostat-rows.patch begins here --- diff -r d03d5ae8b3ef -r 21be4228379f usr.sbin/iostat/iostat.c --- a/usr.sbin/iostat/iostat.c Tue Jan 15 15:04:40 2008 +0000 +++ b/usr.sbin/iostat/iostat.c Wed Jan 16 04:50:48 2008 +0200 @@ -113,6 +113,7 @@ #include #include #include +#include #include #include #include @@ -136,12 +137,16 @@ struct device_selection *dev_select; struct device_selection *dev_select; int maxshowdevs; volatile sig_atomic_t headercount; +volatile sig_atomic_t wresized; /* Tty resized, when non-zero. */ +unsigned short wrows; /* Current number of tty rows. */ int dflag = 0, Iflag = 0, Cflag = 0, Tflag = 0, oflag = 0, Kflag = 0; int xflag = 0, zflag = 0; /* local function declarations */ static void usage(void); static void needhdr(int signo); +static void needresize(int signo); +static void doresize(void); static void phdr(void); static void devstats(int perf_select, long double etime, int havelast); static void cpustats(void); @@ -425,8 +430,9 @@ main(int argc, char **argv) * print out the header again. */ (void)signal(SIGCONT, needhdr); + (void)signal(SIGWINCH, needresize); - for (headercount = 1;;) { + for (wresized = 1, headercount = 1;;) { struct devinfo *tmp_dinfo; long tmp; long double etime; @@ -451,7 +457,9 @@ main(int argc, char **argv) if (!--headercount) { phdr(); - headercount = 20; + if (wresized != 0) + doresize(); + headercount = wrows - 3; } tmp_dinfo = last.dinfo; @@ -493,7 +501,9 @@ main(int argc, char **argv) break; case 1: phdr(); - headercount = 20; + if (wresized != 0) + doresize(); + headercount = wrows - 3; break; default: break; @@ -528,7 +538,9 @@ main(int argc, char **argv) break; case 1: phdr(); - headercount = 20; + if (wresized != 0) + doresize(); + headercount = wrows - 3; break; default: break; @@ -587,6 +599,45 @@ needhdr(int signo) { headercount = 1; +} + +/* + * When the terminal is resized, force an update of the maximum number of rows + * printed between each header repetition. Then force a new header to be + * prepended to the next output. + */ +void +needresize(int signo) +{ + + wresized = 1; + headercount = 1; +} + +/* + * Update the global `wrows' count of terminal rows. + */ +void +doresize(void) +{ + int fd, status; + struct winsize w; + + fd = fileno(stdout); + if (isatty(fd) == 0) { + wrows = 20; /* Traditional default. */ + return; + } + + for (;;) { + status = ioctl(fd, TIOCGWINSZ, &w); + if (status == -1 && errno == EINTR) + continue; + else if (status == -1) + err(1, "ioctl"); + wrows = w.ws_row; + break; + } } static void --- iostat-rows.patch ends here --- >Release-Note: >Audit-Trail: >Unformatted: