* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
"@(#) Copyright (c) 1980 Regents of the University of California.\n\
static char sccsid
[] = "@(#)ps.c 5.9 (Berkeley) %G%";
struct nlist
*nl
; /* all because we can't init unions */
int nllen
; /* # of nlist entries */
short a_stat
, a_uid
, a_pid
, a_nice
, a_pri
, a_slptime
, a_time
;
size_t a_size
, a_rss
, a_tsiz
, a_txtrss
;
int wcwidth
; /* width of the wchan field for sprintf*/
size_t v_swrss
, v_txtswrss
;
struct proc proc
[NPROC
]; /* a few, for less syscalls */
char upages
[UPAGES
][NBPG
];
char *psdb
= "/etc/psdatabase";
int aflg
, cflg
, eflg
, gflg
, kflg
, lflg
, nflg
, sflg
,
int nchans
; /* total # of wait channels */
char *gettty(), *getcmd(), *getname(), *savestr(), *state();
char *rindex(), *calloc(), *sbrk(), *strcpy(), *strcat(), *strncat();
char *strncpy(), *index(), *ttyname(), mytty
[MAXPATHLEN
+1];
char *malloc(), *getchan();
struct pte
*Usrptmap
, *usrpt
;
int cand
[16] = {-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1};
* 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.
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
[] = {
char *kmemf
, *memf
, *swapf
, *nlistf
;
int kmem
, mem
, swap
= -1;
#define pgtok(a) ((a)/(1024/NBPG))
if (ioctl(1, TIOCGWINSZ
, &win
) == -1)
twidth
= (win
.ws_col
== 0 ? 80 : win
.ws_col
);
while (*ap
) switch (*ap
++) {
else if ((tptr
= ttyname(0)) != 0) {
tptr
= strcpy(mytty
, tptr
);
if (strncmp(tptr
, "/dev/", 5) == 0)
if (strncmp(tptr
, "tty", 3) == 0)
if (tptr
&& *tptr
== '?')
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
*= sizeof (struct proc
);
if (read(kmem
, (char *)proc
, j
) != j
) {
cantread("proc table", kmemf
);
for (j
= j
/ sizeof (struct proc
) - 1; j
>= 0; j
--) {
if (mproc
->p_stat
== 0 ||
mproc
->p_pgrp
== 0 && xflg
== 0)
if (tptr
== 0 && gflg
== 0 && xflg
== 0 &&
if (uid
!= mproc
->p_uid
&& aflg
==0)
if (chkpid
!= -1 && chkpid
!= mproc
->p_pid
)
if (vflg
&& gflg
== 0 && xflg
== 0) {
if (mproc
->p_stat
== SZOMB
||
if (mproc
->p_slptime
> MAXSLP
&&
(mproc
->p_stat
== SSLEEP
||
width
= twidth
- cmdstart
- 2;
qsort((char *) savcom
, npr
, sizeof(savcom
[0]), pscomp
);
register struct savcom
*sp
= &savcom
[i
];
if (sp
->ap
->a_stat
== SZOMB
)
else if (sp
->ap
->a_flag
& SWEXIT
)
else if (sp
->ap
->a_pid
== 0)
else if (sp
->ap
->a_pid
== 2)
printf(" %.*s", twidth
- cmdstart
- 2, sp
->ap
->a_cmdp
);
klseek(kmem
, (long)loc
, 0);
if (read(kmem
, (char *)&word
, sizeof (word
)) != sizeof (word
))
printf("error reading kmem at %x\n", loc
);
if ((loc
= vtophys(loc
)) == -1)
(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 */
if ((fp
= fopen(psdb
, "w")) == NULL
) {
fchmod(fileno(fp
), 0644);
fwrite(thisversion
, sizeof thisversion
, 1, fp
);
fwrite(unixname
, strlen(unixname
) + 1, 1, fp
);
if (stat(unixname
, &stb
) < 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 *)<
->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
);
char dbversion
[sizeof thisversion
];
if ((fp
= fopen(psdb
, "r")) == NULL
) {
* Does the db file match this unix?
fread(dbversion
, sizeof dbversion
, 1, fp
);
if (bcmp(thisversion
, dbversion
, sizeof thisversion
))
while ((*p
= getc(fp
)) != '\0')
if (strcmp(unixname
, unamebuf
))
fread((char *) &dbmtime
, sizeof dbmtime
, 1, fp
);
if (stat(unixname
, &stb
) < 0)
if (stb
.st_mtime
!= dbmtime
)
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
);
fprintf(stderr
, "ps: Can't malloc space for tty table\n");
fread((char *) allttys
, sizeof (struct ttys
), nttys
, fp
);
fread((char *) &nchans
, sizeof nchans
, 1, fp
);
wchanhd
= (struct wchan
*) malloc(nchans
* sizeof (struct wchan
));
fprintf(stderr
, "ps: Can't malloc space for wait channels\n");
fseek(fp
, (long) nchans
* sizeof (struct wchan
), 1);
fread((char *) wchanhd
, sizeof (struct wchan
), nchans
, fp
);
fread((char *) wchan_index
, sizeof (caddr_t
), NWCINDEX
, fp
);
kmemf
= argc
> 2 ? argv
[2] : "/vmcore";
if (kflg
== 0 || argc
> 3) {
swapf
= argc
>3 ? argv
[3]: "/dev/drum";
int faildb
= 0; /* true if psdatabase init failed */
nlistf
= argc
> 1 ? argv
[1] : "/vmunix";
} else if (!readpsdb(nlistf
)) {
nl
[X_SYSMAP
].n_un
.n_name
= "";
fprintf(stderr
, "%s: No namelist\n", nlistf
);
/* We must do the sys map first because klseek uses it */
Syssize
= nl
[X_SYSSIZE
].n_value
;
calloc((unsigned) Syssize
, sizeof (struct pte
));
fprintf(stderr
, "Out of space for Sysmap\n");
addr
= (long) nl
[X_SYSMAP
].n_value
;
(void) lseek(kmem
, addr
, 0);
read(kmem
, (char *) Sysmap
, Syssize
* sizeof (struct pte
));
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
);
klseek(kmem
, (long)nl
[X_MAXSLP
].n_value
, 0);
if (read(kmem
, (char *)&maxslp
, sizeof (maxslp
)) != sizeof (maxslp
)) {
cantread("maxslp", kmemf
);
klseek(kmem
, (long)nl
[X_CCPU
].n_value
, 0);
if (read(kmem
, (char *)&ccpu
, sizeof (ccpu
)) != sizeof (ccpu
)) {
klseek(kmem
, (long)nl
[X_ECMX
].n_value
, 0);
if (read(kmem
, (char *)&ecmx
, sizeof (ecmx
)) != sizeof (ecmx
)) {
ntext
= getw(nl
[X_NTEXT
].n_value
);
calloc((unsigned) ntext
, sizeof (struct text
));
fprintf(stderr
, "no room for text table\n");
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
);
dmmin
= getw(nl
[X_DMMIN
].n_value
);
dmmax
= getw(nl
[X_DMMAX
].n_value
);
* get the valloc'ed kernel variables for symbolic wait channels
#define addv(i) addchan(&nl[i].n_un.n_name[1], getw(nl[i].n_value))
if (nl
[X_QUOTA
].n_value
!= 0) { /* these are #ifdef QUOTA */
qsort(wchanhd
, nchans
, sizeof (struct wchan
), wchancomp
);
for (i
= 0; i
< NWCINDEX
; i
++) {
wchan_index
[i
] = wchanhd
[tmp
/ NWCINDEX
].wc_caddr
;
if (sflg
+lflg
+vflg
+uflg
> 1) {
fprintf(stderr
, "ps: specify only one of s,l,v and u\n");
if ((hdr
= malloc(strlen(lhdr
) + WNAMESIZ
)) == NULL
) {
fprintf(stderr
, "ps: out of memory\n");
sprintf(hdr
, lhdr
, wcwidth
, "WCHAN");
/* 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");
sprintf(hdr
, uhdr
, nflg
? " UID" : "USER ");
if (lflg
+vflg
+uflg
+sflg
== 0)
printf("%s COMMAND\n", hdr
);
fprintf(stderr
, "ps: error reading %s from %s\n", what
, fromwhat
);
if ((df
= opendir(".")) == NULL
) {
fprintf(stderr
, "Can't open . in /dev\n");
while ((dbuf
= readdir(df
)) != NULL
)
allttys
= (struct ttys
*)malloc(sizeof(struct ttys
)*nttys
);
fprintf(stderr
, "ps: Can't malloc space for tty table\n");
for (lt
= lallttys
, t
= allttys
; lt
; lt
= lt
->next
, t
++)
* Attempt to avoid stats by guessing minor device
* numbers from tty names. Console is known,
* know that r(hp|up|mt) are unlikely as are different mem's,
* floppy, null, tty, etc.
register char *cp
= dbuf
->d_name
;
if (!strcmp(cp
, "console")) {
/* cu[la]? are possible!?! don't rule them out */
if (!strcmp(cp
, "floppy"))
#define is(a,b) cp[0] == 'a' && cp[1] == 'b'
if (is(h
,p
) || is(r
,a
) || is(u
,p
) || is(h
,k
)
if (isdigit(*cp
) && cp
[2] == 0)
if (cp
[0] == 'm' && cp
[1] == 'e' && cp
[2] == 'm' && cp
[3] == 0)
if (cp
[0] == 'm' && cp
[1] == 't')
if (!strncmp(cp
, "nrmt", 4))
if (cp
[1] && cp
[1] == 't' && cp
[2] == 'y')
if ((cp
[1] == 'a' || cp
[1] == 'p') && isdigit(cp
[2]) &&
cp
= dbuf
->d_name
+ dbuf
->d_namlen
- 1;
if (stat("ttyd0", &stb
) == 0)
dialbase
= stb
.st_rdev
& 017;
if (cp
> dbuf
->d_name
&& isdigit(cp
[-1]) && isdigit(*cp
))
x
+= 10 * (cp
[-1] - ' ') + cp
[0] - '0';
else if (*cp
>= 'a' && *cp
<= 'f')
dp
= (struct lttys
*)malloc(sizeof(struct lttys
));
fprintf(stderr
, "ps: Can't malloc space for tty table\n");
(void) strcpy(dp
->ttys
.name
, dbuf
->d_name
);
if (stat(dp
->ttys
.name
, &stb
) == 0 &&
(stb
.st_mode
&S_IFMT
)==S_IFCHR
)
dp
->ttys
.ttyd
= x
= stb
.st_rdev
;
register struct ttys
*dp
;
for (dp
= &allttys
[cand
[x
]]; dp
!= &allttys
[-1];
dp
= &allttys
[dp
->cand
]) {
if (stat(dp
->name
, &stb
) == 0 &&
(stb
.st_mode
&S_IFMT
)==S_IFCHR
)
if (dp
->ttyd
== u
.u_ttyd
)
for (dp
= allttys
; dp
< &allttys
[nttys
]; dp
++) {
if (stat(dp
->name
, &stb
) == 0 &&
(stb
.st_mode
&S_IFMT
)==S_IFCHR
)
if (dp
->ttyd
== u
.u_ttyd
)
if (p
[0]=='t' && p
[1]=='t' && p
[2]=='y')
register struct savcom
*sp
;
register struct asav
*ap
;
register struct text
*xp
;
if (mproc
->p_stat
!= SZOMB
&& getu() == 0)
if (xflg
== 0 && ttyp
[0] == '?' || tptr
&& strncmp(tptr
, ttyp
, 2))
sp
->ap
= ap
= (struct asav
*)calloc(1, sizeof (struct asav
));
#define e(a,b) ap->a = mproc->b
e(a_flag
, p_flag
); e(a_stat
, p_stat
); e(a_nice
, p_nice
);
e(a_uid
, p_uid
); e(a_pid
, p_pid
); e(a_pri
, p_pri
);
e(a_slptime
, p_slptime
); e(a_time
, p_time
);
ap
->a_tty
[1] = ttyp
[1] ? ttyp
[1] : ' ';
if (ap
->a_stat
== SZOMB
) {
ap
->a_size
= mproc
->p_dsize
+ mproc
->p_ssize
;
ap
->a_cpu
= u
.u_ru
.ru_utime
.tv_sec
+ u
.u_ru
.ru_stime
.tv_sec
;
ap
->a_cpu
+= u
.u_cru
.ru_utime
.tv_sec
+ u
.u_cru
.ru_stime
.tv_sec
;
if (mproc
->p_textp
&& text
) {
xp
= &text
[mproc
->p_textp
- atext
];
ap
->a_txtrss
= xp
->x_rssize
;
ap
->a_xccount
= xp
->x_ccount
;
ap
->a_maxrss
= mproc
->p_maxrss
;
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
);
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
) {
vp
->v_majflt
= u
.u_ru
.ru_majflt
;
vp
->v_txtswrss
= xp
->x_swrss
;
sp
->s_un
.u_pctcpu
= pcpu();
if (ap
->a_stat
!= SZOMB
) {
for (cp
= (char *)u
.u_stack
;
cp
< &user
.upages
[UPAGES
][0]; )
sp
->s_un
.s_ssiz
= (&user
.upages
[UPAGES
][0] - cp
);
register struct asav
*ap
;
if ((ap
->a_flag
&SLOAD
) == 0)
szptudot
= UPAGES
+ clrnd(ctopt(ap
->a_size
+ap
->a_tsiz
));
fracmem
= ((float)ap
->a_rss
+szptudot
)/CLSIZE
/ecmx
;
fracmem
+= ((float)ap
->a_txtrss
)/CLSIZE
/
return (100.0 * fracmem
);
if (time
== 0 || (mproc
->p_flag
&SLOAD
) == 0)
return (100.0 * mproc
->p_pctcpu
);
return (100.0 * mproc
->p_pctcpu
/ (1.0 - exp(time
* log(ccpu
))));
struct pte
*pteaddr
, apte
;
struct pte arguutl
[UPAGES
+CLSIZE
];
size
= sflg
? ctob(UPAGES
) : sizeof (struct user
);
if ((mproc
->p_flag
& SLOAD
) == 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",
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",
(long)ctob(apte
.pg_pfnum
+1) - (UPAGES
+CLSIZE
) * sizeof (struct pte
),
if (read(mem
, (char *)arguutl
, sizeof(arguutl
)) != sizeof(arguutl
)) {
printf("ps: cant read page table for u of pid %d from %s\n",
if (arguutl
[0].pg_fod
== 0 && arguutl
[0].pg_pfnum
)
argaddr
= ctob(arguutl
[0].pg_pfnum
);
pcbpf
= arguutl
[CLSIZE
].pg_pfnum
;
ncl
= (size
+ NBPG
*CLSIZE
- 1) / (NBPG
*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
);
char cmdbuf
[CLSIZE
*NBPG
];
int argi
[CLSIZE
*NBPG
/sizeof (int)];
if (mproc
->p_stat
== SZOMB
|| mproc
->p_flag
&(SSYS
|SWEXIT
))
(void) strncpy(cmdbuf
, u
.u_comm
, sizeof (u
.u_comm
));
return (savestr(cmdbuf
));
if ((mproc
->p_flag
& SLOAD
) == 0 || argaddr
== 0) {
vstodb(0, CLSIZE
, &u
.u_smap
, &db
, 1);
(void) lseek(swap
, (long)dtob(db
.db_base
), 0);
if (read(swap
, (char *)&argspac
, sizeof(argspac
))
lseek(mem
, (long)argaddr
, 0);
if (read(mem
, (char *)&argspac
, sizeof (argspac
))
ip
= &argspac
.argi
[CLSIZE
*NBPG
/sizeof (int)];
ip
-= 2; /* last arg word and .long 0 */
for (cp
= (char *)ip
; cp
< &argspac
.argc
[CLSIZE
*NBPG
]; cp
++) {
else if (c
< ' ' || c
> 0176) {
if (++nbad
>= 5*(eflg
+1)) {
} else if (eflg
== 0 && c
== '=') {
(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
));
fprintf(stderr
, "ps: error locating command name for pid %d from %s\n",
(void) strcpy(cmdbuf
, " (");
(void) strncat(cmdbuf
, u
.u_comm
, sizeof (u
.u_comm
));
(void) strcat(cmdbuf
, ")");
return (savestr(cmdbuf
));
" F UID PID PPID CP PRI NI ADDR SZ RSS %*s STAT TT TIME";
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_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(" %*s", wcwidth
, "");
printf(" %*x", wcwidth
, (int)lp
->l_wchan
&0xffffff);
printf(" %*.*s", wcwidth
, abs(wcwidth
), getchan(lp
->l_wchan
));
printf(" %4.4s ", state(ap
));
printf("%3ld:%02ld", ap
->a_cpu
/ 60, ap
->a_cpu
% 60);
"%s PID %%CPU %%MEM SZ RSS TT STAT TIME";
register struct asav
*ap
= sp
->ap
;
vmsize
= pgtok((ap
->a_size
+ ap
->a_tsiz
));
rmsize
= pgtok(ap
->a_rss
);
rmsize
+= pgtok(ap
->a_txtrss
/ap
->a_xccount
);
printf("%4d ", ap
->a_uid
);
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
);
printf(" %4.4s", state(ap
));
" SIZE PID TT STAT TIME SL RE PAGEIN SIZE RSS LIM TSIZ TRS %CPU %MEM"+5;
register struct vsav
*vp
= sp
->s_un
.vp
;
register struct asav
*ap
= sp
->ap
;
printf("%5u ", ap
->a_pid
);
printf(" %4.4s", state(ap
));
printf("%3d%3d%7d%5d%5d",
ap
->a_slptime
> 99 ? 99 : ap
-> a_slptime
,
ap
->a_time
> 99 ? 99 : ap
->a_time
, vp
->v_majflt
,
pgtok(ap
->a_size
), pgtok(ap
->a_rss
));
if (ap
->a_maxrss
== (RLIM_INFINITY
/NBPG
))
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
));
register struct asav
*ap
= sp
->ap
;
printf("%4d ", sp
->s_un
.s_ssiz
);
printf("%5u", ap
->a_pid
);
printf(" %4.4s", state(ap
));
register struct asav
*ap
;
char stat
, load
, nice
, anom
;
if (ap
->a_slptime
>= MAXSLP
)
else if (ap
->a_flag
& SPAGE
)
load
= ap
->a_flag
& SLOAD
? (ap
->a_rss
>ap
->a_maxrss
? '>' : ' ') : 'W';
else if (ap
->a_nice
> NZERO
)
anom
= (ap
->a_flag
&SUANOM
) ? 'A' : ((ap
->a_flag
&SSEQL
) ? 'S' : ' ');
res
[0] = stat
; res
[1] = load
; res
[2] = nice
; res
[3] = anom
;
* Given a base/size pair in virtual swap area,
* return a physical base/size pair which is the
* (largest) initial, physically contiguous block.
vstodb(vsbase
, vssize
, dmp
, dbp
, rev
)
register struct dblock
*dbp
;
register int blk
= dmmin
;
register swblk_t
*ip
= dmp
->dm_map
;
if (vsbase
< 0 || vsbase
+ vssize
> dmp
->dm_size
)
if (*ip
<= 0 || *ip
+ blk
> nswap
)
dbp
->db_size
= min(vssize
, blk
- vsbase
);
dbp
->db_base
= *ip
+ (rev
? blk
- (vsbase
+ dbp
->db_size
) : vsbase
);
return (s2
->s_un
.u_pctcpu
> s1
->s_un
.u_pctcpu
? 1 : -1);
return (vsize(s2
) - vsize(s1
));
i
= s1
->ap
->a_ttyd
- s2
->ap
->a_ttyd
;
i
= s1
->ap
->a_pid
- s2
->ap
->a_pid
;
register struct asav
*ap
= sp
->ap
;
register struct vsav
*vp
= sp
->s_un
.vp
;
ap
->a_txtrss
/ (ap
->a_xccount
? ap
->a_xccount
: 1));
return (vp
->v_swrss
+ (ap
->a_xccount
? 0 : vp
->v_txtswrss
));
#define NMAX (sizeof (utmp.ut_name))
#define SCPYN(a, b) strncpy(a, b, NMAX)
* This function assumes that the password file is hashed
* (or some such) to allow fast access based on a uid key.
register struct passwd
*pw
;
struct passwd
*getpwent();
#if (((NUID) & ((NUID) - 1)) != 0)
if (uid
>= 0 && nc
[cp
].uid
== uid
&& nc
[cp
].name
[0])
SCPYN(nc
[cp
].name
, pw
->pw_name
);
dp
= (char *)calloc(len
+1, sizeof (char));
* This routine was stolen from adb to simulate memory management
newloc
= loc
& ~0xc0000000;
if ((loc
& 0xc0000000) == 0) {
fprintf(stderr
, "Vtophys: translating non-kernel address\n");
fprintf(stderr
, "Vtophys: page out of bound (%d>=%d)\n",
&& (Sysmap
[p
].pg_fod
|| Sysmap
[p
].pg_pfnum
== 0)) {
fprintf(stderr
, "Vtophys: page not valid\n");
loc
= (long) (ptob(Sysmap
[p
].pg_pfnum
) + (loc
& PGOFSET
));
* 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
register struct nlist
*np
;
nllen
= sizeof nl_names
/ sizeof (char *);
np
= nl
= (struct nlist
*) malloc(nllen
* sizeof (struct nlist
));
fprintf(stderr
, "ps: out of memory allocating namelist\n");
np
->n_un
.n_name
= *namep
;
* nlist - retreive attributes from name list (string table version)
* modified to add wait channels - Charles R. LaBrec 8/85
register struct nlist
*p
, *q
;
off_t sa
; /* symbol address */
off_t ss
; /* start of strings */
struct nlist space
[BUFSIZ
/sizeof (struct nlist
)];
for (q
= list
, nreq
= 0; q
->n_un
.n_name
&& q
->n_un
.n_name
[0]; q
++, nreq
++) {
n
= strlen(q
->n_un
.n_name
);
fread((char *)&buf
, sizeof buf
, 1, f
);
if (fread((char *)space
, m
, 1, f
) != 1)
for (q
= space
; (m
-= sizeof(struct nlist
)) >= 0; q
++) {
if (q
->n_un
.n_strx
== 0 || q
->n_type
& N_STAB
)
* 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
))
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 */
addchan(&nambuf
[1], (caddr_t
) q
->n_value
);
for (p
= list
; p
->n_un
.n_name
&& p
->n_un
.n_name
[0]; p
++) {
if (strcmp(p
->n_un
.n_name
, nambuf
) == 0) {
* add the given channel to the channel list
register struct wchan
*wp
;
for (p
= wchan_stop_list
; *p
; p
++) {
if (**p
!= *name
) /* quick check first */
if (strncmp(name
, *p
, WNAMESIZ
) == 0)
return; /* if found, don't add */
wchanhd
= (struct wchan
*) realloc(wchanhd
,
(nchans
+ left
) * sizeof (struct wchan
));
wchanhd
= (struct wchan
*) malloc(left
* sizeof (struct wchan
));
fprintf(stderr
, "ps: out of memory allocating wait channels\n");
strncpy(wp
->wc_name
, name
, WNAMESIZ
);
wp
->wc_name
[WNAMESIZ
] = '\0';
* returns the symbolic wait channel corresponding to chan
register struct wchan
*wp
;
prevsym
= "???"; /* nothing, to begin with */
for (i
= 0; i
< NWCINDEX
; i
++)
if ((unsigned) chan
< (unsigned) wchan_index
[i
])
if (i
< 0) /* can't be found */
for ( ; i
< iend
; i
++, wp
++) {
if ((unsigned) wp
->wc_caddr
> (unsigned) chan
)
* used in sorting the wait channel array
register unsigned c1
, c2
;
c1
= (unsigned) w1
->wc_caddr
;
c2
= (unsigned) w2
->wc_caddr
;