Subject: working pstat -t.
To: None <current-users@NetBSD.ORG>
From: matthew green <mrg@eterna.com.au>
List: current-users
Date: 05/24/1996 22:42:05
well, after having a quick hack at it last night, listening
to charles' idea, and then beating out the details with jason,
i've implimented tty stats.

currently, serial/console ports only work for the sparc but
it is fairly simple to make these work for other ports.  just
call `tty_attach(tp)'.

below is a shar with two patches in it.  one is for pstat(8)
and one is for the kernel.

please let me know how these work for you.

thanks,

.mrg.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	pstat-t-sys.diff
#	pstat.c.diff
#
echo x - pstat-t-sys.diff
sed 's/^X//' >pstat-t-sys.diff << 'END-of-pstat-t-sys.diff'
XIndex: src/sys/sys/tty.h
X===================================================================
XRCS file: /local/cvs/src/sys/sys/tty.h,v
Xretrieving revision 1.1.1.4
Xdiff -c -r1.1.1.4 tty.h
X*** tty.h	1996/05/04 09:07:53	1.1.1.4
X***************
X*** 81,86 ****
X--- 81,87 ----
X   * (low, high, timeout).
X   */
X  struct tty {
X+ 	TAILQ_ENTRY(tty) tty_link;	/* Link in global tty list. */
X  	struct	clist t_rawq;		/* Device raw input queue. */
X  	long	t_rawcc;		/* Raw input queue statistics. */
X  	struct	clist t_canq;		/* Device canonical queue. */
X***************
X*** 191,197 ****
X--- 192,205 ----
X  #define	isbackground(p, tp)						\
X  	(isctty((p), (tp)) && (p)->p_pgrp != (tp)->t_pgrp)
X  
X+ /*
X+  * ttylist_head is defined here so that user-land has access to it.
X+  */
X+ TAILQ_HEAD(ttylist_head, tty);		/* the ttylist is a TAILQ */
X+ 
X  #ifdef _KERNEL
X+ 
X+ extern	int tty_count;			/* number of ttys in global ttylist */
X  extern	struct ttychars ttydefaults;
X  
X  /* Symbolic sleep message strings. */
X***************
X*** 238,243 ****
X--- 246,254 ----
X  int	 ttywait __P((struct tty *tp));
X  int	 ttywflush __P((struct tty *tp));
X  
X+ void	tty_init __P((void));
X+ void	tty_attach __P((struct tty *));
X+ void	tty_detach __P((struct tty *));
X  struct tty *ttymalloc __P((void));
X  void	 ttyfree __P((struct tty *));
X  u_char	*firstc           __P((struct clist *clp, int *c));
XIndex: src/sys/kern/tty.c
X===================================================================
XRCS file: /local/cvs/src/sys/kern/tty.c,v
Xretrieving revision 1.16
Xdiff -c -r1.16 tty.c
X*** tty.c	1996/03/29 14:08:39	1.16
X***************
X*** 154,159 ****
X--- 154,162 ----
X  #define	CLR(t, f)	(t) &= ~((unsigned)(f))
X  #define	ISSET(t, f)	((t) & (f))
X  
X+ struct ttylist_head ttylist;	/* TAILQ_HEAD */
X+ int tty_count;
X+ 
X  /*
X   * Initial open of tty, or (re)entry to standard tty line discipline.
X   */
X***************
X*** 2025,2030 ****
X--- 2028,2069 ----
X  }
X  
X  /*
X+  * Initialise the global tty list.
X+  */
X+ void
X+ tty_init()
X+ {
X+ 	TAILQ_INIT(&ttylist);
X+ 	tty_count = 0;
X+ }
X+ 
X+ /*
X+  * Attach a tty to the tty list.
X+  */
X+ void
X+ tty_attach(tp)
X+ 	struct tty *tp;
X+ {
X+ 	TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
X+ 	++tty_count;
X+ }
X+ 
X+ /*
X+  * Remove a tty from the tty list.
X+  */
X+ void
X+ tty_detach(tp)
X+ 	struct tty *tp;
X+ {
X+ 	TAILQ_REMOVE(&ttylist, tp, tty_link);
X+ 	--tty_count;
X+ #ifdef DIAGNOSTIC
X+ 	if (tty_count < 0)
X+ 		panic("tty_detach: tty_count < 0");
X+ #endif
X+ }
X+ 
X+ /*
X   * Allocate a tty structure and its associated buffers.
X   */
X  struct tty *
X***************
X*** 2052,2056 ****
X--- 2091,2096 ----
X  	clfree(&tp->t_rawq);
X  	clfree(&tp->t_canq);
X  	clfree(&tp->t_outq);
X+ 	tty_detach(tp);
X  	FREE(tp, M_TTYS);
X  }
XIndex: src/sys/kern/tty_pty.c
X===================================================================
XRCS file: /local/cvs/src/sys/kern/tty_pty.c,v
Xretrieving revision 1.1.1.6
Xdiff -c -r1.1.1.6 tty_pty.c
X*** tty_pty.c	1996/05/04 08:53:15	1.1.1.6
X***************
X*** 119,126 ****
X  	if (minor(dev) >= npty)
X  		return (ENXIO);
X  	pti = &pt_softc[minor(dev)];
X! 	if (!pti->pt_tty)
X  		tp = pti->pt_tty = ttymalloc();
X  	else
X  		tp = pti->pt_tty;
X  	if ((tp->t_state & TS_ISOPEN) == 0) {
X--- 119,128 ----
X  	if (minor(dev) >= npty)
X  		return (ENXIO);
X  	pti = &pt_softc[minor(dev)];
X! 	if (!pti->pt_tty) {
X  		tp = pti->pt_tty = ttymalloc();
X+ 		tty_attach(tp);
X+ 	}
X  	else
X  		tp = pti->pt_tty;
X  	if ((tp->t_state & TS_ISOPEN) == 0) {
X***************
X*** 311,318 ****
X  	if (minor(dev) >= npty)
X  		return (ENXIO);
X  	pti = &pt_softc[minor(dev)];
X! 	if (!pti->pt_tty)
X  		tp = pti->pt_tty = ttymalloc();
X  	else
X  		tp = pti->pt_tty;
X  	if (tp->t_oproc)
X--- 313,322 ----
X  	if (minor(dev) >= npty)
X  		return (ENXIO);
X  	pti = &pt_softc[minor(dev)];
X! 	if (!pti->pt_tty) {
X  		tp = pti->pt_tty = ttymalloc();
X+ 		tty_attach(tp);
X+ 	}
X  	else
X  		tp = pti->pt_tty;
X  	if (tp->t_oproc)
XIndex: src/sys/arch/sparc/dev/zs.c
X===================================================================
XRCS file: /local/cvs/src/sys/arch/sparc/dev/zs.c,v
Xretrieving revision 1.8
Xdiff -c -r1.8 zs.c
X*** zs.c	1996/05/05 14:54:08	1.8
X***************
X*** 325,332 ****
X  		kbd_serial(tp, zsiopen, zsiclose);
X  		cs->cs_conk = 1;		/* do L1-A processing */
X  		ringsize = 128;
X! 	} else
X  		ringsize = 4096;
X  
X  	cs->cs_ringmask = ringsize - 1;
X  	cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
X--- 325,335 ----
X  		kbd_serial(tp, zsiopen, zsiclose);
X  		cs->cs_conk = 1;		/* do L1-A processing */
X  		ringsize = 128;
X! 	} else {
X! 		if (tp != ctp)
X! 			tty_attach(tp);
X  		ringsize = 4096;
X+ 	}
X  
X  	cs->cs_ringmask = ringsize - 1;
X  	cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
X***************
X*** 357,364 ****
X  		tp->t_cflag = CS8;
X  		ms_serial(tp, zsiopen, zsiclose);
X  		ringsize = 128;
X! 	} else
X  		ringsize = 4096;
X  	cs->cs_ringmask = ringsize - 1;
X  	cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
X  			      M_DEVBUF, M_NOWAIT);
X--- 360,370 ----
X  		tp->t_cflag = CS8;
X  		ms_serial(tp, zsiopen, zsiclose);
X  		ringsize = 128;
X! 	} else {
X! 		if (tp != ctp)
X! 			tty_attach(tp);
X  		ringsize = 4096;
X+ 	}
X  	cs->cs_ringmask = ringsize - 1;
X  	cs->cs_rbuf = malloc((u_long)ringsize * sizeof(*cs->cs_rbuf),
X  			      M_DEVBUF, M_NOWAIT);
XIndex: src/sys/arch/sparc/dev/cons.c
X===================================================================
XRCS file: /local/cvs/src/sys/arch/sparc/dev/cons.c,v
Xretrieving revision 1.8
Xdiff -c -r1.8 cons.c
X*** cons.c	1996/05/20 14:12:54	1.8
X***************
X*** 284,289 ****
X--- 284,290 ----
X  		clalloc(&tp->t_canq, 1024, 1);
X  		/* output queue doesn't need quoting */
X  		clalloc(&tp->t_outq, 1024, 0);
X+ 		tty_attach(tp);
X  		/*
X  		 * get the console struct winsize.
X  		 */
END-of-pstat-t-sys.diff
echo x - pstat.c.diff
sed 's/^X//' >pstat.c.diff << 'END-of-pstat.c.diff'
XIndex: src/usr.sbin/pstat/pstat.c
X===================================================================
XRCS file: /a/cvsroot/src/usr.sbin/pstat/pstat.c,v
Xretrieving revision 1.19
Xdiff -c -r1.19 pstat.c
X*** pstat.c	1996/05/02 00:13:19	1.19
X***************
X*** 101,176 ****
X  	{"_nfiles"},
X  #define FNL_MAXFILE	9
X  	{"_maxfiles"},
X! #define NLMANDATORY FNL_MAXFILE	/* names up to here are mandatory */
X  #define VM_NISWAP	NLMANDATORY + 1
X  	{ "_niswap" },
X  #define VM_NISWDEV	NLMANDATORY + 2
X  	{ "_niswdev" },
X- #define	SCONS		NLMANDATORY + 3
X- 	{ "_constty" },
X- #define	SPTY		NLMANDATORY + 4
X- 	{ "_pt_tty" },
X- #define	SNPTY		NLMANDATORY + 5
X- 	{ "_npty" },
X- 
X- #ifdef sparc
X- #define SZS	(SNPTY+1)
X- 	{ "_zs_tty" },
X- #define SCZS	(SNPTY+2)
X- 	{ "_zscd" },
X- #endif
X- 
X- #ifdef hp300
X- #define	SDCA	(SNPTY+1)
X- 	{ "_dca_tty" },
X- #define	SNDCA	(SNPTY+2)
X- 	{ "_ndca" },
X- #define	SDCM	(SNPTY+3)
X- 	{ "_dcm_tty" },
X- #define	SNDCM	(SNPTY+4)
X- 	{ "_ndcm" },
X- #define	SDCL	(SNPTY+5)
X- 	{ "_dcl_tty" },
X- #define	SNDCL	(SNPTY+6)
X- 	{ "_ndcl" },
X- #define	SITE	(SNPTY+7)
X- 	{ "_ite_tty" },
X- #define	SNITE	(SNPTY+8)
X- 	{ "_nite" },
X- #endif
X- 
X- #ifdef mips
X- #define SDC	(SNPTY+1)
X- 	{ "_dc_tty" },
X- #define SNDC	(SNPTY+2)
X- 	{ "_dc_cnt" },
X- #endif
X- 
X- #ifdef i386
X- #define SPC	(SNPTY+1)
X- 	{ "_pc_tty" },
X- #define SCPC	(SNPTY+2)
X- 	{ "_pccd" },
X- #define SCOM	(SNPTY+3)
X- 	{ "_com_tty" },
X- #define SCCOM	(SNPTY+4)
X- 	{ "_comcd" },
X- #endif
X- #ifdef amiga
X- #define SSER	(SNPTY + 1)
X- 	{ "_ser_tty" },
X- #define SCSER	(SNPTY + 2)
X- 	{ "_sercd" },
X- #define SITE	(SNPTY + 3)
X- 	{ "_ite_tty" },
X- #define SCITE	(SNPTY + 4)
X- 	{ "_itecd" },
X- #define SMFCS	(SNPTY + 5)
X- 	{ "_mfcs_tty" },
X- #define SCMFCS	(SNPTY + 6)
X- 	{ "_mfcscd" },
X- #endif
X- 
X  	{ "" }
X  };
X  
X--- 101,115 ----
X  	{"_nfiles"},
X  #define FNL_MAXFILE	9
X  	{"_maxfiles"},
X! #define TTY_NTTY	10
X! 	{"_tty_count"},
X! #define TTY_TTYLIST	11
X! 	{"_ttylist"},
X! #define NLMANDATORY TTY_TTYLIST	/* names up to here are mandatory */
X  #define VM_NISWAP	NLMANDATORY + 1
X  	{ "_niswap" },
X  #define VM_NISWDEV	NLMANDATORY + 2
X  	{ "_niswdev" },
X  	{ "" }
X  };
X  
X***************
X*** 208,217 ****
X  int	nfs_print __P((struct vnode *));
X  void	swapmode __P((void));
X  void	ttymode __P((void));
X! void	ttyprt __P((struct tty *, int));
X! void	ttytype __P((char *, int, int));
X! void	ttytype_newcf __P((char *, int, int));
X! void	ttytype_oldcf __P((char *, int, int));
X  void	ufs_header __P((void));
X  int	ufs_print __P((struct vnode *));
X  void	usage __P((void));
X--- 147,153 ----
X  int	nfs_print __P((struct vnode *));
X  void	swapmode __P((void));
X  void	ttymode __P((void));
X! void	ttyprt __P((struct tty *));
X  void	ufs_header __P((void));
X  int	ufs_print __P((struct vnode *));
X  void	usage __P((void));
X***************
X*** 737,844 ****
X  void
X  ttymode()
X  {
X! 
X! #ifdef sparc
X! 	ttytype("console", SCONS, 1);
X! 	ttytype_newcf("zs", SZS, SCZS);
X! #endif
X! 
X! #ifdef vax
X! 	/* May fill in this later */
X! #endif
X! #ifdef tahoe
X! 	if (nl[SNVX].n_type != 0)
X! 		ttytype_oldcf("vx", SVX, SNVX);
X! 	if (nl[SNMP].n_type != 0)
X! 		ttytype_oldcf("mp", SMP, SNMP);
X! #endif
X! #ifdef hp300
X! 	if (nl[SNITE].n_type != 0)
X! 		ttytype_oldcf("ite", SITE, SNITE);
X! 	if (nl[SNDCA].n_type != 0)
X! 		ttytype_oldcf("dca", SDCA, SNDCA);
X! 	if (nl[SNDCM].n_type != 0)
X! 		ttytype_oldcf("dcm", SDCM, SNDCM);
X! 	if (nl[SNDCL].n_type != 0)
X! 		ttytype_oldcf("dcl", SDCL, SNDCL);
X! #endif
X! #ifdef mips
X! 	if (nl[SNDC].n_type != 0)
X! 		ttytype_oldcf("dc", SDC, SNDC);
X! #endif
X! #ifdef i386
X! 	if (nl[SCPC].n_type != 0)
X! 		ttytype_newcf("pc", SPC, SCPC);
X! 	if (nl[SCCOM].n_type != 0)
X! 		ttytype_newcf("com", SCOM, SCCOM);
X! #endif
X! #ifdef amiga
X! 	if (nl[SCSER].n_type != 0)
X! 		ttytype_newcf("ser", SSER, SCSER);
X! 	if (nl[SCITE].n_type != 0)
X! 		ttytype_newcf("ite", SITE, SCITE);
X! 	if (nl[SCMFCS].n_type != 0)
X! 		ttytype_newcf("mfcs", SMFCS, SCMFCS);
X! #endif
X! 	if (nl[SNPTY].n_type != 0)
X! 		ttytype_oldcf("pty", SPTY, SNPTY);
X! }
X! 
X! void
X! ttytype_oldcf(name, type, number)
X! 	char *name;
X! 	int type, number;
X! {
X! 	int ntty;
X! 
X! 	KGET(number, ntty);
X! 	ttytype(name, type, ntty);
X! }
X! 
X! void
X! ttytype_newcf(name, type, config)
X! 	char *name;
X! 	int type, config;
X! {
X! 	struct cfdriver cf;
X! 	void **cd;
X! 	int i;
X! 
X! 	KGET(config, cf);
X! 	cd = malloc(cf.cd_ndevs * sizeof(void *));
X! 	if (!cd)
X! 		return;
X! 	KGET2(cf.cd_devs, cd, cf.cd_ndevs * sizeof(void *), "cfdevicep");
X! 	for (i = cf.cd_ndevs - 1; i >= 0; --i)
X! 		if (cd[i])
X! 			break;
X! 	free(cd);
X! 	ttytype(name, type, i + 1);
X! }
X! 
X! void
X! ttytype(name, type, number)
X! 	char *name;
X! 	int type, number;
X! {
X! 	static struct tty **ttyp;
X! 	static int nttyp;
X! 	static struct tty tty;
X! 	int ntty = number, i;
X! 
X! 	(void)printf("%d %s %s\n", ntty, name, (ntty == 1) ? "line" : "lines");
X! 	if (ntty > nttyp) {
X! 		nttyp = ntty;
X! 		if ((ttyp = realloc(ttyp, nttyp * sizeof(*ttyp))) == 0)
X! 			err(1, NULL);
X! 	}
X! 	KGET1(type, ttyp, nttyp * sizeof(*ttyp), "tty pointers");
X! 	(void)printf(hdr);
X! 	for (i = 0; i < ntty; i++) {
X! 		if (ttyp[i] == NULL)
X! 			continue;
X! 		KGET2(ttyp[i], &tty, sizeof(struct tty), "tty struct");
X! 		ttyprt(&tty, i);
X  	}
X  }
X  
X--- 673,690 ----
X  void
X  ttymode()
X  {
X! 	int ntty, i;
X! 	struct ttylist_head tty_head;
X! 	struct tty *tp, tty;
X! 
X! 	KGET(TTY_NTTY, ntty);
X! 	(void)printf("%d terminal device%s\n", ntty, ntty == 1 ? "" : "s");
X! 	KGET(TTY_TTYLIST, tty_head);
X! 	for (tp = tty_head.tqh_first; tp; tp = tty.tty_link.tqe_next) {
X! 		if (tp == NULL)
X! 			return;
X! 		KGET2(tp, &tty, sizeof tty, "tty struct");
X! 		ttyprt(&tty);
X  	}
X  }
X  
X***************
X*** 866,882 ****
X  };
X  
X  void
X! ttyprt(tp, line)
X  	register struct tty *tp;
X- 	int line;
X  {
X  	register int i, j;
X  	pid_t pgid;
X  	char *name, state[20];
X  
X! 	if (usenumflag || tp->t_dev == 0 ||
X! 	   (name = devname(tp->t_dev, S_IFCHR)) == NULL)
X! 		(void)printf("%7d ", line); 
X  	else
X  		(void)printf("%-7s ", name);
X  	(void)printf("%3d %4d ", tp->t_rawq.c_cc, tp->t_canq.c_cc);
X--- 712,726 ----
X  };
X  
X  void
X! ttyprt(tp)
X  	register struct tty *tp;
X  {
X  	register int i, j;
X  	pid_t pgid;
X  	char *name, state[20];
X  
X! 	if (usenumflag || (name = devname(tp->t_dev, S_IFCHR)) == NULL)
X! 		(void)printf("0x%3x:%1x ", major(tp->t_dev), minor(tp->t_dev)); 
X  	else
X  		(void)printf("%-7s ", name);
X  	(void)printf("%3d %4d ", tp->t_rawq.c_cc, tp->t_canq.c_cc);
END-of-pstat.c.diff
exit