Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Jan 2009 03:12:45 +0000 (UTC)
From:      Giorgos Keramidas <keramida@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org
Subject:   svn commit: r187265 - stable/7/usr.sbin/iostat
Message-ID:  <200901150312.n0F3Cj9F062006@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: keramida (doc committer)
Date: Thu Jan 15 03:12:45 2009
New Revision: 187265
URL: http://svn.freebsd.org/changeset/base/187265

Log:
  MFC 175562 from /head
  
  Repeat iostat header after rows-3 instead of a hardcoded 20.
  
  Use ioctl() to get the window size in iostat(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 `rows - 3' when the terminal is resized, so that the
  full terminal length can be used for output lines.

Modified:
  stable/7/usr.sbin/iostat/   (props changed)
  stable/7/usr.sbin/iostat/iostat.c

Modified: stable/7/usr.sbin/iostat/iostat.c
==============================================================================
--- stable/7/usr.sbin/iostat/iostat.c	Thu Jan 15 02:57:07 2009	(r187264)
+++ stable/7/usr.sbin/iostat/iostat.c	Thu Jan 15 03:12:45 2009	(r187265)
@@ -113,6 +113,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <termios.h>
 #include <unistd.h>
 #include <limits.h>
 #include <devstat.h>
@@ -129,17 +130,23 @@ struct nlist namelist[] = {
 	{ NULL },
 };
 
+#define	IOSTAT_DEFAULT_ROWS	20	/* Traditional default `wrows' */
+
 struct statinfo cur, last;
 int num_devices;
 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);
@@ -424,6 +431,20 @@ main(int argc, char **argv)
 	 */
 	(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;
+		wrows = IOSTAT_DEFAULT_ROWS;
+	}
+
 	for (headercount = 1;;) {
 		struct devinfo *tmp_dinfo;
 		long tmp;
@@ -457,7 +478,9 @@ main(int argc, char **argv)
 
 		if (!--headercount) {
 			phdr();
-			headercount = 20;
+			if (wresized != 0)
+				doresize();
+			headercount = wrows;
 		}
 
 		tmp_dinfo = last.dinfo;
@@ -499,7 +522,9 @@ main(int argc, char **argv)
 				break;
 			case 1:
 				phdr();
-				headercount = 20;
+				if (wresized != 0)
+					doresize();
+				headercount = wrows;
 				break;
 			default:
 				break;
@@ -534,7 +559,9 @@ main(int argc, char **argv)
 				break;
 			case 1:
 				phdr();
-				headercount = 20;
+				if (wresized != 0)
+					doresize();
+				headercount = wrows;
 				break;
 			default:
 				break;
@@ -595,6 +622,47 @@ 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 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)
+			wrows = w.ws_row - 3;
+		else
+			wrows = IOSTAT_DEFAULT_ROWS;
+		break;
+	}
+
+	/*
+	 * Inhibit doresize() calls until we are rescheduled by SIGWINCH.
+	 */
+	wresized = 0;
+}
+
 static void
 phdr(void)
 {



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