From owner-svn-src-all@FreeBSD.ORG Thu Jan 15 04:49:41 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 22D1A1065672; Thu, 15 Jan 2009 04:49:41 +0000 (UTC) (envelope-from keramida@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 100898FC1A; Thu, 15 Jan 2009 04:49:41 +0000 (UTC) (envelope-from keramida@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n0F4neZU064797; Thu, 15 Jan 2009 04:49:40 GMT (envelope-from keramida@svn.freebsd.org) Received: (from keramida@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n0F4neYd064796; Thu, 15 Jan 2009 04:49:40 GMT (envelope-from keramida@svn.freebsd.org) Message-Id: <200901150449.n0F4neYd064796@svn.freebsd.org> From: Giorgos Keramidas Date: Thu, 15 Jan 2009 04:49:40 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-6@freebsd.org X-SVN-Group: stable-6 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r187283 - stable/6/usr.bin/vmstat X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 15 Jan 2009 04:49:41 -0000 Author: keramida (doc committer) Date: Thu Jan 15 04:49:40 2009 New Revision: 187283 URL: http://svn.freebsd.org/changeset/base/187283 Log: MFC 184645 from /head Repeat vmstat header after window.rows instead of a hardcoded 20. Use ioctl() to get the window size in vmstat(8), and force a new header to be prepended to the output every time the current window size changes. Change the number of lines before each header to the current lines of the terminal when the terminal is resized, so that the full terminal length can be used for output lines. Modified: stable/6/usr.bin/vmstat/vmstat.c Modified: stable/6/usr.bin/vmstat/vmstat.c ============================================================================== --- stable/6/usr.bin/vmstat/vmstat.c Thu Jan 15 04:48:06 2009 (r187282) +++ stable/6/usr.bin/vmstat/vmstat.c Thu Jan 15 04:49:40 2009 (r187283) @@ -135,7 +135,10 @@ static devstat_select_mode select_mode; static struct vmmeter sum, osum; -static int winlines = 20; +#define VMSTAT_DEFAULT_LINES 20 /* Default number of `winlines'. */ +volatile sig_atomic_t wresized; /* Tty resized, when non-zero. */ +static int winlines = VMSTAT_DEFAULT_LINES; /* Current number of tty rows. */ + static int aflag; static int nflag; static int Pflag; @@ -164,6 +167,8 @@ static void kread(int, void *, size_t); static void kreado(int, void *, size_t, size_t); static char *kgetstr(const char *); static void needhdr(int); +static void needresize(int); +static void doresize(void); static void printhdr(int, u_long); static void usage(void); @@ -279,8 +284,6 @@ main(int argc, char *argv[]) errx(1, "Cannot use -P with crash dumps"); if (todo & VMSTAT) { - struct winsize winsize; - /* * Make sure that the userland devstat version matches the * kernel devstat version. If not, exit and print a @@ -291,11 +294,6 @@ main(int argc, char *argv[]) argv = getdrivedata(argv); - winsize.ws_row = 0; - (void) ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&winsize); - if (winsize.ws_row > 0) - winlines = winsize.ws_row; - } #define BACKWARD_COMPATIBILITY @@ -591,8 +589,27 @@ dovmstat(unsigned int interval, int reps uptime = getuptime(); halfuptime = uptime / 2; + + /* + * If the user stops the program (control-Z) and then resumes it, + * print out the header again. + */ (void)signal(SIGCONT, needhdr); + /* + * If our standard output is a tty, then install a SIGWINCH handler + * and set wresized so that our first iteration through the main + * iostat loop will peek at the terminal's current rows to find out + * how many lines can fit in a screenful of output. + */ + if (isatty(fileno(stdout)) != 0) { + wresized = 1; + (void)signal(SIGWINCH, needresize); + } else { + wresized = 0; + winlines = VMSTAT_DEFAULT_LINES; + } + if (kd != NULL) { if (namelist[X_STATHZ].n_type != 0 && namelist[X_STATHZ].n_value != 0) @@ -770,7 +787,9 @@ printhdr(int ncpus, u_long cpumask) printf("\n"); } else printf(" us sy id\n"); - hdrcnt = winlines - 2; + if (wresized != 0) + doresize(); + hdrcnt = winlines; } /* @@ -783,6 +802,47 @@ needhdr(int dummy __unused) hdrcnt = 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; + hdrcnt = 1; +} + +/* + * Update the global `winlines' count of terminal rows. + */ +void +doresize(void) +{ + int status; + struct winsize w; + + for (;;) { + status = ioctl(fileno(stdout), TIOCGWINSZ, &w); + if (status == -1 && errno == EINTR) + continue; + else if (status == -1) + err(1, "ioctl"); + if (w.ws_row > 3) + winlines = w.ws_row - 3; + else + winlines = VMSTAT_DEFAULT_LINES; + break; + } + + /* + * Inhibit doresize() calls until we are rescheduled by SIGWINCH. + */ + wresized = 0; +} + #ifdef notyet static void dotimes(void)