Subject: Re: SIGWINCH->systat
To: None <tech-smp@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-smp
Date: 02/10/2003 17:38:05
In article <20030210140917.Z7389@snowdrop.l8s.co.uk>,
David Laight <david@l8s.co.uk> wrote:
>> More to the point, can someone install a SIGWINCH handler for systat
>> and/or vmstat and/or iostat?
>
>The diff below fixes systat for 'current'.
>I'll commit it if the 'powers that be' say it is ok.

Ok, but...

1. well, ioctl(1, is not great. Unfortunatelly there is no method
   to get the output file pointer, although it is being passed in
   in newterm(). Maybe such a method should be added?
2. libcurses seems to do SIGWINCH and SIGTSTP frobbing in tstp.c,
   why doesn't it work.

christos

>
>	David
>
>Index: main.c
>===================================================================
>RCS file: /cvsroot/src/usr.bin/systat/main.c,v
>retrieving revision 1.30
>diff -u -r1.30 main.c
>--- main.c	2001/12/06 12:40:51	1.30
>+++ main.c	2003/02/10 13:57:43
>@@ -54,6 +54,8 @@
> #include <stdlib.h>
> #include <string.h>
> #include <unistd.h>
>+#include <termios.h>
>+#include <sys/ioctl.h>
> 
> #include "systat.h"
> #include "extern.h"
>@@ -90,6 +92,9 @@
> 
> static	WINDOW *wload;			/* one line window for load average */
> 
>+static void (*sv_stop_handler)(int);
>+
>+static void stop(int);
> static void usage(void);
> int main(int, char **);
> 
>@@ -191,6 +196,7 @@
> 	signal(SIGQUIT, die);
> 	signal(SIGTERM, die);
> 	signal(SIGWINCH, redraw);
>+	sv_stop_handler = signal(SIGTSTP, stop);
> 
> 	/*
> 	 * Initialize display.  Load average appears in a one line
>@@ -317,13 +323,37 @@
> redraw(int signo)
> {
> 	sigset_t set;
>+	struct winsize win;
> 
> 	sigemptyset(&set);
> 	sigaddset(&set, SIGALRM);
> 	sigprocmask(SIG_BLOCK, &set, NULL);
>-	wrefresh(curscr);
>-	refresh();
>+
>+	if (ioctl(1, TIOCGWINSZ, &win) != -1) {
>+		resizeterm(win.ws_row, win.ws_col);
>+		CMDLINE = LINES - 1;
>+		labels();
>+	}
>+
>+	sigprocmask(SIG_UNBLOCK, &set, NULL);
>+	display(0);
>+}
>+
>+static void
>+stop(int signo)
>+{
>+	sigset_t set;
>+
>+	signal(SIGTSTP, sv_stop_handler);
>+	/* unblock SIGTSTP */
>+	sigemptyset(&set);
>+	sigaddset(&set, SIGTSTP);
> 	sigprocmask(SIG_UNBLOCK, &set, NULL);
>+	/* stop ourselves */
>+	kill(0, SIGTSTP);
>+	/* must have been restarted */
>+	redraw(signo);
>+	signal(SIGTSTP, stop);
> }
> 
> void
>
>-- 
>David Laight: david@l8s.co.uk