[net.sources.bugs] System Monitoring Program

pag@hao.UUCP (Peter Gross) (12/05/84)

vm.c in the mon distribution won't compile on a non-dual-cpu Vax.
My diffs follow.

--peter gross
hao!pag

*** /tmp/,RCSt1003602	Tue Dec  4 23:27:28 1984
--- vm.c	Tue Dec  4 23:27:04 1984
***************
*** 1,3
  /*
   *      V M
   *

--- 1,5 -----
+ static char *rcsid = "$Header: vm.c,v 1.2 84/12/04 23:24:41 pag Exp $";
+ 
  /*
   *      V M
   *
***************
*** 8,13
   *      printing.  This makes it very difficult to change the screen
   *      format.  A better solution would be to move all the prints
   *      into a screen update function.
   */
  
  #include "mon.h"

--- 10,23 -----
   *      printing.  This makes it very difficult to change the screen
   *      format.  A better solution would be to move all the prints
   *      into a screen update function.
+  *
+  * $Log:	vm.c,v $
+  * Revision 1.2  84/12/04  23:24:41  pag
+  * Workaround to get mon running:  vm.c wouldn't compile on a non-dual
+  * Vax because on those machines v_swtch2 is undefined.  Added an ifdef
+  * around this code.
+  * 
+  * 
   */
  
  #include "mon.h"
***************
*** 77,82
  	/* Display CPU info */
          mvprintw(CPUY+1,4,"%4d  %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
          cputime();

--- 87,93 -----
  	/* Display CPU info */
          mvprintw(CPUY+1,4,"%4d  %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
+ #ifdef HAVE_DUAL_CPU
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
  #endif
***************
*** 79,84
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
          cputime();
  
  	/* Display additional stuff */

--- 90,96 -----
  #ifdef HAVE_DUAL_CPU
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
+ #endif
          cputime();
  
  	/* Display additional stuff */

jonab@sdcrdcf.UUCP (Jonathan Biggar) (12/05/84)

There are a few problems with the distributed version of the MON
program.  I have made fixes to these problems.

1)  the dualcpu stuff for a dual 780 configuration will not compile
    on a system without the dualcpu hacks.  I have added a DUALCPU
    #ifdef around all portions of the code dealing with dualcpu.

2)  An ioctl to set the terminal into CBREAK mode was done directly,
    instead of using the curses crmode() call.  This causes the
    sgttyb structure for the terminal to get clobbered when MON finishes;
    including messing up the XTABS setting.  I changed it to use
    crmode().

3)  When MON exited normally, it exited with status 1.  I changed this to
    0.

Following are context diffs for 4 files: display.c mon.c mon.h and vm.c.
Feed these through Larry Wall's patch program, or install them by hand.

 
*** /tmp/,RCSt1020354	Wed Dec  5 11:16:54 1984
--- display.c	Wed Dec  5 10:29:15 1984
***************
*** 37,42
          mvprintw(PROCY,LEFT,"Procs: r d p s sl  Mem: real  ract  virt  vact  free");
          mvprintw(DISKY,DISKX,"Disks: Kbps tps msps");
          mvprintw(CPUY,LEFT,"Cpu: ints  scall  csw");
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");

--- 37,43 -----
          mvprintw(PROCY,LEFT,"Procs: r d p s sl  Mem: real  ract  virt  vact  free");
          mvprintw(DISKY,DISKX,"Disks: Kbps tps msps");
          mvprintw(CPUY,LEFT,"Cpu: ints  scall  csw");
+ #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
  #endif DUALCPU
***************
*** 39,44
          mvprintw(CPUY,LEFT,"Cpu: ints  scall  csw");
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");

--- 40,46 -----
  #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
+ #endif DUALCPU
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  #ifdef DUALCPU
  	if (dualcpu)
***************
*** 40,45
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");

--- 42,48 -----
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
  #endif DUALCPU
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
+ #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");
  #endif DUALCPU
***************
*** 42,47
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");

--- 45,51 -----
  #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");
+ #endif DUALCPU
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");
 
*** /tmp/,RCSt1020366	Wed Dec  5 11:17:05 1984
--- mon.c	Wed Dec  5 11:07:39 1984
***************
*** 36,41
  	{ "_tk_nin" },
  	{ "_tk_nout" },
  	{ "_avenrun" },
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */
  	{ 0 }

--- 36,42 -----
  	{ "_tk_nin" },
  	{ "_tk_nout" },
  	{ "_avenrun" },
+ #ifdef DUALCPU
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */
  #endif DUALCPU
***************
*** 38,43
  	{ "_avenrun" },
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */
  	{ 0 }
  };
  

--- 39,45 -----
  #ifdef DUALCPU
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */
+ #endif DUALCPU
  	{ 0 }
  };
  
***************
*** 74,79
          lseek(kmem, (long)namelist[X_HZ].n_value, 0);
          read(kmem, &hz, sizeof hz);
  	read_names();
  	dualcpu = 0;
  	if (namelist[X_SLAVESTART].n_type)
  		dualcpu++;        

--- 76,82 -----
          lseek(kmem, (long)namelist[X_HZ].n_value, 0);
          read(kmem, &hz, sizeof hz);
  	read_names();
+ #ifdef DUALCPU
  	dualcpu = 0;
  	if (namelist[X_SLAVESTART].n_type)
  		dualcpu++;        
***************
*** 77,82
  	dualcpu = 0;
  	if (namelist[X_SLAVESTART].n_type)
  		dualcpu++;        
  /*
   * monitor parameters forever
   */

--- 80,86 -----
  	dualcpu = 0;
  	if (namelist[X_SLAVESTART].n_type)
  		dualcpu++;        
+ #endif DUALCPU
  /*
   * monitor parameters forever
   */
***************
*** 96,108
  	signal(SIGINT, done);
  	signal(SIGQUIT, done);
  
- 	/* set CBREAK mode with no buffering on stdin */
- 	setbuf(stdin, 0);
- 	setbuf(stdout, obuf);
- 	ioctl(0, TIOCGETP, &ttyb);
- 	ttyb.sg_flags |= CBREAK;
- 	ioctl(fileno(stdin), TIOCSETP, (char *)&ttyb);
- 
  	tintv.tv_sec = intv;
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */

--- 100,105 -----
  	signal(SIGINT, done);
  	signal(SIGQUIT, done);
  
  	tintv.tv_sec = intv;
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */
***************
*** 106,111
  	tintv.tv_sec = intv;
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */
  	nifinit();	/* get initial net interfaces data */
          dispinit();     /* initialize display */
          for(;;){

--- 103,109 -----
  	tintv.tv_sec = intv;
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */
+ 	crmode();	/* set terminal into cbreak mode */
  	nifinit();	/* get initial net interfaces data */
          dispinit();     /* initialize display */
          for(;;){
***************
*** 138,147
   */
  done()
  {
- 	ioctl(0, TIOCGETP, &ttyb);
- 	ttyb.sg_flags &= ~CBREAK;
- 	ioctl(fileno(stdin), TIOCSETP, (char *)&ttyb);
- 	mvprintw(23,0,"\n");
  	refresh();
  	exit(1);
  }

--- 136,141 -----
   */
  done()
  {
  	refresh();
  	endwin();
  	exit(0);
***************
*** 143,147
  	ioctl(fileno(stdin), TIOCSETP, (char *)&ttyb);
  	mvprintw(23,0,"\n");
  	refresh();
! 	exit(1);
  }

--- 137,142 -----
  done()
  {
  	refresh();
! 	endwin();
! 	exit(0);
  }
 
*** /tmp/,RCSt1020371	Wed Dec  5 11:17:12 1984
--- mon.h	Wed Dec  5 10:47:29 1984
***************
*** 32,37
  #define	X_TK_NIN	14
  #define	X_TK_NOUT	15
  #define	LOADAV		16
  #define X_CP_TIME2	17	/* 2nd CPU stats */
  #define	X_SLAVESTART	18	/* 2nd cpu existance test */
  

--- 32,38 -----
  #define	X_TK_NIN	14
  #define	X_TK_NOUT	15
  #define	LOADAV		16
+ #ifdef DUALCPU
  #define X_CP_TIME2	17	/* 2nd CPU stats */
  #define	X_SLAVESTART	18	/* 2nd cpu existance test */
  #endif DUALCPU
***************
*** 34,40
  #define	LOADAV		16
  #define X_CP_TIME2	17	/* 2nd CPU stats */
  #define	X_SLAVESTART	18	/* 2nd cpu existance test */
! 
  extern struct nlist namelist[];
  int intv;			/* interval time */
  int numif;			/* number of interfaces */

--- 35,41 -----
  #ifdef DUALCPU
  #define X_CP_TIME2	17	/* 2nd CPU stats */
  #define	X_SLAVESTART	18	/* 2nd cpu existance test */
! #endif DUALCPU
  extern struct nlist namelist[];
  int intv;			/* interval time */
  int numif;			/* number of interfaces */
***************
*** 38,43
  extern struct nlist namelist[];
  int intv;			/* interval time */
  int numif;			/* number of interfaces */
  int dualcpu;			/* flag to indicate dual CPU */
  int kmem, hz;
  int deficit;

--- 39,45 -----
  extern struct nlist namelist[];
  int intv;			/* interval time */
  int numif;			/* number of interfaces */
+ #ifdef DUALCPU
  int dualcpu;			/* flag to indicate dual CPU */
  #endif DUALCPU
  int kmem, hz;
***************
*** 39,44
  int intv;			/* interval time */
  int numif;			/* number of interfaces */
  int dualcpu;			/* flag to indicate dual CPU */
  int kmem, hz;
  int deficit;
  double etime;

--- 41,47 -----
  int numif;			/* number of interfaces */
  #ifdef DUALCPU
  int dualcpu;			/* flag to indicate dual CPU */
+ #endif DUALCPU
  int kmem, hz;
  int deficit;
  double etime;
 
*** /tmp/,RCSt1020384	Wed Dec  5 11:17:23 1984
--- vm.c	Wed Dec  5 10:29:13 1984
***************
*** 27,32
          lseek(kmem, (long)namelist[X_CP_TIME].n_value, 0);
          read(kmem, s.cp_time, sizeof s.cp_time);
  	/* Check for 2nd CPU stats */
  	if (dualcpu) {
  	        lseek(kmem, (long)namelist[X_CP_TIME2].n_value, 0);
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);

--- 27,33 -----
          lseek(kmem, (long)namelist[X_CP_TIME].n_value, 0);
          read(kmem, s.cp_time, sizeof s.cp_time);
  	/* Check for 2nd CPU stats */
+ #ifdef DUALCPU
  	if (dualcpu) {
  	        lseek(kmem, (long)namelist[X_CP_TIME2].n_value, 0);
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);
***************
*** 31,36
  	        lseek(kmem, (long)namelist[X_CP_TIME2].n_value, 0);
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);
  	}
          lseek(kmem, (long)namelist[X_DK_XFER].n_value, 0);
          read(kmem, s.dk_xfer, sizeof s.dk_xfer);
          lseek(kmem, (long)namelist[X_RATE].n_value, 0);

--- 32,38 -----
  	        lseek(kmem, (long)namelist[X_CP_TIME2].n_value, 0);
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);
  	}
+ #endif DUALCPU
          lseek(kmem, (long)namelist[X_DK_XFER].n_value, 0);
          read(kmem, s.dk_xfer, sizeof s.dk_xfer);
          lseek(kmem, (long)namelist[X_RATE].n_value, 0);
***************
*** 44,49
                  t = s.cp_time[i];
                  s.cp_time[i] -= s1.cp_time[i];
                  s1.cp_time[i] = t;
          	if (dualcpu) {
  	                t = s.cp_time2[i];
          	        s.cp_time2[i] -= s1.cp_time2[i];

--- 46,52 -----
                  t = s.cp_time[i];
                  s.cp_time[i] -= s1.cp_time[i];
                  s1.cp_time[i] = t;
+ #ifdef DUALCPU
          	if (dualcpu) {
  	                t = s.cp_time2[i];
          	        s.cp_time2[i] -= s1.cp_time2[i];
***************
*** 49,54
          	        s.cp_time2[i] -= s1.cp_time2[i];
                  	s1.cp_time2[i] = t;
          	}
                  etime += s.cp_time[i];	/* interval must count 1 CPU only */
          }
          if(etime == 0.)

--- 52,58 -----
          	        s.cp_time2[i] -= s1.cp_time2[i];
                  	s1.cp_time2[i] = t;
          	}
+ #endif DUALCPU
                  etime += s.cp_time[i];	/* interval must count 1 CPU only */
          }
          if(etime == 0.)
***************
*** 77,82
  	/* Display CPU info */
          mvprintw(CPUY+1,4,"%4d  %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
          cputime();

--- 81,87 -----
  	/* Display CPU info */
          mvprintw(CPUY+1,4,"%4d  %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
+ #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
  #endif DUALCPU
***************
*** 79,84
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
          cputime();
  
  	/* Display additional stuff */

--- 84,90 -----
  #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
+ #endif DUALCPU
          cputime();
  
  	/* Display additional stuff */
***************
*** 112,117
          x = 6;
          for(i=0; i<CPUSTATES; i++){
                  mvprintw(TIMEY+1,x,"%3.0f", 100 * s.cp_time[i]/t);
          	if (dualcpu)
  	                mvprintw(TIMEY+1,x+27,"%3.0f", 100 * s.cp_time2[i]/t2);
                  x += 5;

--- 118,124 -----
          x = 6;
          for(i=0; i<CPUSTATES; i++){
                  mvprintw(TIMEY+1,x,"%3.0f", 100 * s.cp_time[i]/t);
+ #ifdef DUALCPU
          	if (dualcpu)
  	                mvprintw(TIMEY+1,x+27,"%3.0f", 100 * s.cp_time2[i]/t2);
  #endif DUALCPU
***************
*** 114,119
                  mvprintw(TIMEY+1,x,"%3.0f", 100 * s.cp_time[i]/t);
          	if (dualcpu)
  	                mvprintw(TIMEY+1,x+27,"%3.0f", 100 * s.cp_time2[i]/t2);
                  x += 5;
          }
  }

--- 121,127 -----
  #ifdef DUALCPU
          	if (dualcpu)
  	                mvprintw(TIMEY+1,x+27,"%3.0f", 100 * s.cp_time2[i]/t2);
+ #endif DUALCPU
                  x += 5;
          }
  }

guy@rlgvax.UUCP (Guy Harris) (12/09/84)

Here are some fixes and changes to "mon.c"; the context diffs are based on
the changes posted by Jonathan Biggar in article <1533@sdcrdcf.UUCP>.

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

Working file:    display.c
Moved the definitions of the screen positions of various fields into "mon.h".
Moved some column headings around to align them with their columns.
Fixed to limit the number of disks and network interfaces listed to the number
that will fit on all but the last line of the screen.

*** /tmp/,RCSt1a06329	Sat Dec  8 20:54:39 1984
--- display.c	Sat Dec  8 20:54:40 1984
***************
*** 8,25
  
  #define	HOSTLEN	40		/* Length of hostname */
  
- /* Screen Positions */
- #define	LEFT	0
- #define	PROCY	2
- #define	CPUY	5
- #define	TIMEY	8
- #define	PAGEY	11
- #define	CHARY	5
- #define	CHARX	37
- #define	NETIFY	17
- #define	DISKY	2
- #define	DISKX	55
- 
  /*
   * DISPINIT - clears the screen, puts up the info labels, and
   *   displays the initial information (device names).

--- 8,13 -----
  
  #define	HOSTLEN	40		/* Length of hostname */
  
  /*
   * DISPINIT - clears the screen, puts up the info labels, and
   *   displays the initial information (device names).
***************
*** 41,47
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
  #endif DUALCPU
!         mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");

--- 29,35 -----
  	if (dualcpu)
  	        mvprintw(CPUY,LEFT+25,"Cpu2: csw");
  #endif DUALCPU
!         mvprintw(TIMEY,LEFT,"Time: user nice  sys idle");
  #ifdef DUALCPU
  	if (dualcpu)
  	        mvprintw(TIMEY,LEFT+26,"Time2: user nice  sys idle");
***************
*** 44,50
          mvprintw(TIMEY,LEFT,"Time: user nice sys idle");
  #ifdef DUALCPU
  	if (dualcpu)
! 	        mvprintw(TIMEY,LEFT+26,"Time2: user nice sys idle");
  #endif DUALCPU
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");

--- 32,38 -----
          mvprintw(TIMEY,LEFT,"Time: user nice  sys idle");
  #ifdef DUALCPU
  	if (dualcpu)
! 	        mvprintw(TIMEY,LEFT+26,"Time2: user nice  sys idle");
  #endif DUALCPU
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
***************
*** 49,55
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");
!         mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs  Collis Oqueue");
  
  	/* add the disk drive names to the screen */
          for(i = 0; i < DK_NDRIVE; i++) {

--- 37,43 -----
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");
!         mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs Collis Oqueue");
  
  	/* add the disk drive names to the screen */
          for(i = 0; i < DK_NDRIVE && DISKY+1+i < LINES-3; i++) {
***************
*** 52,58
          mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs  Collis Oqueue");
  
  	/* add the disk drive names to the screen */
!         for(i = 0; i < DK_NDRIVE; i++) {
  		if (*dr_name[i])
  	                mvprintw(DISKY+1+i,DISKX,dr_name[i]);
  		else

--- 40,46 -----
          mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs Collis Oqueue");
  
  	/* add the disk drive names to the screen */
!         for(i = 0; i < DK_NDRIVE && DISKY+1+i < LINES-3; i++) {
  		if (*dr_name[i])
  	                mvprintw(DISKY+1+i,DISKX,dr_name[i]);
  		else
***************
*** 62,68
  	mvprintw(DISKY+2+i,DISKX,"Total:");
  
  	/* put up the network interface names */
! 	for (i = 0; i < numif; i++)
  		mvprintw(NETIFY+1+i,LEFT,nifinfo[i].name);
  }
  

--- 50,56 -----
  	mvprintw(DISKY+2+i,DISKX,"Total:");
  
  	/* put up the network interface names */
! 	for (i = 0; i < numif && NETIFY+1+i < LINES-1; i++)
  		mvprintw(NETIFY+1+i,LEFT,nifinfo[i].name);
  }
  
***************
*** 73,79
  {
  	int	i;
  
! 	for (i = 0; i < numif; i++)
  		mvprintw(NETIFY+1+i,LEFT+7,"%5d  %5d  %5d  %5d  %5d  %5d",
  			nifdat[i].ipackets, nifdat[i].ierrors,
  			nifdat[i].opackets, nifdat[i].oerrors,

--- 61,67 -----
  {
  	int	i;
  
! 	for (i = 0; i < numif && NETIFY+1+i < LINES-1; i++)
  		mvprintw(NETIFY+1+i,LEFT+7,"%5d  %5d  %5d  %5d  %5d  %5d",
  			nifdat[i].ipackets, nifdat[i].ierrors,
  			nifdat[i].opackets, nifdat[i].oerrors,

Working file:    io.c
Moved the definitions of the screen positions of various fields into "mon.h".
Moved some columns around, and shortened some, to align them with their column
headings.
Fixed to limit the number of disks listed to the number that will fit on all
but the last line of the screen.

*** /tmp/,RCSt1a06338	Sat Dec  8 20:54:56 1984
--- io.c	Sat Dec  8 20:46:43 1984
***************
*** 13,23
  
  /* Temporary Defines - All output should be moved to dispinfo */
  #include <curses.h>
! #define CHARX   37
! #define	CHARY	5
! #define	DISKX	55
! #define	DISKY	2
! #define	DISKOFF	6
  #define	DISKWDS	DISKOFF
  #define	DISKXFER DISKOFF+4
  #define	DISKSEEK DISKOFF+8

--- 13,19 -----
  
  /* Temporary Defines - All output should be moved to dispinfo */
  #include <curses.h>
! #define	DISKOFF	7
  #define	DISKWDS	DISKOFF
  #define	DISKXFER DISKOFF+4
  #define	DISKSEEK DISKOFF+8
***************
*** 81,86
  	if (!*dr_name[dn])
  		return(0);
  
          y = dn + DISKY+1;
  	lasty = y;
          if (s.dk_mspw[dn] == 0.0) {

--- 77,83 -----
  	if (!*dr_name[dn])
  		return(0);
  
+ 	/* only display info that fits on the screen */
          y = dn + DISKY+1;
  	if (y >= LINES-3)
  		return(0);
***************
*** 82,87
  		return(0);
  
          y = dn + DISKY+1;
  	lasty = y;
          if (s.dk_mspw[dn] == 0.0) {
                  mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%6.1f ", 0.0, 0.0, 0.0);

--- 79,87 -----
  
  	/* only display info that fits on the screen */
          y = dn + DISKY+1;
+ 	if (y >= LINES-3)
+ 		return(0);
+ 
  	lasty = y;
          if (s.dk_mspw[dn] == 0.0) {
                  mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%5.1f", 0.0, 0.0, 0.0);
***************
*** 84,90
          y = dn + DISKY+1;
  	lasty = y;
          if (s.dk_mspw[dn] == 0.0) {
!                 mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%6.1f ", 0.0, 0.0, 0.0);
                  return(0);
          }
          atime = s.dk_time[dn];

--- 84,90 -----
  
  	lasty = y;
          if (s.dk_mspw[dn] == 0.0) {
!                 mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%5.1f", 0.0, 0.0, 0.0);
                  return(0);
          }
          atime = s.dk_time[dn];
***************
*** 103,109
  	tps = s.dk_xfer[dn]/etime;
          mvprintw(y,DISKX+DISKWDS,"%4.0f", kbps);
          mvprintw(y,DISKX+DISKXFER,"%4.0f", tps);
!         mvprintw(y,DISKX+DISKSEEK,"%6.1f ",
              s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0);
  
  	return(1);	/* Update totals */

--- 103,109 -----
  	tps = s.dk_xfer[dn]/etime;
          mvprintw(y,DISKX+DISKWDS,"%4.0f", kbps);
          mvprintw(y,DISKX+DISKXFER,"%4.0f", tps);
!         mvprintw(y,DISKX+DISKSEEK,"%5.1f",
              s.dk_seek[dn] ? itime*1000./s.dk_seek[dn] : 0.0);
  
  	return(1);	/* Update totals */

Working file:    mon.c
Removed the definition of "ttyb" because it wasn't used anymore and caused
it not to compile with our S5 tty driver.
Fixed to put the terminal into no-echo mode.
Moved the command prompt to the defined bottom of the screen rather than line
23.
Fixed to clear the command prompt line when exiting.

*** /tmp/,RCSt1a06349	Sat Dec  8 20:55:13 1984
--- mon.c	Sat Dec  8 20:48:31 1984
***************
*** 10,16
  #include <curses.h>
  #include <signal.h>
  
- struct	sgttyb ttyb;
  int done();
  
  /*

--- 10,15 -----
  #include <curses.h>
  #include <signal.h>
  
  int done();
  
  /*
***************
*** 104,109
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */
  	crmode();	/* set terminal into cbreak mode */
  	nifinit();	/* get initial net interfaces data */
          dispinit();     /* initialize display */
          for(;;){

--- 103,109 -----
  	tintv.tv_usec = 0;
  	initscr();	/* init curses package */
  	crmode();	/* set terminal into cbreak mode */
+ 	noecho();	/* set terminal into no-echo mode */
  	nifinit();	/* get initial net interfaces data */
          dispinit();     /* initialize display */
          for(;;){
***************
*** 117,123
                  time(&clock);
                  mvprintw(0,40,ctime(&clock));
          	dispupdate();
!         	mvprintw(23, 0, "CMD> ");
                  refresh();
          	tin = 1;
          	i = select(2, &tin, (int *)0, (int *)0, &tintv);

--- 117,123 -----
                  time(&clock);
                  mvprintw(0,40,ctime(&clock));
          	dispupdate();
!         	mvprintw(LINES-1, 0, "CMD> ");
                  refresh();
          	tin = 1;
          	i = select(2, &tin, (int *)0, (int *)0, &tintv);
***************
*** 132,138
  }
  
  /*
!  * DONE - put the term back in non CBREAK mode and exit.
   */
  done()
  {

--- 132,138 -----
  }
  
  /*
!  * DONE - put the term back in ECHO, non CBREAK mode and exit.
   */
  done()
  {
***************
*** 136,141
   */
  done()
  {
  	refresh();
  	endwin();
  	exit(0);

--- 136,142 -----
   */
  done()
  {
+ 	mvprintw(LINES-1,0,"\n");
  	refresh();
  	endwin();
  	exit(0);

Working file:    mon.h
Moved the definitions of the screen positions of various fields into "mon.h".

*** /tmp/,RCSt1a06363	Sat Dec  8 20:55:41 1984
--- mon.h	Sat Dec  8 20:49:41 1984
***************
*** 96,98
  
  #define rate            s.Rate
  #define total           s.Total

--- 96,112 -----
  
  #define rate            s.Rate
  #define total           s.Total
+ 
+ /*
+  * Positions of various data on the screen.
+  */
+ #define	LEFT	0
+ #define	PROCY	2
+ #define	CPUY	5
+ #define	TIMEY	8
+ #define	PAGEY	11
+ #define	CHARY	5
+ #define	CHARX	37
+ #define	NETIFY	17
+ #define	DISKY	2
+ #define	DISKX	55

Working file:    vm.c
Moved the definitions of the screen positions of various fields into "mon.h",
and changed PROCS to PROCY and PAGE to PAGEY because that's what they're called
in the definitions from "display.c".
Moved some columns around to align them with their column headings.

*** /tmp/,RCSt1a06370	Sat Dec  8 20:55:59 1984
--- vm.c	Sat Dec  8 20:52:02 1984
***************
*** 13,24
  #include "mon.h"
  #include <machine/param.h>	/* defines bytes/page */
  
- /* Temporary defines */
- #define	PROCS	2
- #define	CPUY	5
- #define	TIMEY	8
- #define	PAGE	11
- 
  vm()
  {
          register i,j;

--- 13,18 -----
  #include "mon.h"
  #include <machine/param.h>	/* defines bytes/page */
  
  vm()
  {
          register i,j;
***************
*** 60,66
          etime /= (float) hz;
  
  	/* Display the procs line */
!         mvprintw(PROCS+1,6,"%2d%2d%2d%2d %2d", total.t_rq, total.t_dw, total.t_pw, total.t_sw, total.t_sl);
  #define pgtok(a) ((a)*NBPG/1024)
          mvprintw(PROCS+1,23,"%5d %5d", pgtok(total.t_rm), pgtok(total.t_arm) );
          mvprintw(PROCS+1,34,"%6d %5d", pgtok(total.t_vm), pgtok(total.t_avm) );

--- 54,60 -----
          etime /= (float) hz;
  
  	/* Display the procs line */
!         mvprintw(PROCY+1,6,"%2d%2d%2d%2d %2d", total.t_rq, total.t_dw, total.t_pw, total.t_sw, total.t_sl);
  #define pgtok(a) ((a)*NBPG/1024)
          mvprintw(PROCY+1,23,"%5d %5d", pgtok(total.t_rm), pgtok(total.t_arm) );
          mvprintw(PROCY+1,34,"%6d %5d", pgtok(total.t_vm), pgtok(total.t_avm) );
***************
*** 62,70
  	/* Display the procs line */
          mvprintw(PROCS+1,6,"%2d%2d%2d%2d %2d", total.t_rq, total.t_dw, total.t_pw, total.t_sw, total.t_sl);
  #define pgtok(a) ((a)*NBPG/1024)
!         mvprintw(PROCS+1,23,"%5d %5d", pgtok(total.t_rm), pgtok(total.t_arm) );
!         mvprintw(PROCS+1,34,"%6d %5d", pgtok(total.t_vm), pgtok(total.t_avm) );
!         mvprintw(PROCS+1,47,"%5d", pgtok(total.t_free));
  
  	/* Display paging info */
          mvprintw(PAGE+1,6,"%4d %3d",

--- 56,64 -----
  	/* Display the procs line */
          mvprintw(PROCY+1,6,"%2d%2d%2d%2d %2d", total.t_rq, total.t_dw, total.t_pw, total.t_sw, total.t_sl);
  #define pgtok(a) ((a)*NBPG/1024)
!         mvprintw(PROCY+1,23,"%5d %5d", pgtok(total.t_rm), pgtok(total.t_arm) );
!         mvprintw(PROCY+1,34,"%6d %5d", pgtok(total.t_vm), pgtok(total.t_avm) );
!         mvprintw(PROCY+1,47,"%5d", pgtok(total.t_free));
  
  	/* Display paging info */
          mvprintw(PAGEY+1,6,"%4d %3d",
***************
*** 67,73
          mvprintw(PROCS+1,47,"%5d", pgtok(total.t_free));
  
  	/* Display paging info */
!         mvprintw(PAGE+1,6,"%4d %3d",
                  (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec)),
                  (rate.v_xsfrec+rate.v_xifrec));
          mvprintw(PAGE+1,14,"%4d %4d", pgtok(rate.v_pgpgin),

--- 61,67 -----
          mvprintw(PROCY+1,47,"%5d", pgtok(total.t_free));
  
  	/* Display paging info */
!         mvprintw(PAGEY+1,6,"%4d %3d",
                  (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec)),
                  (rate.v_xsfrec+rate.v_xifrec));
          mvprintw(PAGEY+1,14,"%4d %4d", pgtok(rate.v_pgpgin),
***************
*** 70,76
          mvprintw(PAGE+1,6,"%4d %3d",
                  (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec)),
                  (rate.v_xsfrec+rate.v_xifrec));
!         mvprintw(PAGE+1,14,"%4d %4d", pgtok(rate.v_pgpgin),
                  pgtok(rate.v_pgpgout));
  	/* operations per time is (pgin + pgout)  */
          mvprintw(PAGE+1,24,"%4d", (pgtok(rate.v_pgin)+

--- 64,70 -----
          mvprintw(PAGEY+1,6,"%4d %3d",
                  (rate.v_pgrec - (rate.v_xsfrec+rate.v_xifrec)),
                  (rate.v_xsfrec+rate.v_xifrec));
!         mvprintw(PAGEY+1,14,"%4d %4d", pgtok(rate.v_pgpgin),
                  pgtok(rate.v_pgpgout));
  	/* operations per time is (pgin + pgout)  */
          mvprintw(PAGEY+1,25,"%4d", (pgtok(rate.v_pgin)+
***************
*** 73,79
          mvprintw(PAGE+1,14,"%4d %4d", pgtok(rate.v_pgpgin),
                  pgtok(rate.v_pgpgout));
  	/* operations per time is (pgin + pgout)  */
!         mvprintw(PAGE+1,24,"%4d", (pgtok(rate.v_pgin)+
                  pgtok(rate.v_pgout)));
          mvprintw(PAGE+1,29,"%4d %4d %4d", pgtok(rate.v_dfree)
                  , pgtok(deficit), rate.v_scan);

--- 67,73 -----
          mvprintw(PAGEY+1,14,"%4d %4d", pgtok(rate.v_pgpgin),
                  pgtok(rate.v_pgpgout));
  	/* operations per time is (pgin + pgout)  */
!         mvprintw(PAGEY+1,25,"%4d", (pgtok(rate.v_pgin)+
                  pgtok(rate.v_pgout)));
          mvprintw(PAGEY+1,29,"%4d %4d %4d", pgtok(rate.v_dfree)
                  , pgtok(deficit), rate.v_scan);
***************
*** 75,81
  	/* operations per time is (pgin + pgout)  */
          mvprintw(PAGE+1,24,"%4d", (pgtok(rate.v_pgin)+
                  pgtok(rate.v_pgout)));
!         mvprintw(PAGE+1,29,"%4d %4d %4d", pgtok(rate.v_dfree)
                  , pgtok(deficit), rate.v_scan);
  
  	/* Display CPU info */

--- 69,75 -----
  	/* operations per time is (pgin + pgout)  */
          mvprintw(PAGEY+1,25,"%4d", (pgtok(rate.v_pgin)+
                  pgtok(rate.v_pgout)));
!         mvprintw(PAGEY+1,29,"%4d %4d %4d", pgtok(rate.v_dfree)
                  , pgtok(deficit), rate.v_scan);
  
  	/* Display CPU info */
***************
*** 79,85
                  , pgtok(deficit), rate.v_scan);
  
  	/* Display CPU info */
!         mvprintw(CPUY+1,4,"%4d  %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  #ifdef DUALCPU
  	if (dualcpu)

--- 73,79 -----
                  , pgtok(deficit), rate.v_scan);
  
  	/* Display CPU info */
!         mvprintw(CPUY+1,5,"%4d   %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  #ifdef DUALCPU
  	if (dualcpu)
***************
*** 88,94
          cputime();
  
  	/* Display additional stuff */
! 	mvprintw(PAGE+4,6,"%4d%4d %4d%4d %4d%4d %4d %4d%4d",
  		rate.v_nexfod, rate.v_exfod,
  		rate.v_nzfod, rate.v_zfod,
  		rate.v_nvrfod, rate.v_vrfod,

--- 82,88 -----
          cputime();
  
  	/* Display additional stuff */
! 	mvprintw(PAGEY+4,6,"%4d%4d %4d%4d %4d%4d %4d %4d%4d",
  		rate.v_nexfod, rate.v_exfod,
  		rate.v_nzfod, rate.v_zfod,
  		rate.v_nvrfod, rate.v_vrfod,
***************
*** 115,121
  		t = 1.;
  	if (t2 == 0.)
  		t2 = 1.;
!         x = 6;
          for(i=0; i<CPUSTATES; i++){
                  mvprintw(TIMEY+1,x,"%3.0f", 100 * s.cp_time[i]/t);
  #ifdef DUALCPU

--- 109,115 -----
  		t = 1.;
  	if (t2 == 0.)
  		t2 = 1.;
!         x = 7;
          for(i=0; i<CPUSTATES; i++){
                  mvprintw(TIMEY+1,x,"%3.0f", 100 * s.cp_time[i]/t);
  #ifdef DUALCPU

ddj@brunix.UUCP (Dave Johnson) (12/12/84)

I've made some changes to mon in addition to those
posted by Jonathan Biggar in article <1533@sdcrdcf.UUCP>,
and by Guy Harris in article <290@rlgvax.UUCP>.

1) Added code to report the number of forks and vforks
during each interval (this number is usually small enough
to get rounded to zero if you convert into a per-second
rate, so I made it a raw number).

2) Removed three redundant kmem lseek/read calls.  dk_mspw
doesn't change after the system is booted (nor does dk_bps
on the sun), so reading it in mon.c should suffice.
Also dk_xfer isn't used in vm.c, it's read in io.c already.
Finally, hz doesn't change while the program is running either.

3) Added a test for no disks at all before printing the
total disk activity -- makes it just a tad prettier on
a diskless sun.

4) Fixed the disk statistics code to work on either VAXen
or Suns.  Sun's disk drivers maintain a byte/second figure
for each drive rather than Berkeley's millisecond/word.

5) Fixed the load average code for Suns -- they keep the
value as scaled integers rather than as doubles.

6) Fixed the interrupt/second code for Suns -- they don't
count clock interrupts, Berkeley does.

	Dave Johnson
	Brown University CS Dept.
	{ihnp4,decvax,allegra}!brunix!ddj
	ddj%brown.CSNET@csnet-relay.ARPA

------------------
diff -c org/display.c sun/display.c
*** org/display.c	Tue Dec 11 23:17:24 1984
--- sun/display.c	Tue Dec 11 23:42:01 1984
***************
*** 37,42
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");
          mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs Collis Oqueue");

  	/* add the disk drive names to the screen */

--- 37,43 -----
          mvprintw(PAGEY,LEFT,"Paging: re  at pin pout  oprs  fr  def   sr");
  	mvprintw(PAGEY+3,LEFT,"       nxf  xf  nzf  zf  nrf  rf  prf  swi swo");
          mvprintw(CHARY,CHARX,"Char: in   out");
+ 	mvprintw(FORKY,FORKX,"Forks: fork vfork");
          mvprintw(NETIFY,LEFT,"Name   Ipkts  Ierrs  Opkts  Oerrs Collis Oqueue");

  	/* add the disk drive names to the screen */
diff -c org/io.c sun/io.c
*** org/io.c	Tue Dec 11 23:22:10 1984
--- sun/io.c	Tue Dec 11 23:42:29 1984
***************
*** 37,46
          read(kmem, &s.tk_nout, sizeof s.tk_nout);
          lseek(kmem, (long)namelist[X_DK_SEEK].n_value, 0);
          read(kmem, s.dk_seek, sizeof s.dk_seek);
-         lseek(kmem, (long)namelist[X_DK_MSPW].n_value, 0);
-         read(kmem, s.dk_mspw, sizeof s.dk_mspw);
-         lseek(kmem, (long)namelist[X_HZ].n_value, 0);
-         read(kmem, &hz, sizeof hz);
          for (i = 0; i < DK_NDRIVE; i++) {
#define X(fld)  t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
                X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);

--- 37,42 -----
          read(kmem, &s.tk_nout, sizeof s.tk_nout);
          lseek(kmem, (long)namelist[X_DK_SEEK].n_value, 0);
          read(kmem, s.dk_seek, sizeof s.dk_seek);
          for (i = 0; i < DK_NDRIVE; i++) {
#define X(fld)  t = s.fld[i]; s.fld[i] -= s1.fld[i]; s1.fld[i] = t
                X(dk_xfer); X(dk_seek); X(dk_wds); X(dk_time);
***************
*** 60,66
                  }
          }
  	/* Display Totals */
! 	mvprintw(lasty+2, DISKX+DISKOFF, "%4.0f%4.0f", tkbps, ttps);
  }

  /*

--- 58,65 -----
                  }
          }
  	/* Display Totals */
! 	if (lasty != 0)
! 		mvprintw(lasty+2, DISKX+DISKOFF, "%4.0f%4.0f", tkbps, ttps);
  }

  /*
***************
*** 83,89
  		return(0);

  	lasty = y;
!         if (s.dk_mspw[dn] == 0.0) {
                  mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%5.1f", 0.0, 0.0, 0.0);
                  return(0);
          }

--- 82,88 -----
  		return(0);

  	lasty = y;
!         if (s.dk_xfer[dn] == 0) {
                  mvprintw(y,DISKX+DISKOFF,"%4.0f%4.0f%5.1f", 0.0, 0.0, 0.0);
                  return(0);
          }
***************
*** 90,96
          atime = s.dk_time[dn];
          atime /= (float) hz;
          words = s.dk_wds[dn]*32.0;      /* number of 16 bit words transferred */
!         xtime = s.dk_mspw[dn]*words;    /* transfer time */
          itime = atime - xtime;          /* time not transferring (seek time) */

          if (xtime < 0)

--- 89,99 -----
          atime = s.dk_time[dn];
          atime /= (float) hz;
          words = s.dk_wds[dn]*32.0;      /* number of 16 bit words transferred */
! #ifdef sun
! 	xtime = words*2/s.dk_bps[dn];
! #else sun
! 	xtime = s.dk_mspw[dn]*words;    /* transfer time */
! #endif sun
          itime = atime - xtime;          /* time not transferring (seek time) */

          if (xtime < 0)
diff -c org/mon.c sun/mon.c
*** org/mon.c	Tue Dec 11 23:24:20 1984
--- sun/mon.c	Tue Dec 11 23:47:47 1984
***************
*** 19,25
   */
  struct nlist namelist[] = {
  	{ "_dk_busy" },
  	{ "_dk_mspw" },
  	{ "_hz" },
  	{ "_cp_time" },
  	{ "_rate" },

--- 19,29 -----
   */
  struct nlist namelist[] = {
  	{ "_dk_busy" },
! #ifdef sun
! 	{ "_dk_bps" },
! #else sun
! 	{ "_dk_mspw" },
! #endif sun
  	{ "_hz" },
  	{ "_cp_time" },
  	{ "_rate" },
***************
*** 35,40
  	{ "_tk_nin" },
  	{ "_tk_nout" },
  	{ "_avenrun" },
  #ifdef DUALCPU
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */

--- 39,45 -----
  	{ "_tk_nin" },
  	{ "_tk_nout" },
  	{ "_avenrun" },
+ 	{ "_forkstat" },
  #ifdef DUALCPU
  	{ "_cp2_time" },	/* 2nd CPU stats */
  	{ "_slavestart" },	/* Used to detect 2nd CPU */
***************
*** 70,77
  /*
   * do all things that need to be done only once
   */
!         lseek(kmem, (long)namelist[X_DK_MSPW].n_value, 0);
!         read(kmem, s.dk_mspw, sizeof s.dk_mspw);
          lseek(kmem, (long)namelist[X_HZ].n_value, 0);
          read(kmem, &hz, sizeof hz);
  	read_names();

--- 75,90 -----
  /*
   * do all things that need to be done only once
   */
! #ifdef sun
! 	lseek(kmem, (long)namelist[X_DK_BPS].n_value, 0);
! 	read(kmem, s.dk_bps, sizeof s.dk_bps);
! #else sun
! 	lseek(kmem, (long)namelist[X_DK_MSPW].n_value, 0);
! 	read(kmem, s.dk_mspw, sizeof s.dk_mspw);
! #endif sun
! 	/* prime the fork counters so we don't see forks since boot */
! 	lseek(kmem, (long)namelist[X_FORKSTAT].n_value, 0);
! 	read(kmem, &s1.forkstat, sizeof s1.forkstat);
          lseek(kmem, (long)namelist[X_HZ].n_value, 0);
          read(kmem, &hz, sizeof hz);
  	read_names();
***************
*** 113,119
          	/* get load average */
  		lseek(kmem, (long)namelist[LOADAV].n_value, 0);
  		read(kmem, &loadavg[0], sizeof loadavg);
!         	mvprintw(0,13,"%4.2f %4.2f %4.2f %4.2f", loadavg[3], loadavg[0], loadavg[1], loadavg[2]);
                  time(&clock);
                  mvprintw(0,40,ctime(&clock));
          	dispupdate();

--- 123,135 -----
          	/* get load average */
  		lseek(kmem, (long)namelist[LOADAV].n_value, 0);
  		read(kmem, &loadavg[0], sizeof loadavg);
! #ifdef sun
! 		mvprintw(0,13,"%4.2f %4.2f %4.2f",
! 			loadavg[0]/256., loadavg[1]/256., loadavg[2]/256.);
! #else sun
! 		mvprintw(0,13,"%4.2f %4.2f %4.2f %4.2f",
! 				loadavg[3], loadavg[0], loadavg[1], loadavg[2]);
! #endif sun
                  time(&clock);
                  mvprintw(0,40,ctime(&clock));
          	dispupdate();
diff -c org/mon.h sun/mon.h
*** org/mon.h	Tue Dec 11 23:38:35 1984
--- sun/mon.h	Tue Dec 11 23:51:25 1984
***************
*** 16,22
   *  definition of namelist in main.
   */
  #define	X_DK_BUSY	0
! #define	X_DK_MSPW	1
  #define	X_HZ		2
  #define	X_CP_TIME	3
  #define	X_RATE		4

--- 16,26 -----
   *  definition of namelist in main.
   */
  #define	X_DK_BUSY	0
! #ifdef sun
! #define	X_DK_BPS	1
! #else sun
! #define	X_DK_MSPW	1
! #endif sun
  #define	X_HZ		2
  #define	X_CP_TIME	3
  #define	X_RATE		4
***************
*** 32,37
  #define	X_TK_NIN	14
  #define	X_TK_NOUT	15
  #define	LOADAV		16
  #ifdef DUALCPU
  #define X_CP_TIME2	17	/* 2nd CPU stats */
  #define	X_SLAVESTART	18	/* 2nd cpu existance test */

--- 36,42 -----
  #define	X_TK_NIN	14
  #define	X_TK_NOUT	15
  #define	LOADAV		16
+ #define	X_FORKSTAT	17
  #ifdef DUALCPU
  #define	X_CP_TIME2	18	/* 2nd CPU stats */
  #define	X_SLAVESTART	19	/* 2nd cpu existance test */
***************
*** 33,40
  #define	X_TK_NOUT	15
  #define	LOADAV		16
  #ifdef DUALCPU
! #define X_CP_TIME2	17	/* 2nd CPU stats */
! #define	X_SLAVESTART	18	/* 2nd cpu existance test */
  #endif DUALCPU

  extern struct nlist namelist[];

--- 38,45 -----
  #define	LOADAV		16
  #define	X_FORKSTAT	17
  #ifdef DUALCPU
! #define	X_CP_TIME2	18	/* 2nd CPU stats */
! #define	X_SLAVESTART	19	/* 2nd cpu existance test */
  #endif DUALCPU

  extern struct nlist namelist[];
***************
*** 46,52
  int kmem, hz;
  int deficit;
  double etime;
! double loadavg[4];

  /* drive names and numbers */
  char dr_name[DK_NDRIVE][10];

--- 51,61 -----
  int kmem, hz;
  int deficit;
  double etime;
! #ifdef sun
! long loadavg[3];
! #else sun
! double loadavg[4];
! #endif sun

  /* drive names and numbers */
  char dr_name[DK_NDRIVE][10];
***************
*** 88,94
          long    dk_wds[DK_NDRIVE];
          long    dk_seek[DK_NDRIVE];
          long    dk_xfer[DK_NDRIVE];
!         float   dk_mspw[DK_NDRIVE];
          long    tk_nin;
          long    tk_nout;
          struct  vmmeter Rate;

--- 97,107 -----
          long    dk_wds[DK_NDRIVE];
          long    dk_seek[DK_NDRIVE];
          long    dk_xfer[DK_NDRIVE];
! #ifdef sun
!         long    dk_bps[DK_NDRIVE];
! #else sun
!         float   dk_mspw[DK_NDRIVE];
! #endif sun
          long    tk_nin;
          long    tk_nout;
          struct  vmmeter Rate;
***************
*** 93,98
          long    tk_nout;
          struct  vmmeter Rate;
          struct  vmtotal Total;
  } s, s1;

  #define rate            s.Rate

--- 106,112 -----
          long    tk_nout;
          struct  vmmeter Rate;
          struct  vmtotal Total;
+         struct  forkstat forkstat;
  } s, s1;

  #define rate            s.Rate
***************
*** 109,113
  #define	CHARY	5
  #define	CHARX	37
  #define	NETIFY	17
! #define	DISKY	2
  #define	DISKX	55

--- 123,129 -----
  #define	CHARY	5
  #define	CHARX	37
  #define	NETIFY	17
! #define	DISKY	5
  #define	DISKX	55
  #define	FORKY	2
  #define	FORKX	55
***************
*** 111,113
  #define	NETIFY	17
  #define	DISKY	2
  #define	DISKX	55

--- 125,129 -----
  #define	NETIFY	17
  #define	DISKY	5
  #define	DISKX	55
+ #define	FORKY	2
+ #define	FORKX	55
diff -c org/readnames.c sun/readnames.c
*** org/readnames.c	Tue Dec 11 23:05:00 1984
--- sun/readnames.c	Tue Dec 11 22:52:53 1984
***************
*** 6,13
   */
  #include "mon.h"
  #include <sys/buf.h>		/* needed by following two includes */
! #include <vaxuba/ubavar.h>	/* unibus adapters */
! #include <vaxmba/mbavar.h>	/* massbus adapters */

  #define steal(where, var) lseek(kmem, where, 0); read(kmem, &var, sizeof var);


--- 6,18 -----
   */
  #include "mon.h"
  #include <sys/buf.h>		/* needed by following two includes */
! #ifdef vax
! #include <vaxuba/ubavar.h>	/* unibus adapters */
! #include <vaxmba/mbavar.h>	/* massbus adapters */
! #endif vax
! #ifdef sun
! #include <sundev/mbvar.h>	/* multibus */
! #endif sun

  #define steal(where, var) lseek(kmem, where, 0); read(kmem, &var, sizeof var);

***************
*** 13,18

  read_names()
  {
          struct mba_device mdev;
          register struct mba_device *mp;
          struct mba_driver mdrv;

--- 18,24 -----

  read_names()
  {
+ #ifdef vax
          struct mba_device mdev;
          register struct mba_device *mp;
          struct mba_driver mdrv;
***************
*** 16,21
          struct mba_device mdev;
          register struct mba_device *mp;
          struct mba_driver mdrv;
          short two_char;
          char *cp = (char *) &two_char;
          struct uba_device udev, *up;

--- 22,33 -----
          struct mba_device mdev;
          register struct mba_device *mp;
          struct mba_driver mdrv;
+ #endif vax
+ #ifdef sun
+         struct mb_device mdev;
+         register struct mb_device *mp;
+         struct mb_driver mdrv;
+ #endif sun
          short two_char;
          char *cp = (char *) &two_char;
  #ifdef vax
***************
*** 18,23
          struct mba_driver mdrv;
          short two_char;
          char *cp = (char *) &two_char;
          struct uba_device udev, *up;
          struct uba_driver udrv;


--- 30,36 -----
  #endif sun
          short two_char;
          char *cp = (char *) &two_char;
+ #ifdef vax
          struct uba_device udev, *up;
          struct uba_driver udrv;

***************
*** 45,48
                  sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit);
                  dr_unit[udev.ui_dk] = udev.ui_unit;
          }
  }

--- 58,76 -----
                  sprintf(dr_name[udev.ui_dk], "%c%c%d", cp[0], cp[1], udev.ui_unit);
                  dr_unit[udev.ui_dk] = udev.ui_unit;
          }
+ #endif vax
+ #ifdef sun
+         mp = (struct mb_device *) namelist[X_MBDINIT].n_value;
+         if (mp) for (;;) {
+                 steal(mp++, mdev);
+                 if (mdev.md_driver == 0)
+                         break;
+                 if (mdev.md_dk < 0 || mdev.md_alive == 0)
+                         continue;
+                 steal(mdev.md_driver, mdrv);
+                 steal(mdrv.mdr_dname, two_char);
+                 sprintf(dr_name[mdev.md_dk], "%c%c%d", cp[0], cp[1], mdev.md_unit);
+                 dr_unit[mdev.md_dk] = mdev.md_unit;
+         }
+ #endif sun
  }
diff -c org/vm.c sun/vm.c
*** org/vm.c	Tue Dec 11 23:33:33 1984
--- sun/vm.c	Tue Dec 11 23:43:37 1984
***************
*** 27,34
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);
  	}
  #endif DUALCPU
-         lseek(kmem, (long)namelist[X_DK_XFER].n_value, 0);
-         read(kmem, s.dk_xfer, sizeof s.dk_xfer);
          lseek(kmem, (long)namelist[X_RATE].n_value, 0);
          read(kmem, &rate, sizeof rate);
          lseek(kmem, (long)namelist[X_TOTAL].n_value, 0);

--- 27,32 -----
  	        read(kmem, s.cp_time2, sizeof s.cp_time2);
  	}
  #endif DUALCPU
          lseek(kmem, (long)namelist[X_RATE].n_value, 0);
          read(kmem, &rate, sizeof rate);
          lseek(kmem, (long)namelist[X_TOTAL].n_value, 0);
***************
*** 35,40
          read(kmem, &total, sizeof total);
          lseek(kmem, (long)namelist[X_DEFICIT].n_value, 0);
          read(kmem, &deficit, sizeof deficit);
          etime = 0;
          for (i=0; i < CPUSTATES; i++) {
                  t = s.cp_time[i];

--- 33,40 -----
          read(kmem, &total, sizeof total);
          lseek(kmem, (long)namelist[X_DEFICIT].n_value, 0);
          read(kmem, &deficit, sizeof deficit);
+         lseek(kmem, (long)namelist[X_FORKSTAT].n_value, 0);
+         read(kmem, &s.forkstat, sizeof s.forkstat);
          etime = 0;
          for (i=0; i < CPUSTATES; i++) {
                  t = s.cp_time[i];
***************
*** 73,79
                  , pgtok(deficit), rate.v_scan);

  	/* Display CPU info */
!         mvprintw(CPUY+1,5,"%4d   %4d", (rate.v_intr) - hz, rate.v_syscall);
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  #ifdef DUALCPU
  	if (dualcpu)

--- 73,83 -----
                  , pgtok(deficit), rate.v_scan);

  	/* Display CPU info */
! #ifdef sun
!         mvprintw(CPUY+1,5,"%4d   %4d", rate.v_intr, rate.v_syscall);
! #else
!         mvprintw(CPUY+1,5,"%4d   %4d", (rate.v_intr) - hz, rate.v_syscall);
! #endif sun
          mvprintw(CPUY+1,17,"%4d", rate.v_swtch);
  #ifdef DUALCPU
  	if (dualcpu)
***************
*** 80,85
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
  #endif DUALCPU
          cputime();

  	/* Display additional stuff */
  	mvprintw(PAGEY+4,6,"%4d%4d %4d%4d %4d%4d %4d %4d%4d",

--- 84,98 -----
  	        mvprintw(CPUY+1,30,"%4d", rate.v_swtch2);
  #endif DUALCPU
          cputime();
+ 	/* Display FORK info */
+         t = s.forkstat.cntfork;
+ 	    s.forkstat.cntfork -= s1.forkstat.cntfork;
+ 	    s1.forkstat.cntfork = t;
+         t = s.forkstat.cntvfork;
+ 	    s.forkstat.cntvfork -= s1.forkstat.cntvfork;
+ 	    s1.forkstat.cntvfork = t;
+ 	mvprintw(FORKY+1,FORKX+6,"%5d %5d",
+ 		s.forkstat.cntfork, s.forkstat.cntvfork);

  	/* Display additional stuff */
  	mvprintw(PAGEY+4,6,"%4d%4d %4d%4d %4d%4d %4d %4d%4d",