[net.sources] Twenex-Like ^T for 4.1BSD

chris@umcp-cs.UUCP (Chris Torek) (06/19/85)

[There are also 4.2BSD Vax and 4.2-Pyramid changes, under separate
cover.]

The following is a set of changes to 4.1BSD to add a twenex-like
control-T ``usestat'' character.  Most of the code was written by
Rehmi Post (who also made up the diff listings).  The following
note (by me, Chris Torek) certainly applies to the Vax 4.2 code,
and probably to the other changes as well.

We originally turned this on via ``options USESTAT'' in the kernel
config files.  This is actually a bad idea, because then ``pstat
-t'' breaks.  I'd suggest that you put a

	#define USESTAT

in ioctl.h right before the first #ifdef USESTAT, instead.  However,
I will also note that since we haven't got things set up that way
right now, I don't know if that really works right.

Without further ado, the 4.1BSD changes:
--------

The mods are to ttynew.c. The first goes in the function
ntinput... (Some context is given)
**********************************


		} else if (c==tlun.t_suspc || c==tun.t_intrc ||
			   c==tun.t_quitc) {
		...
#ifdef _USESTAT
		} else if (c==tax.t_usest) {	/* KtE 18 Apr 83 */
			ntystatout(tp);
			goto out;
#endif _USESTAT
	/* check for buffer editing functions - cooked mode */
		} else if ((t_flags&CBREAK) == 0) {


********************************
And later on... or at the end...
********************************

#ifdef _USESTAT
/*
 * print out primitive system stats (for now) rehmi 18 Apr 83
 * Last modification rehmi & chris 10 Jun 83
 * Added clearer stats and a few other fixes rehmi 2 Jul 83
 * Shortened message and kludged tty wait check rehmi 16 Nov 83
 * Fixed problem with "k of" in previous version. chris 19 Nov 83
 * Fixed problem with zombie memory measurements. james 20 Nov 83
 * Added priorities on states, 1 second timeouts. rehmi@maryland 30 Apr 84
 */

/* States of process. */

char *states[] = {
	"losing", "waiting", "swapped", "running",
	"idling", "zombied", "stopped", "kbd wait"
};

/* which states are most important to know (least best) */
char st_pri[] = {
	7, 3, 4, 1,
	2, 6, 5, 0
};

ntystatout(tp)
register struct tty *tp;
{
	register struct proc *p;
	register int x, f = 0, cf = 0;
	int size = 0, rss = 0, ptime = 0, state = 0, pflg = 0;
	float pcpu = 0.0;
	static double magic = 4294967296.0;
	extern double avenrun[];
	struct proc *this;
	char *s;
	int ntystatgo();

	/*
	 * Macro to use &s[l] if nothing else has been printed
	 */
#define comma(s,l)	(s + (cf++ ? 0 : l))

	/*
	 * Should we break to next line?
	 */
#define newp		if (tp->t_col > 64) {ntyoutput('\n', tp); cf=0;} else

	/*
	 * If waiting on hoggage, discard
	 * If timing out, discard
	 */
	if (tp->t_state & ASLEEP || tp->t_mflags & Ust_Timing)
		return;

	/* 
	 * set up the timeout
	 */
	tp->t_mflags |= Ust_Timing;
	timeout(ntystatgo, tp, hz);	/* wait a second before ^T works */
	
	/*
	 * Print uptime
	 */
	if (tax.t_usemap&Ust_uptime) {
		x = (int) (time - bootime);
		if (x < 0)
			x = 0;
		ntyout("up ", tp);
		if (x/86400 > 0) {		/* days */
			ntyoutint(x/86400, 10, 1, tp);
			ntyout("d ", tp);
			x %= 86400;
		}
		if (x/3600 > 0) {		/* hours */
			ntyoutint(x/3600, 10, 1, tp);
			ntyout("h ", tp);
			x %= 3600;
		}
		ntyoutint(x/60, 10, 2, tp);	/* minutes */
		ntyout("m", tp);
		cf++;
	}
	newp;

#define	ntyoutfloat(f)	(ntyoutint((f)/100, 10, 1, tp),	\
			 ntyoutput('.', tp),		\
			 ntyoutint((f)%100, 10, 2, tp))

	/*
	 * Print load average
	 */
	if (tax.t_usemap&(Ust_load1|Ust_load5|Ust_load15)) {
		ntyout(comma(", load", 2), tp);
		if (tax.t_usemap&Ust_load1) {
			ntyoutput(' ', tp);
			x = avenrun[0]*100.0 + 0.5;
			if (x < 0)
				x = 0;
			ntyoutfloat(x);
		}
		if (tax.t_usemap&Ust_load5) {
			ntyoutput(' ', tp);
			x = avenrun[1]*100.0 + 0.5;
			if (x < 0)
				x = 0;
			ntyoutfloat(x);
		}
		if (tax.t_usemap&Ust_load15) {
			ntyoutput(' ', tp);
			x = avenrun[2]*100.0 + 0.5;
			if (x < 0)
				x = 0;
			ntyoutfloat(x);
		}
		newp;
	}

	for (p = proc; p < procNPROC; p++) {
		if (p->p_pgrp == tp->t_pgrp) {
			if (tp->t_pgrp == p->p_pid)
				this = p;
			if (st_pri[p->p_stat] < st_pri[state])
				state = p->p_stat;
			if(p->p_stat==SSLEEP &&
			   p->p_wchan==(caddr_t)&tp->t_rawq)
				state=7;
			if (p->p_stat != SZOMB) {
				pcpu  = pcpu + (float)p->p_pctcpu;
				size += p->p_tsize + p->p_ssize + p->p_dsize;
				rss  += p->p_rssize;
				pflg |= p->p_flag;
				ptime += p->p_time;
			}
			f++;
		}
	}
	if (f) {
		/*
		 * Print pid, %cpu, size, rss
		 */
		if (tax.t_usemap&Ust_pgrp) {
			ntyout(comma(", pid ", 2), tp);
			ntyoutint(tp->t_pgrp, 10, 1, tp);
		}
		newp;
		if (tax.t_usemap&Ust_childs) {
			ntyout(comma(" children ", 1), tp);
			ntyoutint(f, 10, 1, tp);
		}
		newp;
		if (tax.t_usemap&Ust_pcpu) {
			ntyout(comma(", %cpu ", 2), tp);
			if (tax.t_usemap&Ust_rawcpu)
				x = pcpu*10000.0 + 0.5;
			else
				x =	10000.0*pcpu  /
				(1.0 - ( (1<<(ptime>>2)) / magic) );
			/* sick!!!!!!!!!!!!! */
			ntyoutfloat(x);
		}
		newp;
    		if (tax.t_usemap&Ust_incore) {
    			ntyout(comma(", ", 2), tp);
			ntyoutint(rss>>1, 10, 1, tp);
			ntyout("k of ", tp);
			ntyoutint(size>>1, 10, 1, tp);
			ntyoutput('k', tp);
		}
		newp;
		if (tax.t_usemap&Ust_flags) {
			ntyout(comma(", flags ", 2), tp);
			ntyoutint(pflg, 16, 1, tp);
		}
		newp;
		if (tax.t_usemap&Ust_state) {
			ntyout(comma(", ", 2), tp);
			ntyout(states[state], tp);
			cf++;
		}
		if (cf)
			ntyoutput('\n', tp);
	}
	else
		ntyout(comma("; no process\n", 2), tp);

	/*
	 * Reset "t_rocount" so pending input will
	 * be retyped if backspacing follows.
	 */

	tp->t_rocount = 0;
}

ntystatgo(tp)
register struct tty *tp;
{
	tp->t_mflags &= ~Ust_Timing;
}

ntyoutint(n, base, min, tp)
register int n, base, min;
register struct tty *tp;
{
	char info[16];
	register char *p = info;

	while (--min >= 0 || n) {
		*p++ = "0123456789abcdef"[n%base];
		n /= base;
	}
	while (p > info)
		ntyoutput(*--p, tp);
}
#endif _USESTAT

************************************************************
Perhaps I should be honest... there are also mods to ioctl.h
************************************************************


#ifdef _USESTAT
struct tauxil {
	char	t_usest;	/* print out user stats */
	short	t_usemap;	/* bitmap for which stats */
};
#endif _USESTAT

/* 
 * ^T (usestat) bits to select options KtE 10 Jun 83
 */
#ifdef _USESTAT
#define Ust_load1	0x0001	/* one-minute load average */
#define Ust_load5	0x0002	/* five-minute load average */
#define Ust_load15	0x0004	/* fifteen-minute load average */
#define Ust_uptime	0x0008	/* time since last boot */
#define Ust_pgrp	0x0010	/* pgroup leader */
#define Ust_childs	0x0020	/* and N children */
#define Ust_pcpu	0x0040	/* %cpu they're getting */
#define Ust_incore	0x0080	/* size and rss of them */
#define Ust_flags	0x0100	/* OR of all their flags */
#define Ust_state	0x0200	/* rough state (in i/o wait, etc) */
#define Ust_rawcpu	0x0400	/* raw or cooked cpu %'age */
#endif _USESTAT

#define TIOCSAUXC	(('t'<<8)|59)	/* set aux char structure KtE */
#define TIOCGAUXC	(('t'<<8)|58)	/* get aux char structure KtE */


**************
Also, tty.h...
**************


struct tty
{
	union {
		struct {
			struct	clist T_rawq;
			struct	clist T_canq;
		} t_t;
#define	t_rawq	t_nu.t_t.T_rawq		/* raw characters or partial line */
#define	t_canq	t_nu.t_t.T_canq		/* complete input lines */
		struct {
			struct	buf *T_bufp;
			char	*T_cp;
			int	T_inbuf;
			int	T_rec;
		} t_n;
#define	t_bufp	t_nu.t_n.T_bufp		/* buffer allocated to protocol */
#define	t_cp	t_nu.t_n.T_cp		/* pointer into the ripped off buffer */
#define	t_inbuf	t_nu.t_n.T_inbuf	/* number chars in the buffer */
#define	t_rec	t_nu.t_n.T_rec		/* have a complete record */
	} t_nu;
	struct	clist t_outq;	/* output list to device */
	int	(*t_oproc)();	/* routine to start output */
	int	(*t_iproc)();	/* routine to start input */
	struct chan *t_chan;	/* destination channel */
	caddr_t	t_linep;	/* aux line discipline pointer */
	caddr_t	t_addr;		/* device address */
	dev_t	t_dev;		/* device number */
	short	t_flags;	/* mode, settable by ioctl call */
	short	t_state;	/* internal state, not visible externally */
	short	t_pgrp;		/* process group name */
	char	t_delct;	/* number of delimiters in raw q */
	char	t_line;		/* line discipline */
	char	t_col;		/* printing column of device */
	char	t_erase;	/* erase character */
	char	t_kill;		/* kill character */
	char	t_char;		/* character temporary */
	char	t_ispeed;	/* input speed */
	char	t_ospeed;	/* output speed */
/* begin local */
	char	t_rocount;	/* chars input since a ttwrite() */
	char	t_rocol;	/* t_col when first input this line */
	struct	ltchars t_lchr;	/* local special CHARACTERS */
	short	t_local;	/* local mode word */
	short	t_lstate;	/* local state bits */
/* end local */
	union {
		struct {
			struct tchars t_ch;
#ifdef _USESTAT
			struct tauxil t_ax;
#endif _USESTAT
		} t_big;
		struct clist t_ctlq;
	} t_un;
};
#define t_chr	t_big.t_ch
#define t_aux	t_big.t_ax
#define	tun	tp->t_un.t_chr
#define tax	tp->t_un.t_aux
#define	tlun	tp->t_lchr


***************
An' tty.c
***************


ttychars(tp)
register struct tty *tp;
{

	tun.t_intrc = CINTR;
	tun.t_quitc = CQUIT;
	tun.t_startc = CSTART;
	tun.t_stopc = CSTOP;
	tun.t_eofc = CEOT;
	tun.t_brkc = CBRK;
	tp->t_erase = CERASE;
	tp->t_kill = CKILL;
/* begin local */
	tlun.t_suspc = CTRL(z);
	tlun.t_dsuspc = CTRL(y);
	tlun.t_rprntc = CTRL(r);
	tlun.t_flushc = CTRL(o);
	tlun.t_werasc = CTRL(w);
	tlun.t_lnextc = CTRL(v);
	tp->t_local = 0;
	tp->t_lstate = 0;
/* end local */
#ifdef _USESTAT
/* begin UoM local */
	tax.t_usest = CTRL(t);
	tax.t_usemap = ~(Ust_uptime|Ust_flags|Ust_childs);
/* end UoM local */
#endif _USESTAT
}


/*
 * Common code for tty ioctls.
 */
/*ARGSUSED*/
ttioctl(tp, com, addr, flag)
register struct tty *tp;
caddr_t addr;
{
	int dev;
	unsigned t;
	struct sgttyb iocb;
	struct clist tq;
	extern int nldisp;
	register c;
	int temp;

	/*
	 * This is especially so that isatty() will
	 * fail when carrier is gone.
	 */
	if ((tp->t_state&CARR_ON) == 0) {
		u.u_error = EBADF;
		return (1);
	}

	dev = tp->t_dev;
	/*
	 * If the ioctl involves modification,
	 * insist on being able to write the device,
	 * and hang if in the background.
	 */
	switch(com) {

	case TIOCSETD:
	case TIOCSETP:
	case TIOCSETN:
	case TIOCFLUSH:
	case TIOCSETC:
	case TIOCSLTC:
	case TIOCSPGRP:
	case TIOCLBIS:
	case TIOCLBIC:
	case TIOCLSET:
	case TIOCSTI:
#ifdef _USESTAT
	case TIOCSAUXC:
#endif _USESTAT
/* this is reasonable, but impractical... 
		if ((flag & FWRITE) == 0) {
			u.u_error = EBADF;
			return (1);
		}
 */
		while (tp->t_line == NTTYDISC &&
		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
		   (u.u_procp->p_flag&SVFORK) == 0 &&
		   u.u_signal[SIGTTOU] != SIG_IGN &&
		   u.u_signal[SIGTTOU] != SIG_HOLD &&
		   (u.u_procp->p_flag&SDETACH)==0) {
			gsignal(u.u_procp->p_pgrp, SIGTTOU);
			sleep((caddr_t)&lbolt, TTOPRI);
		}
		break;
	}

	/*
	 * Process the ioctl.
	 */
	switch(com) {

	/*
	 * Get discipline number
	 */
	case TIOCGETD:
		t = tp->t_line;
		if (copyout((caddr_t)&t, addr, sizeof(t)))
			u.u_error = EFAULT;
		break;

	/*
	 * Set line discipline
	 */
	case TIOCSETD:
		if (copyin(addr, (caddr_t)&t, sizeof(t))) {
			u.u_error = EFAULT;
			break;
		}
		if (t >= nldisp) {
			u.u_error = ENXIO;
			break;
		}
		(void) spl5();
		if (tp->t_line)
			(*linesw[tp->t_line].l_close)(tp);
		if (t)
			(*linesw[t].l_open)(dev, tp, addr);
		if (u.u_error==0)
			tp->t_line = t;
		(void) spl0();
		break;

	/*
	 * Prevent more opens on channel
	 */
	case TIOCEXCL:
		tp->t_state |= XCLUDE;
		break;

	case TIOCNXCL:
		tp->t_state &= ~XCLUDE;
		break;

	/*
	 * Set new parameters
	 */
	case TIOCSETP:
	case TIOCSETN:
		if (copyin(addr, (caddr_t)&iocb, sizeof(iocb))) {
			u.u_error = EFAULT;
			return(1);
		}
		(void) spl5();
		if (tp->t_line == 0) {
			if (com == TIOCSETP)
				wflushtty(tp);
			while (canon(tp)>=0) 
				;
#ifdef notdef
			wakeup((caddr_t)&tp->t_rawq);
#endif
		} else if (tp->t_line == NTTYDISC) {
			if (tp->t_flags&RAW || iocb.sg_flags&RAW ||
			    com == TIOCSETP)
				wflushtty(tp);
			else if ((tp->t_flags&CBREAK) != (iocb.sg_flags&CBREAK)) {
				if (iocb.sg_flags & CBREAK) {
					catq(&tp->t_rawq, &tp->t_canq);
					tq = tp->t_rawq;
					tp->t_rawq = tp->t_canq;
					tp->t_canq = tq;
				} else {
					tp->t_local |= LPENDIN;
					if (tp->t_canq.c_cc)
						panic("ioccom canq");
#ifdef notdef
					if (tp->t_chan)
						(void) sdata(tp->t_chan);
					else
#endif
						wakeup((caddr_t)&tp->t_rawq);
				}
			}
		}
		if ((tp->t_state&SPEEDS)==0) {
			tp->t_ispeed = iocb.sg_ispeed;
			tp->t_ospeed = iocb.sg_ospeed;
		}
		tp->t_erase = iocb.sg_erase;
		tp->t_kill = iocb.sg_kill;
		tp->t_flags = iocb.sg_flags;
		if (tp->t_flags & RAW) {
			tp->t_state &= ~TTSTOP;
			ttstart(tp);
		}
		(void) spl0();
		break;

	/*
	 * Send current parameters to user
	 */
	case TIOCGETP:
		iocb.sg_ispeed = tp->t_ispeed;
		iocb.sg_ospeed = tp->t_ospeed;
		iocb.sg_erase = tp->t_erase;
		iocb.sg_kill = tp->t_kill;
		iocb.sg_flags = tp->t_flags;
		if (copyout((caddr_t)&iocb, addr, sizeof(iocb)))
			u.u_error = EFAULT;
		break;

	/*
	 * Hang up line on last close
	 */
	case TIOCHPCL:
		tp->t_state |= HUPCLS;
		break;

	case TIOCFLUSH: {
		int flags;
		if (addr == 0)
			flags = FREAD|FWRITE;
		else if (copyin(addr, (caddr_t)&flags, sizeof (flags))) {
			u.u_error = EFAULT;
			return(1);
		}
		flushtty(tp, flags);
		break;
	}

	/*
	 * Set and fetch special characters
	 */
	case TIOCSETC:
		if (copyin(addr, (caddr_t)&tun, sizeof(struct tchars)))
			u.u_error = EFAULT;
		break;

	case TIOCGETC:
		if (copyout((caddr_t)&tun, addr, sizeof(struct tchars)))
			u.u_error = EFAULT;
		break;

/* local ioctls */
	/*
	 * Set/get local special characters.
	 */
	case TIOCSLTC:
		if (copyin(addr, (caddr_t)&tlun, sizeof (struct ltchars)))
			u.u_error = EFAULT;
		break;

	case TIOCGLTC:
		if (copyout((caddr_t)&tlun, addr, sizeof (struct ltchars)))
			u.u_error = EFAULT;
		break;
#ifdef _USESTAT

	/*
	 * Set/get local aux chars.
	 */
	case TIOCSAUXC:
		if (copyin(addr, (caddr_t)&tax, sizeof (struct tauxil)))
			u.u_error = EFAULT;
		break;
	
	case TIOCGAUXC:
		if (copyout((caddr_t)&tax, addr, sizeof (struct tauxil)))
			u.u_error = EFAULT;
		break;
#endif _USESTAT
	
	/*
	 * Return number of characters immediately available.
	 */
	case FIONREAD: {
		off_t nread;

		switch (tp->t_line) {

		case NETLDISC:
			nread = tp->t_rec ? tp->t_inbuf : 0;
			break;

		case 0:
			(void) spl5();
			while (canon(tp)>=0)
				;
			(void) spl0();
			/* fall into ... */

		case NTTYDISC:
			if (tp->t_local & LPENDIN)
				ntypend(tp);
			nread = tp->t_canq.c_cc;
			if (tp->t_flags & (RAW|CBREAK))
				nread += tp->t_rawq.c_cc;
			break;

		}
		if (copyout((caddr_t)&nread, addr, sizeof (off_t)))
			u.u_error = EFAULT;
		break;
		}

	/*
	 * Should allow SPGRP and GPGRP only if tty open for reading.
	 */
	case TIOCSPGRP:
		if (copyin(addr, (caddr_t)&tp->t_pgrp, sizeof (tp->t_pgrp)))
			u.u_error = EFAULT;
		break;

	case TIOCGPGRP:
		if (copyout((caddr_t)&tp->t_pgrp, addr, sizeof(tp->t_pgrp)))
			u.u_error = EFAULT;
		break;

	/*
	 * Modify local mode word.
	 */
	case TIOCLBIS:
		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
			u.u_error = EFAULT;
		else
			tp->t_local |= temp;
		break;

	case TIOCLBIC:
		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
			u.u_error = EFAULT;
		else
			tp->t_local &= ~temp;
		break;

	case TIOCLSET:
		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
			u.u_error = EFAULT;
		else
			tp->t_local = temp;
		break;

	case TIOCLGET:
		if (copyout((caddr_t)&tp->t_local, addr, sizeof(tp->t_local)))
			u.u_error = EFAULT;
		break;

	/*
	 * Return number of characters in
	 * the output.
	 */
	case TIOCOUTQ:
		if (copyout((caddr_t)&tp->t_outq.c_cc, addr, sizeof(tp->t_outq.c_cc)))
			u.u_error = EFAULT;
		break;

	/*
	 * Simulate typing of a character at the terminal.
	 */
	case TIOCSTI:
		c = fubyte(addr);
		if (u.u_uid && u.u_ttyp != tp || c < 0)
			u.u_error = EFAULT;
		else
			(*linesw[tp->t_line].l_rint)(c, tp);
		break;
/* end of locals */

	default:
		return(0);
	}
	return(1);
}

********************************
And finally, some mods to stty.c
********************************
*** stty.c	Thu Dec  8 18:29:33 1983
--- stty.c.old	Fri Jun 10 21:09:00 1983
***************
*** 6,14
  #include <stdio.h>
  #include <sgtty.h>
  
- #define	pcol(x,y)	pcoln(x,y,7)
- #define	pco2(x,y)	pcoln(x,y,6)
- 
  struct
  {
  	char	*string;

--- 6,11 -----
  #include <stdio.h>
  #include <sgtty.h>
  
  struct
  {
  	char	*string;
***************
*** 31,39
  	"9600",	B9600,
  	"exta",	EXTA,
  	"extb",	EXTB,
! 	"19200", EXTA,
! 	"19.2k", EXTA,
! 	"19.2", EXTA,
  	0,
  };
  struct

--- 28,35 -----
  	"9600",	B9600,
  	"exta",	EXTA,
  	"extb",	EXTB,
! 	"19.2k",EXTA,
! 	"19200",EXTA,
  	0,
  };
  struct
***************
*** 124,171
  	0,
  };
  
- #ifdef	_USESTAT
- struct Ust_option {
- 	char	*uo_name;
- 	short	uo_set, uo_clear;
- } Ust_options[] = {
- 	"load1",	Ust_load1,	0,
- 	"-load1",	0,		Ust_load1,
- 	"load5",	Ust_load5,	0,
- 	"-load5",	0,		Ust_load5,
- 	"load15",	Ust_load15,	0,
- 	"-load15",	0,		Ust_load15,
- 	"load",		Ust_load1|Ust_load5|Ust_load15, 0,
- 	"-load",	0,		Ust_load1|Ust_load5|Ust_load15,
- 	"uptime",	Ust_uptime,	0,
- 	"-uptime",	0,		Ust_uptime,
- 	"pid",		Ust_pgrp,	0,
- 	"-pid",		0,		Ust_pgrp,
- 	"children",	Ust_childs,	0,
- 	"-children",	0,		Ust_childs,
- 	"cpu",		Ust_pcpu,	0,
- 	"-cpu",		0,		Ust_pcpu,
- 	"size",		Ust_incore,	0,
- 	"-size",	0,		Ust_incore,
- 	"flags",	Ust_flags,	0,
- 	"-flags",	0,		Ust_flags,
- 	"state",	Ust_state,	0,
- 	"-state",	0,		Ust_state,
- 	"rawcpu",	Ust_rawcpu,	0,
- 	"-rawcpu",	0,		Ust_rawcpu,
- 	"cookedcpu",	0,		Ust_rawcpu,
- 	"stdusest",	Ust_load1|Ust_load5|Ust_load15|Ust_pgrp|
- 			Ust_pcpu|Ust_incore|Ust_state|Ust_rawcpu,
- 					Ust_uptime|Ust_childs|Ust_flags,
- 	"-usest",	0,		0,
- 	"-stdusest",	Ust_load1|Ust_load15|Ust_uptime|
- 			Ust_pcpu|Ust_incore|Ust_state,
- 					Ust_childs|Ust_pgrp|Ust_flags|
- 					Ust_rawcpu|Ust_load5,
- 	0,		0,		0
- };
- #endif	_USESTAT
- 
  struct tchars tc;
  struct ltchars ltc;
  struct sgttyb mode;

--- 120,125 -----
  	0,
  };
  
  struct tchars tc;
  struct ltchars ltc;
  #ifdef Rehmi
***************
*** 168,173
  
  struct tchars tc;
  struct ltchars ltc;
  struct sgttyb mode;
  #ifdef	_USESTAT
  struct tauxil auxil;

--- 122,130 -----
  
  struct tchars tc;
  struct ltchars ltc;
+ #ifdef Rehmi
+ struct tauxil tx;
+ #endif Rehmi
  struct sgttyb mode;
  int	lmode;
  int	oldisc, ldisc;
***************
*** 169,177
  struct tchars tc;
  struct ltchars ltc;
  struct sgttyb mode;
- #ifdef	_USESTAT
- struct tauxil auxil;
- #endif	_USESTAT
  int	lmode;
  int	oldisc, ldisc;
  

--- 126,131 -----
  struct tauxil tx;
  #endif Rehmi
  struct sgttyb mode;
  int	lmode;
  int	oldisc, ldisc;
  
***************
*** 196,204
  	"flush",	&ltc.t_flushc,		CTRL(o),
  	"werase",	&ltc.t_werasc,		CTRL(w),
  	"lnext",	&ltc.t_lnextc,		CTRL(v),
! #ifdef	_USESTAT
! 	"usest",	&auxil.t_usest,		CTRL(t),
! #endif	_USESTAT
  	0
  };
  char	*arg;

--- 150,158 -----
  	"flush",	&ltc.t_flushc,		CTRL(o),
  	"werase",	&ltc.t_werasc,		CTRL(w),
  	"lnext",	&ltc.t_lnextc,		CTRL(v),
! #ifdef Rehmi
! 	"usest",	&tx.t_usest,		CTRL(t),
! #endif Rehmi
  	0
  };
  char	*arg;
***************
*** 208,214
  main(iargc, iargv)
  char	**iargv;
  {
! 	register int i;
  	register struct special *sp;
  	char obuf[BUFSIZ];
  

--- 162,168 -----
  main(iargc, iargv)
  char	**iargv;
  {
! 	int i;
  	register struct special *sp;
  	char obuf[BUFSIZ];
  
***************
*** 221,229
  	ioctl(1, TIOCGETC, &tc);
  	ioctl(1, TIOCLGET, &lmode);
  	ioctl(1, TIOCGLTC, &ltc);
! #ifdef	_USESTAT
! 	ioctl(1, TIOCGAUXC, &auxil);
! #endif	_USESTAT
  	if(argc == 1) {
  		prmodes(0);
  		exit(0);

--- 175,183 -----
  	ioctl(1, TIOCGETC, &tc);
  	ioctl(1, TIOCLGET, &lmode);
  	ioctl(1, TIOCGLTC, &ltc);
! #ifdef Rehmi
! 	ioctl(1, TIOCGAUXC, &tx);
! #endif Rehmi
  	if(argc == 1) {
  		prmodes(0);
  		exit(0);
***************
*** 302,308
  					    0177 : (*argv)[1] & 037;
  				else
  					*sp->cp = **argv;
! 				continue;
  			}
  		if (eq("gspeed")) {
  			mode.sg_ispeed = B300;

--- 256,262 -----
  					    0177 : (*argv)[1] & 037;
  				else
  					*sp->cp = **argv;
! 				goto cont;
  			}
  		if (eq("gspeed")) {
  			mode.sg_ispeed = B300;
***************
*** 315,323
  		}
  		for(i=0; speeds[i].string; i++)
  			if(eq(speeds[i].string)) {
! 				mode.sg_ispeed =
! 				mode.sg_ospeed = speeds[i].speed;
! 				continue;
  			}
  		if (eq("speed")) {
  			gtty(open("/dev/tty", 0), &mode);

--- 269,276 -----
  		}
  		for(i=0; speeds[i].string; i++)
  			if(eq(speeds[i].string)) {
! 				mode.sg_ispeed = mode.sg_ospeed = speeds[i].speed;
! 				goto cont;
  			}
  		if (eq("speed")) {
  			gtty(open("/dev/tty", 0), &mode);
***************
*** 335,341
  				mode.sg_flags |= modes[i].set;
  				lmode &= ~modes[i].lreset;
  				lmode |= modes[i].lset;
- 				continue;
  			}
  #ifdef	_USESTAT
  		for(i=0; Ust_options[i].uo_name; i++)

--- 288,293 -----
  				mode.sg_flags |= modes[i].set;
  				lmode &= ~modes[i].lreset;
  				lmode |= modes[i].lset;
  			}
  		if(arg)
  			fprintf(stderr,"unknown mode: %s\n", arg);
***************
*** 337,350
  				lmode |= modes[i].lset;
  				continue;
  			}
- #ifdef	_USESTAT
- 		for(i=0; Ust_options[i].uo_name; i++)
- 			if(eq(Ust_options[i].uo_name)) {
- 				auxil.t_usemap |= Ust_options[i].uo_set;
- 				auxil.t_usemap &= ~Ust_options[i].uo_clear;
- 				continue;
- 			}
- #endif	_USESTAT
  		if(arg)
  			fprintf(stderr,"unknown mode: %s\n", arg);
  	}

--- 289,294 -----
  				lmode &= ~modes[i].lreset;
  				lmode |= modes[i].lset;
  			}
  		if(arg)
  			fprintf(stderr,"unknown mode: %s\n", arg);
  cont:
***************
*** 347,352
  #endif	_USESTAT
  		if(arg)
  			fprintf(stderr,"unknown mode: %s\n", arg);
  	}
  done:
  	ioctl(1, TIOCSETN, &mode);

--- 291,298 -----
  			}
  		if(arg)
  			fprintf(stderr,"unknown mode: %s\n", arg);
+ cont:
+ 		;
  	}
  done:
  	ioctl(1, TIOCSETN, &mode);
***************
*** 353,361
  	ioctl(1, TIOCSETC, &tc);
  	ioctl(1, TIOCSLTC, &ltc);
  	ioctl(1, TIOCLSET, &lmode);
! #ifdef	_USESTAT
! 	ioctl(1, TIOCSAUXC, &auxil);
! #endif	_USESTAT
  }
  
  eq(string)

--- 299,307 -----
  	ioctl(1, TIOCSETC, &tc);
  	ioctl(1, TIOCSLTC, &ltc);
  	ioctl(1, TIOCLSET, &lmode);
! #ifdef Rehmi
! 	ioctl(1, TIOCSAUXC, &tx);
! #endif Rehmi
  }
  
  eq(string)
***************
*** 359,365
  }
  
  eq(string)
! register char *string;
  {
  	register int i;
  

--- 305,311 -----
  }
  
  eq(string)
! char *string;
  {
  	int i;
  
***************
*** 361,367
  eq(string)
  register char *string;
  {
! 	register int i;
  
  	if(!arg)
  		return(0);

--- 307,313 -----
  eq(string)
  char *string;
  {
! 	int i;
  
  	if(!arg)
  		return(0);
***************
*** 465,471
  
  		case 0:
  			fprintf(stderr,"\
! erase  kill   intr   quit   stop   eof\
  \n");
  			pcol(mode.sg_erase, -1);
  			pcol(mode.sg_kill, -1);

--- 411,417 -----
  
  		case 0:
  			fprintf(stderr,"\
! erase kill  intr  quit  stop  eof\
  \n");
  			pcol(mode.sg_erase, -1);
  			pcol(mode.sg_kill, -1);
***************
*** 477,483
  			break;
  
  		case NTTYDISC:
- #ifdef	_USESTAT
  			fprintf(stderr,"\
  erase kill  weras rprnt flush lnext susp  intr  quit  stop  eof   usest\n");
  			pco2(mode.sg_erase, -1);

--- 423,428 -----
  			break;
  
  		case NTTYDISC:
  			fprintf(stderr,"\
  erase kill  weras rprnt flush lnext susp  intr  quit  stop  eof   usest\
  \n"); 
***************
*** 479,500
  		case NTTYDISC:
  #ifdef	_USESTAT
  			fprintf(stderr,"\
! erase kill  weras rprnt flush lnext susp  intr  quit  stop  eof   usest\n");
! 			pco2(mode.sg_erase, -1);
! 			pco2(mode.sg_kill, -1);
! 			pco2(ltc.t_werasc, -1);
! 			pco2(ltc.t_rprntc, -1);
! 			pco2(ltc.t_flushc, -1);
! 			pco2(ltc.t_lnextc, -1);
! 			pco2(ltc.t_suspc, ltc.t_dsuspc);
! 			pco2(tc.t_intrc, -1);
! 			pco2(tc.t_quitc, -1);
! 			pco2(tc.t_stopc, tc.t_startc);
! 			pco2(tc.t_eofc, tc.t_brkc);
! 			pco2(auxil.t_usest, -1);
! #else	_USESTAT
! 			fprintf(stderr,"\
! erase  kill   werase rprnt  flush  lnext  susp   intr   quit   stop   eof\n");
  			pcol(mode.sg_erase, -1);
  			pcol(mode.sg_kill, -1);
  			pcol(ltc.t_werasc, -1);

--- 424,431 -----
  
  		case NTTYDISC:
  			fprintf(stderr,"\
! erase kill  weras rprnt flush lnext susp  intr  quit  stop  eof   usest\
! \n"); 
  			pcol(mode.sg_erase, -1);
  			pcol(mode.sg_kill, -1);
  			pcol(ltc.t_werasc, -1);
***************
*** 506,512
  			pcol(tc.t_quitc, -1);
  			pcol(tc.t_stopc, tc.t_startc);
  			pcol(tc.t_eofc, tc.t_brkc);
! #endif	_USESTAT
  			fprintf(stderr,"\n");
  			break;
  		}

--- 437,445 -----
  			pcol(tc.t_quitc, -1);
  			pcol(tc.t_stopc, tc.t_startc);
  			pcol(tc.t_eofc, tc.t_brkc);
! #ifdef Rehmi
! 			pcol(tx.t_usest, -1);
! #endif Rehmi
  			fprintf(stderr,"\n");
  			break;
  		}
***************
*** 524,551
  		if (first == 0)
  			fprintf(stderr, "\n");
  	}
- #ifdef	_USESTAT
- #define	map(str,bit) fprintf(stderr, str + ((auxil.t_usemap&bit) != 0))
- #define	Ust_load3	(Ust_load1|Ust_load5|Ust_load15)
- 	if (all == 2 && ldisc == NTTYDISC) {
- 		if ((auxil.t_usemap&Ust_load3)==Ust_load3)
- 			fprintf (stderr, "load (load1 load5 load15) ");
- 		else {
- 			map("-load1 ", Ust_load1);
- 			map("-load5 ", Ust_load5);
- 			map("-load15 ", Ust_load15);
- 		}
- 		map("-uptime ", Ust_uptime);
- 		map("-pid ", Ust_pgrp);
- 		map("-children ", Ust_childs);
- 		map("-cpu ", Ust_pcpu);
- 		map("-size ", Ust_incore);
- 		map("-flags ", Ust_flags);
- 		map("-state ", Ust_state);
- 		map("-rawcpu ", Ust_rawcpu);
- 		putc ('\n', stderr);
- 	}
- #endif	_USESTAT
  }
  
  pcoln(ch1, ch2, n)

--- 457,462 -----
  		if (first == 0)
  			fprintf(stderr, "\n");
  	}
  }
  
  pcol(ch1, ch2)
***************
*** 548,555
  #endif	_USESTAT
  }
  
! pcoln(ch1, ch2, n)
! 	int ch1, ch2, n;
  {
  	int nout = 0;
  

--- 459,466 -----
  	}
  }
  
! pcol(ch1, ch2)
! 	int ch1, ch2;
  {
  	int nout = 0;
  
***************
*** 581,587
  			nout++;
  		}
  	}
! 	while (nout < n) {
  		fprintf(stderr, " ");
  		nout++;
  	}

--- 492,498 -----
  			nout++;
  		}
  	}
! 	while (nout < 6) {
  		fprintf(stderr, " ");
  		nout++;
  	}
*****************
That seems to be all...

					Enjoy!
					
					-Rehmi
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 4251)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@maryland