4.3BSD-UWisc/src/bin/ps/ps.diff

*** ps.c	Mon Sep 15 15:27:28 1986
--- /usr/staff/tadl/nfs/bin/ps.c	Sun May 18 18:35:13 1986
***************
*** 1,25 ****
--- 1,15 ----
  /*
!< * Copyright (c) 1980 Regents of the University of California.
!< * All rights reserved.  The Berkeley software License Agreement
!< * specifies the terms and conditions for redistribution.
   */
-<
-<#ifndef lint
-<char copyright[] =
-<"@(#) Copyright (c) 1980 Regents of the University of California.\n\
-< All rights reserved.\n";
-<#endif not lint
-<
-<#ifndef lint
-<static char sccsid[] = "@(#)ps.c	5.9 (Berkeley) 5/8/86";
-<#endif not lint
-<
  #include <stdio.h>
  #include <ctype.h>
!<#include <a.out.h>
  #include <pwd.h>
  #include <sys/param.h>
-<#include <sys/ioctl.h>
  #include <sys/tty.h>
  #include <sys/dir.h>
  #include <sys/user.h>
---------------
+>/* NFSSRC @(#)ps.c	2.2 86/05/14 */
+>#ifndef lint
+>static	char sccsid[] = "@(#)ps.c 1.1 86/02/03 SMI"; /* from UCB 4.24 83/05/22 */
+>#endif
  /*
!> * ps
   */
  #include <stdio.h>
  #include <ctype.h>
!>#include <nlist.h>
  #include <pwd.h>
  #include <sys/param.h>
  #include <sys/tty.h>
  #include <sys/dir.h>
  #include <sys/user.h>
***************
*** 30,102 ****
--- 20,60 ----
  #include <sys/stat.h>
  #include <sys/mbuf.h>
  #include <math.h>
-<#include <errno.h>
  
!<char *nl_names[] = {
!<	"_proc",
  #define	X_PROC		0
!<	"_Usrptmap",
!<#define	X_USRPTMAP	1
!<	"_usrpt",
  #define	X_USRPT		2
!<	"_text",
  #define	X_TEXT		3
!<	"_nswap",
  #define	X_NSWAP		4
!<	"_maxslp",
  #define	X_MAXSLP	5
!<	"_ccpu",
  #define	X_CCPU		6
!<	"_ecmx",
  #define	X_ECMX		7
!<	"_nproc",
  #define	X_NPROC		8
!<	"_ntext",
  #define	X_NTEXT		9
!<	"_dmmin",
  #define	X_DMMIN		10
!<	"_dmmax",
  #define	X_DMMAX		11
!<	"_Sysmap",
  #define	X_SYSMAP	12
!<	"_Syssize",
!<#define	X_SYSSIZE	13
!<	"_inode",
!<#define X_INODE		14
!<	"_file",
!<#define X_FILE		15
!<	"_cfree",
!<#define X_CFREE		16
!<	"_callout",
!<#define X_CALLOUT	17
!<	"_swapmap",
!<#define X_SWAPMAP	18
!<	"_argmap",
!<#define X_ARGMAP	19
!<	"_kernelmap",
!<#define X_KERNELMAP	20
!<	"_mbmap",
!<#define X_MBMAP		21
!<	"_namecache",
!<#define X_NCH		22
!<	"_quota",
!<#define X_QUOTA		23
!<	"_dquot",
!<#define X_DQUOT		24
!<	"_swbuf",
!<#define X_SWBUF		25
!<	"_buf",
!<#define X_BUF		26
!<	"_cmap",
!<#define X_CMAP		27
!<	"_buffers",
!<#define X_BUFFERS	28
!<	""
  };
  
-<struct nlist *nl;			/* all because we can't init unions */
-<int nllen;				/* # of nlist entries */
-<
  struct	savcom {
  	union {
  		struct	lsav *lp;
---------------
  #include <sys/stat.h>
  #include <sys/mbuf.h>
  #include <math.h>
  
!>struct nlist nl[] = {
!>	{ "_proc" },
  #define	X_PROC		0
!>	{ "_Usrptmap" },
!>#define	X_USRPTMA	1
!>	{ "_usrpt" },
  #define X_USRPT         2
!>	{ "_text" },
  #define	X_TEXT		3
!>	{ "_nswap" },
  #define	X_NSWAP		4
!>	{ "_maxslp" },
  #define	X_MAXSLP	5
!>	{ "_ccpu" },
  #define	X_CCPU		6
!>	{ "_ecmx" },
  #define	X_ECMX		7
!>	{ "_nproc" },
  #define	X_NPROC		8
!>	{ "_ntext" },
  #define	X_NTEXT		9
!>	{ "_dmmin" },
  #define	X_DMMIN		10
!>	{ "_dmmax" },
  #define	X_DMMAX		11
!>	{ "_Sysmap" },
  #define	X_SYSMAP	12
!>	{ "_Sysbase" },
!>#define	X_SYSBASE	13
!>	{ "_Syslimit" },
!>#define	X_SYSLIMIT	14
!>	{ "" },
  };
  
  struct	savcom {
  	union {
  		struct	lsav *lp;
***************
*** 120,126 ****
--- 78,83 ----
  };
  
  char	*lhdr;
-<int	wcwidth;		/* width of the wchan field for sprintf*/
  struct	lsav {
  	short	l_ppid;
  	char	l_cpu;
---------------
  struct	lsav {
  	short	l_ppid;
  	char	l_cpu;
***************
*** 138,146 ****
--- 95,101 ----
  	float	v_pctcpu;
  };
  
!<#define	NPROC	16
!<
!<struct	proc proc[NPROC];		/* a few, for less syscalls */
  struct	proc *mproc;
  struct	text *text;
  
---------------
  	float	v_pctcpu;
  };
  
!>struct	proc proc[8];		/* 8 = a few, for less syscalls */
  struct	proc *mproc;
  struct	text *text;
  
***************
*** 150,235 ****
--- 105,144 ----
  } user;
  #define u	user.user
  
!<#ifndef	PSFILE
!<char	*psdb	= "/etc/psdatabase";
!<#else
!<char	*psdb	= PSFILE;
!<#endif
  
!<int	chkpid = -1;
!<int	aflg, cflg, eflg, gflg, kflg, lflg, nflg, sflg,
!<	uflg, vflg, xflg, Uflg;
!<int	nchans;				/* total # of wait channels */
  char	*tptr;
!<char	*gettty(), *getcmd(), *getname(), *savestr(), *state();
  char	*rindex(), *calloc(), *sbrk(), *strcpy(), *strcat(), *strncat();
!<char	*strncpy(), *index(), *ttyname(), mytty[MAXPATHLEN+1];
!<char	*malloc(), *getchan();
  long	lseek();
-<off_t	vtophys();
  double	pcpu(), pmem();
-<int	wchancomp();
  int	pscomp();
  int	nswap, maxslp;
  struct	text *atext;
  double	ccpu;
  int	ecmx;
!<struct	pte *Usrptmap, *usrpt;
  int	nproc, ntext;
  int	dmmin, dmmax;
-<struct	pte *Sysmap;
-<int	Syssize;
  
-<int	nttys;
-<
  struct	ttys {
-<	dev_t	ttyd;
-<	int cand;
  	char	name[MAXNAMLEN+1];
!<} *allttys;
!<int cand[16] = {-1, -1, -1, -1, -1, -1, -1, -1,
!<		-1, -1, -1, -1, -1, -1, -1, -1};
!<struct lttys {
!<	struct ttys ttys;
!<	struct lttys *next;
!<} *lallttys;
  
-</*
-< * struct for the symbolic wait channel info
-< *
-< * WNAMESIZ is the max # of chars saved of the symbolic wchan gleaned
-< * from the namelist.  Normally, only WSNAMESIZ are printed in the long
-< * format, unless the terminal width is greater than WTSIZ wide.
-< */
-<#define WNAMESIZ	12
-<#define WSNAMESIZ	6
-<#define WTSIZ		95
-<
-<struct wchan {
-<	char	wc_name[WNAMESIZ+1];	/* symbolic name */
-<	caddr_t wc_caddr;		/* addr in kmem */
-<} *wchanhd;				/* an array sorted by wc_caddr */
-<
-<#define NWCINDEX	10		/* the size of the index array */
-<
-<caddr_t wchan_index[NWCINDEX];		/* used to speed searches */
-</*
-< * names listed here are not kept as wait channels -- this is used to 
-< * remove names that confuse ps, like symbols that define the end of an
-< * array that happen to be equal to the next symbol.
-< */
-<char *wchan_stop_list[] = {
-<	"umbabeg",
-<	"umbaend",
-<	"calimit",
-<	NULL
-<};
-<
  int	npr;
  
  int	cmdstart;
  int	twidth;
-<struct	winsize win;
  char	*kmemf, *memf, *swapf, *nlistf;
  int	kmem, mem, swap = -1;
  int	rawcpu, sumcpu;
---------------
  } user;
  #define u	user.user
  
!>#define clear(x) 	((int)x - KERNELBASE)
  
!>int	chkpid;
!>int	aflg, cflg, eflg, gflg, kflg, lflg, sflg,
!>	uflg, vflg, xflg;
  char	*tptr;
!>char	*gettty(), *getcmd(), *getname(), *savestr(), *alloc(), *state();
  char	*rindex(), *calloc(), *sbrk(), *strcpy(), *strcat(), *strncat();
!>char	*index(), *ttyname(), mytty[16];
  long	lseek();
  double	pcpu(), pmem();
  int	pscomp();
  int	nswap, maxslp;
  struct	text *atext;
  double	ccpu;
+>long	kccpu;
  int	ecmx;
!>struct	pte *Usrptma, *usrpt;
!>struct	pte *Sysmap;
!>int	Sysbase, Syslimit;
  int	nproc, ntext;
  int	dmmin, dmmax;
  
  struct	ttys {
  	char	name[MAXNAMLEN+1];
!>	dev_t	ttyd;
!>	struct	ttys *next;
!>	struct	ttys *cand;
!>} *allttys, *cand[16];
  
  int	npr;
  
  int	cmdstart;
  int	twidth;
  char	*kmemf, *memf, *swapf, *nlistf;
  int	kmem, mem, swap = -1;
  int	rawcpu, sumcpu;
***************
*** 236,243 ****
--- 145,153 ----
  
  int	pcbpf;
  int	argaddr;
  
!<#define	pgtok(a)	((a)/(1024/NBPG))
  
  main(argc, argv)
  	char **argv;
---------------
  
  int	pcbpf;
  int	argaddr;
+>int	swaddr;
  
!>#define	pgtok(a)	((a)*CLBYTES/1024)
  
  main(argc, argv)
  	char **argv;
***************
*** 246,257 ****
--- 156,163 ----
  	register char *ap;
  	int uid;
  	off_t procp;
-<	int width;
  
-<	if (ioctl(1, TIOCGWINSZ, &win) == -1)
  		twidth = 80;
-<	else
-<		twidth = (win.ws_col == 0 ? 80 : win.ws_col);
  	argc--, argv++;
  	if (argc > 0) {
  		ap = argv[0];
---------------
  	argc--, argv++;
  	if (argc > 0) {
  		ap = argv[0];
***************
*** 263,273 ****
--- 169,174 ----
  		case 'S':
  			sumcpu++;
  			break;
-<
-<		case 'U':
-<			Uflg++;
-<			break;
-<
  		case 'a':
  			aflg++;
  			break;
---------------
  		case 'a':
  			aflg++;
  			break;
***************
*** 286,294 ****
--- 187,192 ----
  		case 'l':
  			lflg++;
  			break;
-<		case 'n':
-<			nflg++;
-<			break;
  		case 's':
  			sflg++;
  			break;
---------------
  		case 's':
  			sflg++;
  			break;
***************
*** 295,307 ****
--- 193,203 ----
  		case 't':
  			if (*ap)
  				tptr = ap;
!<			else if ((tptr = ttyname(0)) != 0) {
!<				tptr = strcpy(mytty, tptr);
!<				if (strncmp(tptr, "/dev/", 5) == 0)
!<					tptr += 5;
  			}
-<			if (strncmp(tptr, "tty", 3) == 0)
-<				tptr += 3;
  			aflg++;
  			gflg++;
  			if (tptr && *tptr == '?')
---------------
  		case 't':
  			if (*ap)
  				tptr = ap;
!>			else if ((tptr = ttyname(2)) != 0) {
!>				strcpy(mytty, tptr);
!>				if ((tptr = index(mytty,'y')) != 0)
!>					tptr++;
  			}
  			aflg++;
  			gflg++;
  			if (tptr && *tptr == '?')
***************
*** 317,323 ****
--- 213,219 ----
  			vflg++;
  			break;
  		case 'w':
!<			if (twidth < 132)
  				twidth = 132;
  			else
  				twidth = BUFSIZ;
---------------
  			vflg++;
  			break;
  		case 'w':
!>			if (twidth == 80)
  				twidth = 132;
  			else
  				twidth = BUFSIZ;
***************
*** 337,352 ****
--- 233,253 ----
  	}
  	openfiles(argc, argv);
  	getkvars(argc, argv);
  	uid = getuid();
  	printhdr();
  	procp = getw(nl[X_PROC].n_value);
  	nproc = getw(nl[X_NPROC].n_value);
!<	savcom = (struct savcom *)calloc((unsigned) nproc, sizeof (*savcom));
!<	for (i=0; i<nproc; i += NPROC) {
!<		klseek(kmem, (long)procp, 0);
  		j = nproc - i;
!<		if (j > NPROC)
!<			j = NPROC;
  		j *= sizeof (struct proc);
  		if (read(kmem, (char *)proc, j) != j) {
  			cantread("proc table", kmemf);
---------------
  	}
  	openfiles(argc, argv);
  	getkvars(argc, argv);
+>	if (chdir("/dev") < 0) {
+>		perror("/dev");
+>		exit(1);
+>	}
+>	getdev();
  	uid = getuid();
  	printhdr();
  	procp = getw(nl[X_PROC].n_value);
  	nproc = getw(nl[X_NPROC].n_value);
!>	savcom = (struct savcom *)calloc(nproc, sizeof (*savcom));
!>	for (i=0; i<nproc; i += 8) {
!>		vlseek(kmem, (long)procp, 0);
  		j = nproc - i;
!>		if (j > 8)
!>			j = 8;
  		j *= sizeof (struct proc);
  		if (read(kmem, (char *)proc, j) != j) {
  			cantread("proc table", kmemf);
***************
*** 361,370 ****
--- 262,270 ----
  			if (tptr == 0 && gflg == 0 && xflg == 0 &&
  			    mproc->p_ppid == 1)
  				continue;
!<			if (uid != mproc->p_uid && aflg==0)
  				continue;
-<			if (chkpid != -1 && chkpid != mproc->p_pid)
-<				continue;
  			if (vflg && gflg == 0 && xflg == 0) {
  				if (mproc->p_stat == SZOMB ||
  				    mproc->p_flag&SWEXIT)
---------------
  			if (tptr == 0 && gflg == 0 && xflg == 0 &&
  			    mproc->p_ppid == 1)
  				continue;
!>			if (uid != mproc->p_uid && aflg==0 ||
!>			    chkpid != 0 && chkpid != mproc->p_pid)
  				continue;
  			if (vflg && gflg == 0 && xflg == 0) {
  				if (mproc->p_stat == SZOMB ||
  				    mproc->p_flag&SWEXIT)
***************
*** 377,386 ****
--- 277,283 ----
  			save();
  		}
  	}
!<	width = twidth - cmdstart - 2;
!<	if (width < 0)
!<		width = 0;
!<	qsort((char *) savcom, npr, sizeof(savcom[0]), pscomp);
  	for (i=0; i<npr; i++) {
  		register struct savcom *sp = &savcom[i];
  		if (lflg)
---------------
  			save();
  		}
  	}
!>	qsort(savcom, npr, sizeof(savcom[0]), pscomp);
  	for (i=0; i<npr; i++) {
  		register struct savcom *sp = &savcom[i];
  		if (lflg)
***************
*** 391,404 ****
--- 288,303 ----
  			upr(sp);
  		else
  			spr(sp);
!<		if (sp->ap->a_stat == SZOMB)
!<			printf(" <defunct>");
!<		else if (sp->ap->a_flag & SWEXIT)
  			printf(" <exiting>");
  		else if (sp->ap->a_pid == 0)
  			printf(" swapper");
  		else if (sp->ap->a_pid == 2)
  			printf(" pagedaemon");
  		else
  			printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
  		printf("\n");
---------------
  			upr(sp);
  		else
  			spr(sp);
!>		if (sp->ap->a_flag & SWEXIT)
  			printf(" <exiting>");
+>		else if (sp->ap->a_stat == SZOMB)
+>			printf(" <defunct>");
  		else if (sp->ap->a_pid == 0)
  			printf(" swapper");
  		else if (sp->ap->a_pid == 2)
  			printf(" pagedaemon");
+>		else if (sp->ap->a_pid == 3 && sp->ap->a_flag & SSYS)
+>			printf(" ip input");
  		else
  			printf(" %.*s", twidth - cmdstart - 2, sp->ap->a_cmdp);
  		printf("\n");
***************
*** 406,535 ****
--- 305,386 ----
  	exit(npr == 0);
  }
  
  getw(loc)
  	unsigned long loc;
  {
!<	int word;
  
!<	klseek(kmem, (long)loc, 0);
  	if (read(kmem, (char *)&word, sizeof (word)) != sizeof (word))
!<		printf("error reading kmem at %x\n", loc);
  	return (word);
  }
  
!<klseek(fd, loc, off)
  	int fd;
  	long loc;
  	int off;
  {
!<	if (kflg) {
!<		if ((loc = vtophys(loc)) == -1)
!<			return;
  	}
-<	(void) lseek(fd, (long)loc, off);
  }
  
!</*
!< * Version allows change of db format w/o temporarily bombing ps's
!< */
!<char thisversion[4] = "V2";		/* length must remain 4 */
!<
!<writepsdb(unixname)
!<	char *unixname;
  {
-<	register FILE *fp;
-<	struct lttys *lt;
-<	struct stat stb;
  
!<	setgid(getgid());
!<	setuid(getuid());
!<	if ((fp = fopen(psdb, "w")) == NULL) {
!<		perror(psdb);
  		exit(1);
-<	} else
-<		fchmod(fileno(fp), 0644);
-<
-<	fwrite(thisversion, sizeof thisversion, 1, fp);
-<	fwrite(unixname, strlen(unixname) + 1, 1, fp);
-<	if (stat(unixname, &stb) < 0)
-<		stb.st_mtime = 0;
-<	fwrite((char *) &stb.st_mtime, sizeof stb.st_mtime, 1, fp);
-<
-<	fwrite((char *) &nllen, sizeof nllen, 1, fp);
-<	fwrite((char *) nl, sizeof (struct nlist), nllen, fp);
-<	fwrite((char *) cand, sizeof (cand), 1, fp);
-<	fwrite((char *) &nttys, sizeof nttys, 1, fp);
-<	for (lt = lallttys ; lt ; lt = lt->next)
-<		fwrite((char *)&lt->ttys, sizeof (struct ttys), 1, fp);
-<	fwrite((char *) &nchans, sizeof nchans, 1, fp);
-<	fwrite((char *) wchanhd, sizeof (struct wchan), nchans, fp);
-<	fwrite((char *) wchan_index, sizeof (caddr_t), NWCINDEX, fp);
-<	fclose(fp);
  }
-<
-<readpsdb(unixname)
-<	char *unixname;
-<{
-<	register i;
-<	register FILE *fp;
-<	char unamebuf[BUFSIZ];
-<	char *p	= unamebuf;
-<	char dbversion[sizeof thisversion];
-<	struct stat stb;
-<	time_t dbmtime;
-<	extern int errno;
-<
-<	if ((fp = fopen(psdb, "r")) == NULL) {
-<		if (errno == ENOENT)
-<			return (0);
-<		perror(psdb);
-<		exit(1);
  	}
  
-<	/*
-<	 * Does the db file match this unix?
-<	 */
-<	fread(dbversion, sizeof dbversion, 1, fp);
-<	if (bcmp(thisversion, dbversion, sizeof thisversion))
-<		goto bad;
-<	while ((*p = getc(fp)) != '\0')
-<		p++;
-<	if (strcmp(unixname, unamebuf))
-<		goto bad;
-<	fread((char *) &dbmtime, sizeof dbmtime, 1, fp);
-<	if (stat(unixname, &stb) < 0)
-<		stb.st_mtime = 0;
-<	if (stb.st_mtime != dbmtime)
-<		goto bad;
  
-<	fread((char *) &nllen, sizeof nllen, 1, fp);
-<	nl = (struct nlist *) malloc (nllen * sizeof (struct nlist));
-<	fread((char *) nl, sizeof (struct nlist), nllen, fp);
-<	fread((char *) cand, sizeof (cand), 1, fp);
-<	fread((char *) &nttys, sizeof nttys, 1, fp);
-<	allttys = (struct ttys *)malloc(sizeof(struct ttys)*nttys);
-<	if (allttys == NULL) {
-<		fprintf(stderr, "ps: Can't malloc space for tty table\n");
-<		exit(1);
-<	}
-<	fread((char *) allttys, sizeof (struct ttys), nttys, fp);
-<	fread((char *) &nchans, sizeof nchans, 1, fp);
-<	wchanhd = (struct wchan *) malloc(nchans * sizeof (struct wchan));
-<	if (wchanhd == NULL) {
-<		fprintf(stderr, "ps: Can't malloc space for wait channels\n");
-<		nflg++;
-<		fseek(fp, (long) nchans * sizeof (struct wchan), 1);
-<	} else
-<		fread((char *) wchanhd, sizeof (struct wchan), nchans, fp);
-<	fread((char *) wchan_index, sizeof (caddr_t), NWCINDEX, fp);
-<	fclose(fp);
-<	return(1);
-<
-<bad:
-<	fclose(fp);
-<	return(0);
-<}
-<
  openfiles(argc, argv)
  	char **argv;
  {
---------------
  	exit(npr == 0);
  }
  
+>/*
+> * Returns the physical address of location "addr" in kmem.
+> * It is assumed that addr, Sysbase, Syslimit, and Sysmap
+> * have already been "clear()ed" in the kflg case.
+> */
+>physaddr(addr)
+>	int addr;
+>{
+>	int v;
+>	struct pte pte;
+>
+>	if (kflg) {
+>		if (addr < Sysbase || addr > Syslimit) {
+>			return (addr);
+>		}
+>		v = btop(addr);
+>		lseek(kmem, (long)(Sysmap+v), 0);
+>		if (read(kmem, &pte, sizeof(pte)) != sizeof(pte)) {
+>			printf("error reading %s to get pte for %x\n",
+>			    kmemf, addr);
+>			return (addr);
+>		}
+>		if (pte.pg_v == 0 && (pte.pg_fod || pte.pg_pfnum == 0)) {
+>			printf("page not valid for address %x\n", addr);
+>			return (addr);
+>		}
+>		addr &= PGOFSET;
+>		addr += (int)ptob(pte.pg_pfnum);
+>	}
+>	return (addr);
+>}
+>
+>
  getw(loc)
  	unsigned long loc;
  {
!>	long word;
  
!>	vlseek(kmem, (long)loc, 0);
  	if (read(kmem, (char *)&word, sizeof (word)) != sizeof (word))
!>		printf("error reading %s at %x\n", kmemf, loc);
!>	if (kflg && word >= KERNELBASE)
!>		word -= KERNELBASE;
  	return (word);
  }
  
!>/*
!> * Seek to a kernel virtual address
!> */
!>vlseek(fd, loc, off)
  	int fd;
  	long loc;
  	int off;
  {
!>	loc = physaddr(loc);
!>	if (lseek(fd, (long)loc, off) == -1) {
!>		perror("seek");
!>		exit(1);
  	}
  }
  
!>klseek(fd, loc, off)
!>	int fd;
!>	long loc;
!>	int off;
  {
  
!>	if (kflg && loc >= KERNELBASE)
!>		loc -= KERNELBASE;
!>	if (lseek(fd, (long)loc, off) == -1) {
!>		perror("seek");
  		exit(1);
  	}
  }
  
  
  openfiles(argc, argv)
  	char **argv;
  {
***************
*** 566,632 ****
--- 417,456 ----
  getkvars(argc, argv)
  	char **argv;
  {
!<	int faildb = 0;			/* true if psdatabase init failed */
!<	int i;
  
  	nlistf = argc > 1 ? argv[1] : "/vmunix";
-<	if (Uflg) {
-<		init_nlist();
  		nlist(nlistf, nl);
-<		getvchans();
-<		getdev();
-<		writepsdb(nlistf);
-<		exit (0);
-<	} else if (!readpsdb(nlistf)) {
-<		init_nlist();
-<		if (!kflg)
-<			nl[X_SYSMAP].n_un.n_name = "";
-<		faildb = 1;
-<		nlist(nlistf, nl);
-<		nttys = 0;
-<		getdev();
-<	}
-<
  	if (nl[0].n_type == 0) {
  		fprintf(stderr, "%s: No namelist\n", nlistf);
  		exit(1);
  	}
!<	if (kflg) {
!<		/* We must do the sys map first because klseek uses it */
!<		long	addr;
!<
!<		Syssize = nl[X_SYSSIZE].n_value;
!<		Sysmap = (struct pte *)
!<			calloc((unsigned) Syssize, sizeof (struct pte));
!<		if (Sysmap == NULL) {
!<			fprintf(stderr, "Out of space for Sysmap\n");
!<			exit(1);
!<		}
!<		addr = (long) nl[X_SYSMAP].n_value;
!<		addr &= ~0x80000000;
!<		(void) lseek(kmem, addr, 0);
!<		read(kmem, (char *) Sysmap, Syssize * sizeof (struct pte));
!<	}
!<	if (faildb)
!<		getvchans();
!<	usrpt = (struct pte *)nl[X_USRPT].n_value;
!<	Usrptmap = (struct pte *)nl[X_USRPTMAP].n_value;
!<	klseek(kmem, (long)nl[X_NSWAP].n_value, 0);
  	if (read(kmem, (char *)&nswap, sizeof (nswap)) != sizeof (nswap)) {
  		cantread("nswap", kmemf);
  		exit(1);
  	}
!<	klseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
  	if (read(kmem, (char *)&maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
  		cantread("maxslp", kmemf);
  		exit(1);
  	}
!<	klseek(kmem, (long)nl[X_CCPU].n_value, 0);
!<	if (read(kmem, (char *)&ccpu, sizeof (ccpu)) != sizeof (ccpu)) {
  		cantread("ccpu", kmemf);
  		exit(1);
  	}
!<	klseek(kmem, (long)nl[X_ECMX].n_value, 0);
  	if (read(kmem, (char *)&ecmx, sizeof (ecmx)) != sizeof (ecmx)) {
  		cantread("ecmx", kmemf);
  		exit(1);
---------------
  getkvars(argc, argv)
  	char **argv;
  {
!>	register struct nlist *nlp;
  
  	nlistf = argc > 1 ? argv[1] : "/vmunix";
  	nlist(nlistf, nl);
  	if (nl[0].n_type == 0) {
  		fprintf(stderr, "%s: No namelist\n", nlistf);
  		exit(1);
  	}
!>	usrpt = (struct pte *)nl[X_USRPT].n_value;      /* don't clear!! */
!>	Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
!>	if (kflg)
!>		for (nlp = nl; nlp < &nl[sizeof (nl)/sizeof (nl[0])]; nlp++)
!>			if (nlp->n_value >= KERNELBASE)
!>				nlp->n_value = clear(nlp->n_value);
!>	Sysmap = (struct pte *)nl[X_SYSMAP].n_value;
!>	Sysbase = nl[X_SYSBASE].n_value;
!>	Syslimit = nl[X_SYSLIMIT].n_value;
!>	vlseek(kmem, (long)nl[X_NSWAP].n_value, 0);
  	if (read(kmem, (char *)&nswap, sizeof (nswap)) != sizeof (nswap)) {
  		cantread("nswap", kmemf);
  		exit(1);
  	}
!>	vlseek(kmem, (long)nl[X_MAXSLP].n_value, 0);
  	if (read(kmem, (char *)&maxslp, sizeof (maxslp)) != sizeof (maxslp)) {
  		cantread("maxslp", kmemf);
  		exit(1);
  	}
!>	vlseek(kmem, (long)nl[X_CCPU].n_value, 0);
!>	if (read(kmem, (char *)&kccpu, sizeof (kccpu)) != sizeof (kccpu)) {
  		cantread("ccpu", kmemf);
  		exit(1);
  	}
!>	ccpu = (double)kccpu / FSCALE;
!>	vlseek(kmem, (long)nl[X_ECMX].n_value, 0);
  	if (read(kmem, (char *)&ecmx, sizeof (ecmx)) != sizeof (ecmx)) {
  		cantread("ecmx", kmemf);
  		exit(1);
***************
*** 633,646 ****
--- 457,469 ----
  	}
  	if (uflg || vflg) {
  		ntext = getw(nl[X_NTEXT].n_value);
!<		text = (struct text *)
!<			calloc((unsigned) ntext, sizeof (struct text));
  		if (text == 0) {
  			fprintf(stderr, "no room for text table\n");
  			exit(1);
  		}
  		atext = (struct text *)getw(nl[X_TEXT].n_value);
!<		klseek(kmem, (long)atext, 0);
  		if (read(kmem, (char *)text, ntext * sizeof (struct text))
  		    != ntext * sizeof (struct text)) {
  			cantread("text table", kmemf);
---------------
  	}
  	if (uflg || vflg) {
  		ntext = getw(nl[X_NTEXT].n_value);
!>		text = (struct text *)alloc(ntext * sizeof (struct text));
  		if (text == 0) {
  			fprintf(stderr, "no room for text table\n");
  			exit(1);
  		}
  		atext = (struct text *)getw(nl[X_TEXT].n_value);
!>		vlseek(kmem, (long)atext, 0);
  		if (read(kmem, (char *)text, ntext * sizeof (struct text))
  		    != ntext * sizeof (struct text)) {
  			cantread("text table", kmemf);
***************
*** 651,693 ****
--- 474,479 ----
  	dmmax = getw(nl[X_DMMAX].n_value);
  }
  
-</*
-< * get the valloc'ed kernel variables for symbolic wait channels
-< */
-<getvchans()
-<{
-<	int i, tmp;
-<
-<	if (nflg)
-<		return;
-<
-<#define addv(i) 	addchan(&nl[i].n_un.n_name[1], getw(nl[i].n_value))
-<	addv(X_INODE);
-<	addv(X_FILE);
-<	addv(X_PROC);
-<	addv(X_TEXT);
-<	addv(X_CFREE);
-<	addv(X_CALLOUT);
-<	addv(X_SWAPMAP);
-<	addv(X_ARGMAP);
-<	addv(X_KERNELMAP);
-<	addv(X_MBMAP);
-<	addv(X_NCH);
-<	if (nl[X_QUOTA].n_value != 0) {	/* these are #ifdef QUOTA */
-<		addv(X_QUOTA);
-<		addv(X_DQUOT);
-<	}
-<	addv(X_SWBUF);
-<	addv(X_BUF);
-<	addv(X_CMAP);
-<	addv(X_BUFFERS);
-<	qsort(wchanhd, nchans, sizeof (struct wchan), wchancomp);
-<	for (i = 0; i < NWCINDEX; i++) {
-<		tmp = i * nchans;
-<		wchan_index[i] = wchanhd[tmp / NWCINDEX].wc_caddr;
-<	}
-<#undef addv
-<}
  printhdr()
  {
  	char *hdr;
---------------
  printhdr()
  {
  	char *hdr;
***************
*** 696,724 ****
--- 482,490 ----
  		fprintf(stderr, "ps: specify only one of s,l,v and u\n");
  		exit(1);
  	}
!<	if (lflg) {
!<		if (nflg)
!<			wcwidth = 6;
!<		else if (twidth > WTSIZ)
!<			wcwidth = -WNAMESIZ;
!<		else
!<			wcwidth = -WSNAMESIZ;
!<		if ((hdr = malloc(strlen(lhdr) + WNAMESIZ)) == NULL) {
!<			fprintf(stderr, "ps: out of memory\n");
!<			exit(1);
!<		}
!<		sprintf(hdr, lhdr, wcwidth, "WCHAN");
!<	} else if (vflg)
!<		hdr = vhdr;
!<	else if (uflg) {
!<		/* add enough on so that it can hold the sprintf below */
!<		if ((hdr = malloc(strlen(uhdr) + 10)) == NULL) {
!<			fprintf(stderr, "ps: out of memory\n");
!<			exit(1);
!<		}
!<		sprintf(hdr, uhdr, nflg ? " UID" : "USER    ");
!<	} else
!<		hdr = shdr;
  	if (lflg+vflg+uflg+sflg == 0)
  		hdr += strlen("SSIZ ");
  	cmdstart = strlen(hdr);
---------------
  		fprintf(stderr, "ps: specify only one of s,l,v and u\n");
  		exit(1);
  	}
!>	hdr = lflg ? lhdr : 
!>			(vflg ? vhdr : 
!>				(uflg ? uhdr : shdr));
  	if (lflg+vflg+uflg+sflg == 0)
  		hdr += strlen("SSIZ ");
  	cmdstart = strlen(hdr);
***************
*** 739,751 ****
--- 505,511 ----
  getdev()
  {
  	register DIR *df;
-<	struct ttys *t;
-<	struct lttys *lt;
  
-<	if (chdir("/dev") < 0) {
-<		perror("/dev");
-<		exit(1);
-<	}
  	dialbase = -1;
  	if ((df = opendir(".")) == NULL) {
  		fprintf(stderr, "Can't open . in /dev\n");
---------------
  	dialbase = -1;
  	if ((df = opendir(".")) == NULL) {
  		fprintf(stderr, "Can't open . in /dev\n");
***************
*** 754,767 ****
--- 514,520 ----
  	while ((dbuf = readdir(df)) != NULL) 
  		maybetty();
  	closedir(df);
-<	allttys = (struct ttys *)malloc(sizeof(struct ttys)*nttys);
-<	if (allttys == NULL) {
-<		fprintf(stderr, "ps: Can't malloc space for tty table\n");
-<		exit(1);
  	}
-<	for (lt = lallttys, t = allttys; lt ; lt = lt->next, t++)
-<		*t = lt->ttys;
-<}
  
  /*
   * Attempt to avoid stats by guessing minor device
---------------
  
  /*
   * Attempt to avoid stats by guessing minor device
***************
*** 772,779 ****
--- 525,531 ----
  maybetty()
  {
  	register char *cp = dbuf->d_name;
!<	static struct lttys *dp;
!<	struct lttys *olddp;
  	int x;
  	struct stat stb;
  
---------------
  maybetty()
  {
  	register char *cp = dbuf->d_name;
!>	register struct ttys *dp;
  	int x;
  	struct stat stb;
  
***************
*** 805,813 ****
--- 557,566 ----
  
  	case 'r':
  		cp++;
  #define is(a,b) cp[0] == 'a' && cp[1] == 'b'
!<		if (is(h,p) || is(r,a) || is(u,p) || is(h,k) 
!<		    || is(r,b) || is(m,t)) {
  			cp += 2;
  			if (isdigit(*cp) && cp[2] == 0)
  				return;
---------------
  
  	case 'r':
  		cp++;
+>		if (*cp == 'r' || *cp == 'u' || *cp == 'h')
+>			cp++;
  #define is(a,b) cp[0] == 'a' && cp[1] == 'b'
!>		if (is(r,p) || is(u,p) || is(r,k) || is(r,m) || is(m,t)) {
  			cp += 2;
  			if (isdigit(*cp) && cp[2] == 0)
  				return;
***************
*** 825,839 ****
--- 578,585 ----
  	case 'n':
  		if (!strcmp(cp, "null"))
  			return;
-<		if (!strncmp(cp, "nrmt", 4))
-<			return;
  		break;
  
-<	case 'p':
-<		if (cp[1] && cp[1] == 't' && cp[2] == 'y')
-<			return;
-<		break;
-<
  	case 'v':
  		if ((cp[1] == 'a' || cp[1] == 'p') && isdigit(cp[2]) &&
  		    cp[3] == 0)
---------------
  	case 'v':
  		if ((cp[1] == 'a' || cp[1] == 'p') && isdigit(cp[2]) &&
  		    cp[3] == 0)
***************
*** 863,902 ****
--- 609,624 ----
  	else
  		x = -1;
  donecand:
!<	olddp = dp;
!<	dp = (struct lttys *)malloc(sizeof(struct lttys));
!<	if (dp == NULL) {
!<		fprintf(stderr, "ps: Can't malloc space for tty table\n");
!<		exit(1);
!<	}
!<	if (lallttys == NULL)
!<		lallttys = dp;
!<	nttys++;
!<	if (olddp)
!<		olddp->next = dp;
!<	dp->next = NULL;
!<	(void) strcpy(dp->ttys.name, dbuf->d_name);
!<	if (Uflg) {
!<		if (stat(dp->ttys.name, &stb) == 0 &&
!<		   (stb.st_mode&S_IFMT)==S_IFCHR)
!<			dp->ttys.ttyd = x = stb.st_rdev;
!<		else {
!<			nttys--;
!<			if (lallttys == dp)
!<				lallttys = NULL;
!<			free(dp);
!<			dp = olddp;
!<			if (dp)
!<				dp->next = NULL;
!<			return;
!<		}
!<	} else
!<		dp->ttys.ttyd = -1;
  	if (x == -1)
  		return;
  	x &= 017;
!<	dp->ttys.cand = cand[x];
!<	cand[x] = nttys-1;
  }
  
  char *
---------------
  	else
  		x = -1;
  donecand:
!>	dp = (struct ttys *)alloc(sizeof (struct ttys));
!>	(void) strcpy(dp->name, dbuf->d_name);
!>	dp->next = allttys;
!>	dp->ttyd = -1;
!>	allttys = dp;
  	if (x == -1)
  		return;
  	x &= 017;
!>	dp->cand = cand[x];
!>	cand[x] = dp;
  }
  
  char *
***************
*** 910,917 ****
--- 632,638 ----
  	if (u.u_ttyp == 0)
  		return("?");
  	x = u.u_ttyd & 017;
!<	for (dp = &allttys[cand[x]]; dp != &allttys[-1];
!<	     dp = &allttys[dp->cand]) {
  		if (dp->ttyd == -1) {
  			if (stat(dp->name, &stb) == 0 &&
  			   (stb.st_mode&S_IFMT)==S_IFCHR)
---------------
  	if (u.u_ttyp == 0)
  		return("?");
  	x = u.u_ttyd & 017;
!>	for (dp = cand[x]; dp; dp = dp->cand) {
  		if (dp->ttyd == -1) {
  			if (stat(dp->name, &stb) == 0 &&
  			   (stb.st_mode&S_IFMT)==S_IFCHR)
***************
*** 923,929 ****
--- 644,650 ----
  			goto found;
  	}
  	/* ick */
!<	for (dp = allttys; dp < &allttys[nttys]; dp++) {
  		if (dp->ttyd == -1) {
  			if (stat(dp->name, &stb) == 0 &&
  			   (stb.st_mode&S_IFMT)==S_IFCHR)
---------------
  			goto found;
  	}
  	/* ick */
!>	for (dp = allttys; dp; dp = dp->next) {
  		if (dp->ttyd == -1) {
  			if (stat(dp->name, &stb) == 0 &&
  			   (stb.st_mode&S_IFMT)==S_IFCHR)
***************
*** 959,965 ****
--- 680,686 ----
  	cmdp = getcmd();
  	if (cmdp == 0)
  		return;
!<	sp->ap = ap = (struct asav *)calloc(1, sizeof (struct asav));
  	sp->ap->a_cmdp = cmdp;
  #define e(a,b) ap->a = mproc->b
  	e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
---------------
  	cmdp = getcmd();
  	if (cmdp == 0)
  		return;
!>	sp->ap = ap = (struct asav *)alloc(sizeof (struct asav));
  	sp->ap->a_cmdp = cmdp;
  #define e(a,b) ap->a = mproc->b
  	e(a_flag, p_flag); e(a_stat, p_stat); e(a_nice, p_nice);
***************
*** 988,1006 ****
--- 709,728 ----
  	if (lflg) {
  		register struct lsav *lp;
  
!<		sp->s_un.lp = lp = (struct lsav *)
!<			calloc(1, sizeof (struct lsav));
  #define e(a,b) lp->a = mproc->b
  		e(l_ppid, p_ppid); e(l_cpu, p_cpu);
  		if (ap->a_stat != SZOMB)
  			e(l_wchan, p_wchan);
  #undef e
  		lp->l_addr = pcbpf;
  	} else if (vflg) {
  		register struct vsav *vp;
  
!<		sp->s_un.vp = vp = (struct vsav *)
!<			calloc(1, sizeof (struct vsav));
  #define e(a,b) vp->a = mproc->b
  		if (ap->a_stat != SZOMB) {
  			e(v_swrss, p_swrss);
---------------
  	if (lflg) {
  		register struct lsav *lp;
  
!>		sp->s_un.lp = lp = (struct lsav *)alloc(sizeof (struct lsav));
  #define e(a,b) lp->a = mproc->b
  		e(l_ppid, p_ppid); e(l_cpu, p_cpu);
  		if (ap->a_stat != SZOMB)
  			e(l_wchan, p_wchan);
  #undef e
+>		if (ap->a_flag & SLOAD)
  			lp->l_addr = pcbpf;
+>		else
+>			lp->l_addr = swaddr;
  	} else if (vflg) {
  		register struct vsav *vp;
  
!>		sp->s_un.vp = vp = (struct vsav *)alloc(sizeof (struct vsav));
  #define e(a,b) vp->a = mproc->b
  		if (ap->a_stat != SZOMB) {
  			e(v_swrss, p_swrss);
***************
*** 1048,1110 ****
--- 770,855 ----
  pcpu()
  {
  	time_t time;
  
  	time = mproc->p_time;
  	if (time == 0 || (mproc->p_flag&SLOAD) == 0)
  		return (0.0);
  	if (rawcpu)
!<		return (100.0 * mproc->p_pctcpu);
!<	return (100.0 * mproc->p_pctcpu / (1.0 - exp(time * log(ccpu))));
  }
  
!<getu()
  {
  	struct pte *pteaddr, apte;
!<	struct pte arguutl[UPAGES+CLSIZE];
  	register int i;
  	int ncl, size;
  
!<	size = sflg ? ctob(UPAGES) : sizeof (struct user);
  	if ((mproc->p_flag & SLOAD) == 0) {
  		if (swap < 0)
  			return (0);
  		(void) lseek(swap, (long)dtob(mproc->p_swaddr), 0);
  		if (read(swap, (char *)&user.user, size) != size) {
!<			fprintf(stderr, "ps: cant read u for pid %d from %s\n",
  			    mproc->p_pid, swapf);
  			return (0);
  		}
  		pcbpf = 0;
  		argaddr = 0;
  		return (1);
  	}
!<	pteaddr = &Usrptmap[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
!<	klseek(kmem, (long)pteaddr, 0);
!<	if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
!<		printf("ps: cant read indir pte to get u for pid %d from %s\n",
!<		    mproc->p_pid, kmemf);
  		return (0);
!<	}
!<	lseek(mem,
!<	    (long)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte),
!<		0);
!<	if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
!<		printf("ps: cant read page table for u of pid %d from %s\n",
!<		    mproc->p_pid, memf);
!<		return (0);
!<	}
!<	if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
!<		argaddr = ctob(arguutl[0].pg_pfnum);
  	else
  		argaddr = 0;
!<	pcbpf = arguutl[CLSIZE].pg_pfnum;
!<	ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
  	while (--ncl >= 0) {
  		i = ncl * CLSIZE;
!<		lseek(mem, (long)ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
!<		if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
!<			printf("ps: cant read page %d of u of pid %d from %s\n",
!<			    arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
  			return(0);
  		}
  	}
---------------
  pcpu()
  {
  	time_t time;
+>	double p;
  
  	time = mproc->p_time;
  	if (time == 0 || (mproc->p_flag&SLOAD) == 0)
  		return (0.0);
+>	p = (double)mproc->p_pctcpu / FSCALE;
  	if (rawcpu)
!>		return (100.0 * p);
!>	return (100.0 * p / (1.0 - exp(time * log(ccpu))));
  }
  
!>/*
!> * Get npte ptes from kernel address ptep into array kpte.
!> * XXX - ptes must not cross a kernel page boundary.
!> */
!>getkpte(ptep, npte, kpte)
!>	struct pte *ptep;
!>	int npte;
!>	struct pte kpte[];
  {
  	struct pte *pteaddr, apte;
!>
!>	pteaddr = &Usrptma[btokmx(ptep)];
!>	if (kflg)
!>		pteaddr = (struct pte *)clear(pteaddr);
!>	klseek(kmem, (long)pteaddr, 0);
!>	if (read(kmem, (char *)&apte, sizeof (apte)) != sizeof (apte)) {
!>		printf("ps: can't read indir pte to get u for pid %d from %s\n",
!>		    mproc->p_pid, swapf);
!>		return (0);
!>	}
!>	klseek(mem, (long)ctob(apte.pg_pfnum) + (((int)ptep)&PGOFSET), 0);
!>	if (read(mem, (char *)kpte, npte * sizeof (struct pte)) !=
!>	    npte * sizeof (struct pte)) {
!>		printf("ps: can't read page table for u of pid %d from %s\n",
!>		    mproc->p_pid, kmemf);
!>		return (0);
!>	}
!>	return (1);
!>}
!>
!>getu()
!>{
!>	struct pte apte;
!>	struct pte uutl[UPAGES];
  	register int i;
  	int ncl, size;
  
!>	size = sflg ? ctob(UPAGES) : roundup(sizeof (struct user), DEV_BSIZE);
  	if ((mproc->p_flag & SLOAD) == 0) {
  		if (swap < 0)
  			return (0);
  		(void) lseek(swap, (long)dtob(mproc->p_swaddr), 0);
  		if (read(swap, (char *)&user.user, size) != size) {
!>			fprintf(stderr, "ps: can't read u for pid %d from %s\n",
  			    mproc->p_pid, swapf);
  			return (0);
  		}
  		pcbpf = 0;
  		argaddr = 0;
+>		swaddr = mproc->p_swaddr;
  		return (1);
  	}
!>	swaddr = 0;
!>	if (getkpte(sptopte(mproc, CLSIZE-1), 1, &apte) == 0)
  		return (0);
!>	if (apte.pg_fod == 0 && apte.pg_pfnum)
!>		argaddr = ctob(apte.pg_pfnum);
  	else
  		argaddr = 0;
!>	if (getkpte(mproc->p_addr, UPAGES, uutl) == 0)
!>		return (0);
!>	pcbpf = uutl[((char *)&u.u_pcb - (char *)&u) / CLBYTES].pg_pfnum;
!>	ncl = (size + CLBYTES - 1) / (CLBYTES);
  	while (--ncl >= 0) {
  		i = ncl * CLSIZE;
!>		klseek(mem, (long)ctob(uutl[i].pg_pfnum), 0);
!>		if (read(mem, user.upages[i], CLBYTES) != CLBYTES) {
!>			printf("ps: can't read page %d of u of pid %d from %s\n",
!>			    uutl[i].pg_pfnum, mproc->p_pid, memf);
  			return (0);
  		}
  	}
***************
*** 1114,1123 ****
--- 859,868 ----
  char *
  getcmd()
  {
!<	char cmdbuf[CLSIZE*NBPG];
  	union {
!<		char	argc[CLSIZE*NBPG];
!<		int	argi[CLSIZE*NBPG/sizeof (int)];
  	} argspac;
  	register char *cp;
  	register int *ip;
---------------
  char *
  getcmd()
  {
!>	char cmdbuf[CLBYTES];
  	union {
!>		char	argc[CLBYTES];
!>		int	argi[CLBYTES/sizeof (int)];
  	} argspac;
  	register char *cp;
  	register int *ip;
***************
*** 1132,1137 ****
--- 877,884 ----
---------------
  		(void) strncpy(cmdbuf, u.u_comm, sizeof (u.u_comm));
  		return (savestr(cmdbuf));
  	}
+>	if (u.u_ssize == 0)
+>		goto retucomm;
  	if ((mproc->p_flag & SLOAD) == 0 || argaddr == 0) {
  		if (swap < 0)
  			goto retucomm;
***************
*** 1142,1154 ****
--- 889,901 ----
  			goto bad;
  		file = swapf;
  	} else {
!<		lseek(mem, (long)argaddr, 0);
  		if (read(mem, (char *)&argspac, sizeof (argspac))
  		    != sizeof (argspac))
  			goto bad;
  		file = memf;
  	}
!<	ip = &argspac.argi[CLSIZE*NBPG/sizeof (int)];
  	ip -= 2;		/* last arg word and .long 0 */
  	while (*--ip)
  		if (ip == argspac.argi)
---------------
  			goto bad;
  		file = swapf;
  	} else {
!>		klseek(mem, (long)argaddr, 0);
  		if (read(mem, (char *)&argspac, sizeof (argspac))
  		    != sizeof (argspac))
  			goto bad;
  		file = memf;
  	}
!>	ip = &argspac.argi[CLBYTES/sizeof (int)];
  	ip -= 2;		/* last arg word and .long 0 */
  	while (*--ip)
  		if (ip == argspac.argi)
***************
*** 1156,1162 ****
--- 903,909 ----
  	*(char *)ip = ' ';
  	ip++;
  	nbad = 0;
!<	for (cp = (char *)ip; cp < &argspac.argc[CLSIZE*NBPG]; cp++) {
  		c = *cp & 0177;
  		if (c == 0)
  			*cp = ' ';
---------------
  	*(char *)ip = ' ';
  	ip++;
  	nbad = 0;
!>	for (cp = (char *)ip; cp < &argspac.argc[CLBYTES]; cp++) {
  		c = *cp & 0177;
  		if (c == 0)
  			*cp = ' ';
***************
*** 1177,1188 ****
--- 924,939 ----
  	while (*--cp == ' ')
  		*cp = 0;
  	cp = (char *)ip;
!<	(void) strncpy(cmdbuf, cp, &argspac.argc[CLSIZE*NBPG] - cp);
  	if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
  		(void) strcat(cmdbuf, " (");
  		(void) strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
  		(void) strcat(cmdbuf, ")");
  	}
  	return (savestr(cmdbuf));
  
  bad:
---------------
  	while (*--cp == ' ')
  		*cp = 0;
  	cp = (char *)ip;
!>	(void) strncpy(cmdbuf, cp, &argspac.argc[CLBYTES] - cp);
  	if (cp[0] == '-' || cp[0] == '?' || cp[0] <= ' ') {
  		(void) strcat(cmdbuf, " (");
  		(void) strncat(cmdbuf, u.u_comm, sizeof(u.u_comm));
  		(void) strcat(cmdbuf, ")");
  	}
+>/*
+>	if (xflg == 0 && gflg == 0 && tptr == 0 && cp[0] == '-')
+>		return (0);
+>*/
  	return (savestr(cmdbuf));
  
  bad:
***************
*** 1196,1202 ****
--- 947,953 ----
  }
  
  char	*lhdr =
!<"      F UID   PID  PPID CP PRI NI ADDR  SZ  RSS %*s STAT TT  TIME";
  lpr(sp)
  	struct savcom *sp;
  {
---------------
  }
  
  char	*lhdr =
!>"      F UID   PID  PPID CP PRI NI ADDR  SZ RSS   WCHAN STAT TT  TIME";
  lpr(sp)
  	struct savcom *sp;
  {
***************
*** 1203,1218 ****
--- 954,964 ----
  	register struct asav *ap = sp->ap;
  	register struct lsav *lp = sp->s_un.lp;
  
!<	printf("%7x%4d%6u%6u%3d%4d%3d%5x%4d%5d",
  	    ap->a_flag, ap->a_uid,
  	    ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
  	    ap->a_nice-NZERO, lp->l_addr, pgtok(ap->a_size), pgtok(ap->a_rss));
!<	if (lp->l_wchan == 0)
!<		printf(" %*s", wcwidth, "");
!<	else if (nflg)
!<		printf(" %*x", wcwidth, (int)lp->l_wchan&0xffffff);
!<	else
!<		printf(" %*.*s", wcwidth, abs(wcwidth), getchan(lp->l_wchan));
  	printf(" %4.4s ", state(ap));
  	ptty(ap->a_tty);
  	ptime(ap);
---------------
  	register struct asav *ap = sp->ap;
  	register struct lsav *lp = sp->s_un.lp;
  
!>	printf("%7x%4d%6u%6u%3d%4d%3d%5x%4d%4d",
  	    ap->a_flag, ap->a_uid,
  	    ap->a_pid, lp->l_ppid, lp->l_cpu&0377, ap->a_pri-PZERO,
  	    ap->a_nice-NZERO, lp->l_addr, pgtok(ap->a_size), pgtok(ap->a_rss));
!>	printf(lp->l_wchan ? " %7x" : "        ", (int)lp->l_wchan&0xfffffff);
  	printf(" %4.4s ", state(ap));
  	ptty(ap->a_tty);
  	ptime(ap);
***************
*** 1233,1239 ****
--- 979,985 ----
  }
  
  char	*uhdr =
!<"%s   PID %%CPU %%MEM   SZ  RSS TT STAT  TIME";
  upr(sp)
  	struct savcom *sp;
  {
---------------
  }
  
  char	*uhdr =
!>"USER       PID %CPU %MEM   SZ  RSS TT STAT  TIME";
  upr(sp)
  	struct savcom *sp;
  {
***************
*** 1244,1255 ****
--- 990,998 ----
  	rmsize = pgtok(ap->a_rss);
  	if (ap->a_xccount)
  		rmsize += pgtok(ap->a_txtrss/ap->a_xccount);
!<	if (nflg)
!<		printf("%4d ", ap->a_uid);
!<	else
!<		printf("%-8.8s ", getname(ap->a_uid));
!<	printf("%5d%5.1f%5.1f%5d%5d",
!<	    ap->a_pid, sp->s_un.u_pctcpu, pmem(ap), vmsize, rmsize);
  	putchar(' ');
  	ptty(ap->a_tty);
  	printf(" %4.4s", state(ap));
---------------
  	rmsize = pgtok(ap->a_rss);
  	if (ap->a_xccount)
  		rmsize += pgtok(ap->a_txtrss/ap->a_xccount);
!>	printf("%-8.8s %5d%5.1f%5.1f%5d%5d",
!>	    getname(ap->a_uid), ap->a_pid, sp->s_un.u_pctcpu, pmem(ap),
!>	    vmsize, rmsize);
  	putchar(' ');
  	ptty(ap->a_tty);
  	printf(" %4.4s", state(ap));
***************
*** 1275,1281 ****
--- 1018,1024 ----
  	if (ap->a_maxrss == (RLIM_INFINITY/NBPG))
  		printf("    xx");
  	else
!<		printf("%6d", pgtok(ap->a_maxrss));
  	printf("%5d%4d%5.1f%5.1f",
  	   pgtok(ap->a_tsiz), pgtok(ap->a_txtrss), vp->v_pctcpu, pmem(ap));
  }
---------------
  	if (ap->a_maxrss == (RLIM_INFINITY/NBPG))
  		printf("   xx");
  	else
!>		printf("%5d", pgtok(ap->a_maxrss));
  	printf("%5d%4d%5.1f%5.1f",
  	   pgtok(ap->a_tsiz), pgtok(ap->a_txtrss), vp->v_pctcpu, pmem(ap));
  }
***************
*** 1419,1717 ****
--- 1162,1289 ----
  	return (vp->v_swrss + (ap->a_xccount ? 0 : vp->v_txtswrss));
  }
  
!<#include <utmp.h>
  
!<struct	utmp utmp;
!<#define	NMAX	(sizeof (utmp.ut_name))
!<#define SCPYN(a, b)	strncpy(a, b, NMAX)
  
!<#define NUID	64
!<
!<struct ncache {
!<	int	uid;
!<	char	name[NMAX+1];
!<} nc[NUID];
!<
!</*
!< * This function assumes that the password file is hashed
!< * (or some such) to allow fast access based on a uid key.
!< */
!<char *
!<getname(uid)
  {
!<	register struct passwd *pw;
!<	struct passwd *getpwent();
!<	register int cp;
!<	extern int _pw_stayopen;
  
-<	_pw_stayopen = 1;
-<
-<#if	(((NUID) & ((NUID) - 1)) != 0)
-<	cp = uid % (NUID);
-<#else
-<	cp = uid & ((NUID) - 1);
-<#endif
-<	if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0])
-<		return (nc[cp].name);
-<	pw = getpwuid(uid);
-<	if (!pw)
-<		return (0);
-<	nc[cp].uid = uid;
-<	SCPYN(nc[cp].name, pw->pw_name);
-<	return (nc[cp].name);
-<}
-<
-<char *
-<savestr(cp)
-<	char *cp;
-<{
-<	register unsigned len;
-<	register char *dp;
-<
-<	len = strlen(cp);
-<	dp = (char *)calloc(len+1, sizeof (char));
-<	(void) strcpy(dp, cp);
-<	return (dp);
-<}
-<
  /*
!< * This routine was stolen from adb to simulate memory management
!< * on the VAX.
   */
-<off_t
-<vtophys(loc)
-<long	loc;
-<{
-<	register	p;
-<	off_t	newloc;
  
!<	newloc = loc & ~0xc0000000;
!<	p = btop(newloc);
!<	if ((loc & 0xc0000000) == 0) {
!<		fprintf(stderr, "Vtophys: translating non-kernel address\n");
!<		return((off_t) -1);
  	}
!<	if (p >= Syssize) {
!<		fprintf(stderr, "Vtophys: page out of bound (%d>=%d)\n",
!<			p, Syssize);
!<		return((off_t) -1);
  	}
-<	if (Sysmap[p].pg_v == 0
-<	&& (Sysmap[p].pg_fod || Sysmap[p].pg_pfnum == 0)) {
-<		fprintf(stderr, "Vtophys: page not valid\n");
-<		return((off_t) -1);
-<	}
-<	loc = (long) (ptob(Sysmap[p].pg_pfnum) + (loc & PGOFSET));
-<	return(loc);
-<}
  
!</*
!< * since we can't init unions, the cleanest way to use a.out.h instead
!< * of nlist.h (required since nlist() uses some defines) is to do a
!< * runtime copy into the nl array -- sigh
!< */
!<init_nlist()
  {
!<	register struct nlist *np;
!<	register char **namep;
  
-<	nllen = sizeof nl_names / sizeof (char *);
-<	np = nl = (struct nlist *) malloc(nllen * sizeof (struct nlist));
-<	if (np == NULL) {
-<		fprintf(stderr, "ps: out of memory allocating namelist\n");
-<		exit(1);
-<	}
-<	namep = &nl_names[0];
-<	while (nllen > 0) {
-<		np->n_un.n_name = *namep;
-<		if (**namep == '\0')
-<			break;
-<		namep++;
-<		np++;
-<	}
-<}
-<
  /*
!< * nlist - retreive attributes from name list (string table version)
!< * 	modified to add wait channels - Charles R. LaBrec 8/85
   */
-<nlist(name, list)
-<	char *name;
-<	struct nlist *list;
-<{
-<	register struct nlist *p, *q;
-<	register char *s1, *s2;
-<	register n, m;
-<	int maxlen, nreq;
-<	FILE *f;
-<	FILE *sf;
-<	off_t sa;		/* symbol address */
-<	off_t ss;		/* start of strings */
-<	int type;
-<	struct exec buf;
-<	struct nlist space[BUFSIZ/sizeof (struct nlist)];
-<	char nambuf[BUFSIZ];
  
!<	maxlen = 0;
!<	for (q = list, nreq = 0; q->n_un.n_name && q->n_un.n_name[0]; q++, nreq++) {
!<		q->n_type = 0;
!<		q->n_value = 0;
!<		q->n_desc = 0;
!<		q->n_other = 0;
!<		n = strlen(q->n_un.n_name);
!<		if (n > maxlen)
!<			maxlen = n;
!<	}
!<	f = fopen(name, "r");
!<	if (f == NULL)
!<		return (-1);
!<	fread((char *)&buf, sizeof buf, 1, f);
!<	if (N_BADMAG(buf)) {
!<		fclose(f);
!<		return (-1);
!<	}
!<	sf = fopen(name, "r");
!<	if (sf == NULL) {
!<		/* ??? */
!<		fclose(f);
!<		return(-1);
!<	}
!<	sa = N_SYMOFF(buf);
!<	ss = sa + buf.a_syms;
!<	n = buf.a_syms;
!<	fseek(f, sa, 0);
!<	while (n) {
!<		m = sizeof (space);
!<		if (n < m)
!<			m = n;
!<		if (fread((char *)space, m, 1, f) != 1)
!<			break;
!<		n -= m;
!<		for (q = space; (m -= sizeof(struct nlist)) >= 0; q++) {
!<			if (q->n_un.n_strx == 0 || q->n_type & N_STAB)
!<				continue;
!<			/*
!<			 * since we know what type of symbols we will get,
!<			 * we can make a quick check here -- crl
!<			 */
!<			type = q->n_type & (N_TYPE | N_EXT);
!<			if ((q->n_type & N_TYPE) != N_ABS
!<			    && type != (N_EXT | N_DATA)
!<			    && type != (N_EXT | N_BSS))
!<				continue;
!<			fseek(sf, ss+q->n_un.n_strx, 0);
!<			fread(nambuf, maxlen+1, 1, sf);
!<			/* if using wchans, add it to the list of channels */
!<			if (!nflg)
!<				addchan(&nambuf[1], (caddr_t) q->n_value);
!<			for (p = list; p->n_un.n_name && p->n_un.n_name[0]; p++) {
!<				s1 = p->n_un.n_name;
!<				s2 = nambuf;
!<				if (strcmp(p->n_un.n_name, nambuf) == 0) {
!<					p->n_value = q->n_value;
!<					p->n_type = q->n_type;
!<					p->n_desc = q->n_desc;
!<					p->n_other = q->n_other;
!<					--nreq;
!<					break;
!<				}
!<			}
!<		}
!<	}
!<alldone:
!<	fclose(f);
!<	fclose(sf);
!<	return (nreq);
!<}
  
!</*
!< * add the given channel to the channel list
!< */
!<addchan(name, caddr)
!<char *name;
!<caddr_t caddr;
!<{
!<	static int left = 0;
!<	register struct wchan *wp;
!<	register char **p;
  
!<	for (p = wchan_stop_list; *p; p++) {
!<		if (**p != *name)	/* quick check first */
  			continue;
!<		if (strncmp(name, *p, WNAMESIZ) == 0)
!<			return;		/* if found, don't add */
  	}
!<	if (left == 0) {
!<		if (wchanhd) {
!<			left = 100;
!<			wchanhd = (struct wchan *) realloc(wchanhd,
!<				(nchans + left) * sizeof (struct wchan));
!<		} else {
!<			left = 600;
!<			wchanhd = (struct wchan *) malloc(left
!<				* sizeof (struct wchan));
  		}
!<		if (wchanhd == NULL) {
!<			fprintf(stderr, "ps: out of memory allocating wait channels\n");
!<			nflg++;
!<			return;
  		}
  	}
-<	left--;
-<	wp = &wchanhd[nchans++];
-<	strncpy(wp->wc_name, name, WNAMESIZ);
-<	wp->wc_name[WNAMESIZ] = '\0';
-<	wp->wc_caddr = caddr;
-<}
  
!</*
!< * returns the symbolic wait channel corresponding to chan
!< */
  char *
!<getchan(chan)
!<register caddr_t chan;
  {
!<	register i, iend;
!<	register char *prevsym;
!<	register struct wchan *wp;
  
!<	prevsym = "???";		/* nothing, to begin with */
!<	if (chan) {
!<		for (i = 0; i < NWCINDEX; i++)
!<			if ((unsigned) chan < (unsigned) wchan_index[i])
!<				break;
!<		iend = i--;
!<		if (i < 0)		/* can't be found */
!<			return prevsym;
!<		iend *= nchans;
!<		iend /= NWCINDEX;
!<		i *= nchans;
!<		i /= NWCINDEX;
!<		wp = &wchanhd[i];
!<		for ( ; i < iend; i++, wp++) {
!<			if ((unsigned) wp->wc_caddr > (unsigned) chan)
!<				break;
!<			prevsym = wp->wc_name;
  		}
  	}
-<	return prevsym;
-<}
  
!</*
!< * used in sorting the wait channel array
!< */
!<int
!<wchancomp (w1, w2)
!<struct wchan *w1, *w2;
  {
!<	register unsigned c1, c2;
  
!<	c1 = (unsigned) w1->wc_caddr;
!<	c2 = (unsigned) w2->wc_caddr;
!<	if (c1 > c2)
!<		return 1;
!<	else if (c1 == c2)
!<		return 0;
!<	else
!<		return -1;
  }
---------------
  	return (vp->v_swrss + (ap->a_xccount ? 0 : vp->v_txtswrss));
  }
  
!>#define	NMAX	8	/* sizeof loginname (should be sizeof (utmp.ut_name)) */
!>#define NUID	2048	/* must not be a multiple of 5 */
  
!>struct nametable {
!>	char	nt_name[NMAX+1];
!>	int	nt_uid;
!>} nametable[NUID];
  
!>struct nametable *
!>findslot(uid)
!>unsigned short	uid;
  {
!>	register struct nametable	*n, *start;
  
  	/*
!>	 * find the uid or an empty slot.
!>	 * return NULL if neither found.
  	 */
  
!>	n = start = nametable + (uid % (NUID - 20));
!>	while (n->nt_name[0] && n->nt_uid != uid) {
!>		if ((n += 5) >= &nametable[NUID])
!>			n -= NUID;
!>		if (n == start)
!>			return((struct nametable *)NULL);
  	}
!>	return(n);
  }
  
!>char *
!>getname(uid)
  {
!>	register struct passwd		*pw;
!>	static				init = 0;
!>	struct passwd			*getpwent();
!>	register struct nametable	*n;
  
  	/*
!>	 * find uid in hashed table; add it if not found.
!>	 * return pointer to name.
  	 */
  
!>	if ((n = findslot(uid)) == NULL)
!>		return((char *)NULL);
  
!>	if (n->nt_name[0])	/* occupied? */
!>		return(n->nt_name);
  
!>	switch (init) {
!>		case 0:
!>			setpwent();
!>			init = 1;
!>			/* intentional fall-thru */
!>		case 1:
!>			while (pw = getpwent()) {
!>				if (pw->pw_uid < 0)
  					continue;
!>				if ((n = findslot(pw->pw_uid)) == NULL) {
!>					endpwent();
!>					init = 2;
!>					return((char *)NULL);
  				}
!>				if (n->nt_name[0])
!>					continue;	/* duplicate, not uid */
!>				strncpy(n->nt_name, pw->pw_name, NMAX);
!>				n->nt_uid = pw->pw_uid;
!>				if (pw->pw_uid == uid)
!>					return (n->nt_name);
  			}
!>			endpwent();
!>			init = 2;
!>			/* intentional fall-thru */
!>		case 2:
!>			return ((char *)NULL);
  	}
  }
  
!>char	*freebase;
!>int	nleft;
!>
  char *
!>alloc(size)
!>	int size;
  {
!>	register char *cp;
!>	register int i;
  
!>#ifdef sun
!>	/* 68000 can only address words on even boundaries */
!>	size = (size+1)&~1;
!>#else sun
!>#ifdef vax
!>	/* the vax has no problem */
!>#else vax
!>	put your machine dependent code here
!>#endif vax
!>#endif sun
!>	if (size > nleft) {
!>		freebase = (char *)sbrk((int)(i = size > 2048 ? size : 2048));
!>		if (freebase == (char *)-1) {
!>			fprintf(stderr, "ps: ran out of memory\n");
!>			exit(1);
  		}
+>		nleft = i - size;
+>	} else
+>		nleft -= size;
+>	cp = freebase;
+>	for (i = size; --i >= 0; )
+>		*cp++ = 0;
+>	freebase = cp;
+>	return (cp - size);
  }
  
!>char *
!>savestr(cp)
!>	char *cp;
  {
!>	register int len;
!>	register char *dp;
  
!>	len = strlen(cp);
!>	dp = (char *)alloc(len+1);
!>	(void) strcpy(dp, cp);
!>	return (dp);
  }