* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#ifndef lint
#endif /* not lint */
#ifndef lint
-static char sccsid[] = "@(#)ps.c 5.32 (Berkeley) %G%";
+static char sccsid[] = "@(#)ps.c 5.43 (Berkeley) 7/1/91";
#endif /* not lint */
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/kinfo.h>
+#include <nlist.h>
#include <kvm.h>
#include <errno.h>
#include <unistd.h>
-#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <paths.h>
#include "ps.h"
+#ifdef SPPWAIT
+#define NEWVM
+#endif
+
KINFO *kinfo;
-VAR *vhead, *vtail;
+struct varent *vhead, *vtail;
int eval; /* exit value */
int rawcpu; /* -C */
static int needuser, needcomm;
-enum sort { SORTMEM, SORTCPU } sortby;
+enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT;
uid_t getuid();
char *ttyname();
-#define DFMT "pid tt state time command"
-#define JFMT "user pid ppid pgid sess jobc state tt time command"
-#define LFMT \
- "uid pid ppid cpu pri nice vsz rss wchan state tt time command"
-#define SFMT "uid pid sig sigmask sigignore sigcatch state tt command"
-#define UFMT \
- "user pid %cpu %mem vsz rss tt state start time command"
-#define VFMT \
- "pid tt state time sl re pagein vsz rss lim tsiz trs %cpu %mem command"
+char dfmt[] = "pid tt state time command";
+char jfmt[] = "user pid ppid pgid sess jobc state tt time command";
+char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command";
+char o1[] = "pid";
+char o2[] = "tt state time command";
+char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command";
+char vfmt[] =
+ "pid state time sl re pagein vsz rss lim tsiz trs %cpu %mem command";
main(argc, argv)
int argc;
extern int optind;
register struct proc *p;
register size_t nentries;
- register VAR *v;
+ register struct varent *vent;
register int i;
struct winsize ws;
dev_t ttydev;
int all, ch, flag, fmt, lineno, pid, prtheader, uid, what, xflg;
int pscomp();
+ char *nlistf, *memf, *swapf;
char *kludge_oldps_options();
if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, (char *)&ws) == -1 &&
all = xflg = 0;
pid = uid = -1;
ttydev = NODEV;
- while ((ch = getopt(argc, argv, "aCghjLlmO:o:p:rSsTt:uvwx")) != EOF)
+ memf = nlistf = swapf = NULL;
+ while ((ch = getopt(argc, argv,
+ "aCghjLlM:mN:O:o:p:rSTt:uvW:wx")) != EOF)
switch((char)ch) {
case 'a':
all = 1;
prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
break;
case 'j':
- parsefmt(JFMT);
+ parsefmt(jfmt);
fmt = 1;
+ jfmt[0] = '\0';
break;
case 'L':
showkey();
exit(0);
case 'l':
- parsefmt(LFMT);
+ parsefmt(lfmt);
fmt = 1;
+ lfmt[0] = '\0';
+ break;
+ case 'M':
+ memf = optarg;
break;
case 'm':
sortby = SORTMEM;
break;
+ case 'N':
+ nlistf = optarg;
+ break;
case 'O':
- parsefmt("pid");
+ parsefmt(o1);
parsefmt(optarg);
- parsefmt("tt state time command");
+ parsefmt(o2);
+ o1[0] = o2[0] = '\0';
fmt = 1;
break;
case 'o':
case 'S':
sumrusage = 1;
break;
- case 's':
- parsefmt(SFMT);
- fmt = 1;
- break;
case 'T':
if ((optarg = ttyname(STDIN_FILENO)) == NULL)
- error("stdin: not a terminal");
+ err("stdin: not a terminal");
/* FALLTHROUGH */
case 't': {
char *ttypath;
_PATH_TTY, optarg);
else
ttypath = optarg;
- if (stat(ttypath, &stbuf) == -1) {
- (void)fprintf(stderr,
- "ps: %s: %s\n", strerror(ttypath));
- exit(1);
- }
+ if (stat(ttypath, &stbuf) == -1)
+ err("%s: %s", ttypath, strerror(errno));
if (!S_ISCHR(stbuf.st_mode))
- error("%s: not a terminal", ttypath);
+ err("%s: not a terminal", ttypath);
ttydev = stbuf.st_rdev;
break;
}
case 'u':
- parsefmt(UFMT);
+ parsefmt(ufmt);
sortby = SORTCPU;
fmt = 1;
+ ufmt[0] = '\0';
break;
case 'v':
- parsefmt(VFMT);
+ parsefmt(vfmt);
sortby = SORTMEM;
fmt = 1;
+ vfmt[0] = '\0';
+ break;
+ case 'W':
+ swapf = optarg;
break;
case 'w':
if (termwidth < 131)
argc -= optind;
argv += optind;
+#define BACKWARD_COMPATIBILITY
+#ifdef BACKWARD_COMPATIBILITY
if (*argv) {
- char *nlistf, *memf = NULL, *swapf = NULL;
- nlistf = *argv++;
- if (*argv) {
- memf = *argv++;
- if (*argv)
- swapf = *argv++;
+ nlistf = *argv;
+ if (*++argv) {
+ memf = *argv;
+ if (*++argv)
+ swapf = *argv;
}
- if (kvm_openfiles(nlistf, memf, swapf) == -1)
- error("kvm_openfiles: %s", kvm_geterr());
}
+#endif
+ if (kvm_openfiles(nlistf, memf, swapf) == -1)
+ err("kvm_openfiles: %s", kvm_geterr());
if (!fmt)
- parsefmt(DFMT);
+ parsefmt(dfmt);
if (!all && ttydev == NODEV && pid == -1) /* XXX - should be cleaner */
uid = getuid();
} else if (pid != -1) {
what = KINFO_PROC_PID;
flag = pid;
+ } else
+ what = KINFO_PROC_ALL;
/*
* select procs
*/
- if ((nentries = kvm_getprocs(what, flag)) == -1) {
- (void) fprintf(stderr, "ps: %s\n", kvm_geterr());
- exit(1);
- }
- kinfo = (KINFO *)malloc(nentries * sizeof(KINFO));
- if (kinfo == NULL) {
- (void)fprintf(stderr, "ps: %s\n", strerror(ENOMEM));
- exit(1);
- }
+ if ((nentries = kvm_getprocs(what, flag)) == -1)
+ err("%s", kvm_geterr());
+ kinfo = malloc(nentries * sizeof(KINFO));
+ if (kinfo == NULL)
+ err("%s", strerror(errno));
for (nentries = 0; p = kvm_nextproc(); ++nentries) {
kinfo[nentries].ki_p = p;
kinfo[nentries].ki_e = kvm_geteproc(p);
if (xflg == 0 && (kinfo[i].ki_e->e_tdev == NODEV ||
(kinfo[i].ki_p->p_flag & SCTTY ) == 0))
continue;
- for (v = vhead; v; v = v->next) {
- (*v->oproc)(&kinfo[i], v);
- if (v->next != NULL)
+ for (vent = vhead; vent; vent = vent->next) {
+ (*vent->var->oproc)(&kinfo[i], vent->var, vent->next);
+ if (vent->next != NULL)
(void) putchar(' ');
}
(void) putchar('\n');
scanvars()
{
+ register struct varent *vent;
register VAR *v;
register int i;
- for (v = vhead; v; v = v->next) {
+ for (vent = vhead; vent; vent = vent->next) {
+ v = vent->var;
i = strlen(v->header);
if (v->width < i)
v->width = i;
register struct usave *usp;
register struct user *up;
- if ((usp = (struct usave *)calloc(1, sizeof(struct usave))) == NULL) {
- (void)fprintf(stderr, "ps: %s\n", strerror(errno));
- exit(1);
- }
- ki->ki_u = usp;
+ if ((usp = calloc(1, sizeof(struct usave))) == NULL)
+ err("%s", strerror(errno));
up = kvm_getu(ki->ki_p);
/*
* save arguments if needed
*/
ki->ki_args = needcomm ? strdup(kvm_getargs(ki->ki_p, up)) : NULL;
if (up != NULL) {
+ ki->ki_u = usp;
/*
* save important fields
*/
+#ifdef NEWVM
+ usp->u_start = up->u_stats.p_start;
+ usp->u_ru = up->u_stats.p_ru;
+ usp->u_cru = up->u_stats.p_cru;
+#else
usp->u_procp = up->u_procp;
usp->u_start = up->u_start;
usp->u_ru = up->u_ru;
usp->u_cru = up->u_cru;
usp->u_acflag = up->u_acflag;
- }
+#endif
+ } else
+ free(usp);
}
pscomp(k1, k2)
KINFO *k1, *k2;
{
int i;
+#ifdef NEWVM
+#define VSIZE(k) ((k)->ki_e->e_vm.vm_dsize + (k)->ki_e->e_vm.vm_ssize + \
+ (k)->ki_e->e_vm.vm_tsize)
+#else
#define VSIZE(k) ((k)->ki_p->p_dsize + (k)->ki_p->p_ssize + (k)->ki_e->e_xsize)
+#endif
if (sortby == SORTCPU)
return (getpcpu(k2) - getpcpu(k1));
char *newopts, *ns, *cp;
len = strlen(s);
- if ((newopts = ns = malloc(len + 2)) == NULL) {
- (void)fprintf(stderr, "ps: %s\n", strerror(errno));
- exit(1);
- }
+ if ((newopts = ns = malloc(len + 2)) == NULL)
+ err("%s", strerror(errno));
/*
* options begin with '-'
*/
return (newopts);
}
-#ifdef lint
-/* VARARGS1 */
-error(fmt) char *fmt; { (void) fputs(fmt, stderr); exit(1); /* NOTREACHED */ }
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(const char *fmt, ...)
#else
-error(fmt)
+err(fmt, va_alist)
char *fmt;
+ va_dcl
+#endif
{
va_list ap;
-
+#if __STDC__
va_start(ap, fmt);
- (void) fprintf(stderr, "ps: ");
- (void) vfprintf(stderr, fmt, ap);
- (void) fprintf(stderr, "\n");
+#else
+ va_start(ap);
+#endif
+ (void)fprintf(stderr, "ps: ");
+ (void)vfprintf(stderr, fmt, ap);
va_end(ap);
+ (void)fprintf(stderr, "\n");
exit(1);
+ /* NOTREACHED */
}
-#endif
usage()
{
(void) fprintf(stderr,
- "usage:\tps [ -aChjlmrSsTuvwx ] [ -O|o fmt ] [ -p pid ] [ -t tty ] [ system ] [ core ] [ swap ]\n\t ps [ -L ]\n");
+"usage: ps [-aChjlmrSTuvwx] [-O|o fmt] [-p pid] [-t tty]\n\t [-M core] [-N system] [-W swap]\n ps [-L]\n");
exit(1);
}