* This is the augmented UCB ps for UCB/VM Unix (9/79)
* examine and print certain things about processes
* usage: ps [acgklrt#uvwx] [corefile] [swapfile] [system]
#define INTPPG (NBPG/sizeof(int)) /* ints per page */
#define clear(x) ((int)x & 0x7fffffff)
int aflg
; /* -a: all processes, not just mine */
int cflg
; /* -c: complete listing of args, not just comm. */
int gflg
; /* -g: complete listing including group headers, etc */
int kflg
; /* -k: read from core file instead of real memory */
int lflg
; /* -l: long listing form */
int rflg
; /* -r: raw output in style <psout.h> */
int sflg
; /* -s: stack depth */
int uflg
; /* -u: user name */
int vflg
; /* -v: virtual memory statistics */
int wflg
; /* -w[w]: wide terminal */
int xflg
; /* -x: ALL processes, even those without ttys */
int login
; /* -: this is a login shell */
struct pte pagetbl
[NPTEPG
];
struct psout outargs
[NPROC
]; /* info for first npr processes */
int npr
; /* number of processes found so far */
int argwidth
; /* number of chars of args to print */
register struct nlist
*nlp
;
while (*ap
) switch (*ap
++) {
coref
= argc
> 1 ? argv
[1] : "/vmcore";
if ((kmem
= open(coref
, 0)) < 0) {
if ((mem
= open("/dev/mem", 0)) < 0) {
fprintf(stderr
, "No mem\n");
if ((swap
= open(argc
>2 ? argv
[2]: "/dev/drum", 0)) < 0) {
fprintf(stderr
, "Can't open /dev/drum\n");
nlist(argc
>3 ? argv
[3] : "/vmunix", nl
);
fprintf(stderr
, "No namelist\n");
fprintf(stderr
, "Can't change to /dev\n");
for (nlp
= nl
; nlp
< &nl
[sizeof (nl
)/sizeof (nl
[0])]; nlp
++)
nlp
->n_value
&= 0x7ffffffff;
Usrptma
= nl
[X_USRPTMA
].n_value
;
usrpt
= nl
[X_USRPT
].n_value
;
* read kmem to find swap dev.
lseek(kmem
, (long)nl
[X_SWAPDEV
].n_value
, 0);
read(kmem
, &nl
[X_SWAPDEV
].n_value
, sizeof(nl
[X_SWAPDEV
].n_value
));
* Find base and size of swap
lseek(kmem
, (long)nl
[X_SWPLO
].n_value
, 0);
read(kmem
, &swplo
, sizeof(swplo
));
lseek(kmem
, (long)nl
[X_NSWAP
].n_value
, 0);
read(kmem
, &nswap
, sizeof (nswap
));
* If v flag get text table
lseek(kmem
, (long)nl
[X_TEXT
].n_value
, 0);
read(kmem
, text
, sizeof (text
));
if (sflg
+ lflg
+ vflg
+ uflg
> 1) {
printf("Cannot combine s, l, v, and/or u.\n");
/* different psout widths depending on how much printed & w flag */
if (wflg
) argwidth
+= 52; /* 132 col term */
if (lflg
) argwidth
-= 49; /* extra junk printed */
if (vflg
) argwidth
-= 48; /* extra junk for -v */
if (sflg
) argwidth
-= 4; /* 4 cols of stack size */
if (uflg
) argwidth
-= 27; /* user name */
; /* No heading for raw output */
printf(" F S UID PID PPID CPU PRI NICE ADDR SZ RSS WCHAN TTY TIME COMMAND\n");
printf("F PID TT TIME TIM SL MINFLT MAJFLT SIZE RSS SRS TSIZ TRS PF COMMAND\n");
printf("USER PID %%CPU NICE SZ RSS TTY TIME COMMAND\n");
printf(" PID TTY TIME COMMAND\n");
for (i
=0; i
<NPROC
; i
++) {
lseek(kmem
, (long)(nl
[X_PROC
].n_value
+i
*(sizeof mproc
)), 0);
read(kmem
, &mproc
, sizeof mproc
);
/* skip processes that don't exist */
/* skip those without a tty unless -x */
if (mproc
.p_pgrp
==0 && xflg
==0)
/* skip group leaders on a tty unless -g, -x, or -t.. */
if (!gflg
&& !xflg
&& !tptr
&& mproc
.p_pid
== mproc
.p_pgrp
)
/* -g also skips those where **argv is "-" - see savcom */
/* skip other peoples processes unless -a or a specific pid */
if ((uid
!= puid
&& aflg
==0) ||
(chkpid
!=0 && chkpid
!=mproc
.p_pid
))
if (prcom(&outargs
[i
])) {
if ((df
= fopen("/dev", "r")) == NULL
) {
fprintf(stderr
, "Can't open /dev\n");
while (fread(&dbuf
, sizeof(dbuf
), 1, df
) == 1) {
if(stat(dbuf
.d_name
, &sbuf
) < 0)
if ((sbuf
.st_mode
&S_IFMT
) != S_IFCHR
)
strcpy(devl
[ndev
].dname
, dbuf
.d_name
);
devl
[ndev
].dev
= sbuf
.st_rdev
;
register struct psout
*a
;
/* skip long sleeping or dead processes if -v unless -g or -x */
if (!gflg
&& vflg
&& !xflg
) {
if (mproc
.p_slptime
> MAXSLP
)
/* read in the user structure */
if ((mproc
.p_flag
& SLOAD
) == 0) {
/* not loaded - get from swap */
addr
= (mproc
.p_swaddr
+swplo
)<<9;
if (read(swap
, &u
, sizeof(u
)) != sizeof(u
))
/* loaded, get each page from memory separately */
for(cc
=0; cc
<UPAGES
; cc
++) { /* get u area */
int upage
= ctob(mproc
.p_addr
[cc
]);
if (read(mem
,((int *)&u
)+INTPPG
*cc
,NBPG
) != NBPG
)
if (tptr
&& strcmpn(tptr
, tp
, 2))
/* saving com starts here */
a
->o_flag
= mproc
.p_flag
;
a
->o_ppid
= mproc
.p_ppid
;
a
->o_pctcpu
= 0.0; /* This needs to be fixed later */
a
->o_nice
= mproc
.p_nice
;
a
->o_addr0
= mproc
.p_addr
[0];
a
->o_dsize
= mproc
.p_dsize
;
a
->o_ssize
= mproc
.p_ssize
;
a
->o_rssize
= mproc
.p_rssize
;
a
->o_swrss
= mproc
.p_swrss
;
a
->o_wchan
= mproc
.p_wchan
;
a
->o_pgrp
= mproc
.p_pgrp
;
a
->o_tty
[1] = tp
[1] ? tp
[1] : ' ';
a
->o_stat
= mproc
.p_stat
;
a
->o_flag
= mproc
.p_flag
;
if (a
->o_stat
==SZOMB
) return(1);
a
->o_cutime
= u
.u_cutime
;
a
->o_cstime
= u
.u_cstime
;
a
->o_sigs
= u
.u_signal
[SIGINT
] + u
.u_signal
[SIGQUIT
];
a
->o_time
= mproc
.p_time
;
a
->o_slptime
= mproc
.p_slptime
;
for (cp
= (char *)u
.u_stack
; cp
< (char *)&u
+ ctob(UPAGES
); cp
++)
a
->o_stksize
= (int) ((char *)&u
+ ctob(UPAGES
) - cp
);
if (mproc
.p_stat
==SZOMB
) return(1);
register struct text
*xp
;
xp
= &text
[mproc
.p_textp
- (struct text
*)nl
[5].n_value
];
a
->o_xrssize
= xp
->x_rssize
;
a
->o_aveflt
= mproc
.p_aveflt
;
a
->o_minorflt
= u
.u_minorflt
;
a
->o_majorflt
= u
.u_majorflt
;
strcpy(a
->o_comm
, u
.u_comm
);
a
->o_args
[0] = 0; /* in case of early return */
if ((mproc
.p_flag
& SLOAD
) == 0) {
vstodb(0, 1, &u
.u_smap
, &db
, 1);
addr
= ctob(swplo
+ db
.db_base
);
if (read(swap
, abuf
, sizeof(abuf
)) != sizeof(abuf
))
p0br
= kflg
? clear((int)mproc
.p_p0br
) : (int)mproc
.p_p0br
;
cc
= Usrptma
+ (p0br
+ NBPG
*(szpt
-1) - usrpt
)/NPTEPG
;
if (read(kmem
, &apte
, sizeof(apte
)) != sizeof(apte
))
lseek(mem
, ctob(apte
.pg_pfnum
), 0);
if (read(mem
,pagetbl
,sizeof(pagetbl
)) != sizeof(pagetbl
))
if (pagetbl
[NPTEPG
-1].pg_fod
== 0 && pagetbl
[NPTEPG
-1].pg_pfnum
) {
lseek(mem
,ctob((pagetbl
[NPTEPG
-1].pg_pfnum
)),0);
if (read(mem
,abuf
,sizeof(abuf
)) != sizeof(abuf
))
vstodb(0, 1, &u
.u_smap
, &db
, 1);
addr
= ctob(swplo
+ db
.db_base
);
if (read(swap
, abuf
, sizeof(abuf
)) != sizeof(abuf
))
for (ip
= &abuf
[INTPPG
-2]; ip
> abuf
;) {
if (*--ip
== -1 || *ip
== 0) {
for (cp1
= cp
; cp1
< (char *)&abuf
[INTPPG
]; cp1
++) {
else if (cc
< ' ' || cc
> 0176) {
while (cp1
>cp
&& *--cp1
!=' ')
if (cp
[0]=='-'&&cp
[1]<=' ' || cp
[0]=='?' || cp
[0]<=' ') {
cp
[127] = 0; /* max room in psout is 128 chars */
if (xflg
|| gflg
|| tptr
|| cp
[0]!='-')
register struct psout
*a
;
write(1, a
, sizeof (*a
));
printf("%4x %c", 0xffff & a
->o_flag
,
if ((a
->o_flag
& SLOAD
) == 0)
else if (a
->o_pri
>= PZERO
)
else if (a
->o_flag
& SPAGE
)
printf("%-8.8s", a
->o_uname
);
printf("%5d", a
->o_stksize
);
printf("%6u%4d%4d%4d%6x", a
->o_ppid
, a
->o_cpu
&0377,
a
->o_pri
, a
->o_nice
, a
->o_addr0
);
printf("%5.1f%4d ", a
->o_pctcpu
, a
->o_nice
);
printf("%4d%5d", a
->o_dsize
+a
->o_ssize
, a
->o_rssize
);
printf("%6x", clear(a
->o_wchan
));
printf(" %-2.2s", a
->o_tty
);
tm
= (a
->o_utime
+ a
->o_stime
+ 30)/60;
printf(tm
<10?"0%ld":"%ld", tm
);
tm = (a->o_stime + 30) / 60;
printf(tm<10?"0%ld":"%ld", tm);
printf("%4d%3d", a
->o_time
, a
->o_slptime
);
if (0 && lflg
==0) { /* 0 == old tflg (print long times) */
tm
= (a
->o_cstime
+ 30)/60;
printf(tm
<10?"0%ld":"%ld", tm
);
tm
= (a
->o_cutime
+ 30)/60;
printf(tm
<10?"0%ld":"%ld", tm
);
printf("%7d%7d",a
->o_minorflt
,a
->o_majorflt
);
printf("%5d%4d%4d", a
->o_dsize
+a
->o_ssize
, a
->o_rssize
, a
->o_swrss
);
printf("%5d%4d", a
->o_xsize
, a
->o_xrssize
);
printf("%3d", a
->o_aveflt
);
printf(" %s", a
->o_comm
);
a
-> o_args
[argwidth
] = 0; /* force it to quit early */
printf(" %s", a
->o_args
);
if (devl
[i
].dev
== u
.u_ttyd
) {
if (p
[0]=='t' && p
[1]=='t' && p
[2]=='y')
* 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
);
printf("Press return when done: ");
* fixup figures out everybodys name and sorts into a nice order.
register struct passwd
*pw
;
struct passwd
*getpwent();
* If we want names, traverse the password file. For each
* passwd entry, look for it in the processes.
* In case of multiple entries in /etc/passwd, we believe
* the first one (same thing ls does).
while ((pw
=getpwent()) != NULL
) {
if (outargs
[i
].o_uid
== pw
-> pw_uid
) {
if (outargs
[i
].o_uname
[0] == 0)
strcpy(outargs
[i
].o_uname
, pw
-> pw_name
);
qsort(outargs
, np
, sizeof(outargs
[0]), pscomp
);
pscomp(x1
, x2
) struct psout
*x1
, *x2
; {
c
= (x1
)->o_ttyd
- (x2
)->o_ttyd
;
if (c
==0) c
= (x1
)->o_pid
- (x2
)->o_pid
;