2009-10-22 01:11:57 +04:00
|
|
|
/* $NetBSD: ps.c,v 1.34 2009/10/21 21:12:07 rmind Exp $ */
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
/*-
|
|
|
|
* Copyright (c) 1999
|
|
|
|
* The NetBSD Foundation, Inc. All rights reserved.
|
|
|
|
*
|
|
|
|
* 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.
|
1999-12-16 07:41:49 +03:00
|
|
|
* 3. All advertising materials mentioning features or use of this software
|
|
|
|
* must display the following acknowledgement:
|
1999-12-20 22:31:47 +03:00
|
|
|
* This product includes software developed by the NetBSD Foundation.
|
|
|
|
* 4. Neither the name of the Foundation nor the names of its contributors
|
1999-02-22 00:48:07 +03:00
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX Notes XXX
|
|
|
|
* showps -- print data needed at each refresh
|
|
|
|
* fetchps -- get data used by mode (done at each refresh)
|
|
|
|
* labelps -- print labels (ie info not needing refreshing)
|
|
|
|
* initps -- prepare once-only data structures for mode
|
|
|
|
* openps -- prepare per-run information for mode, return window
|
|
|
|
* closeps -- close mode to prepare to switch modes
|
|
|
|
* cmdps -- optional, handle commands
|
|
|
|
*/
|
|
|
|
|
1999-04-22 07:40:46 +04:00
|
|
|
#include <sys/cdefs.h>
|
|
|
|
#ifndef lint
|
2009-10-22 01:11:57 +04:00
|
|
|
__RCSID("$NetBSD: ps.c,v 1.34 2009/10/21 21:12:07 rmind Exp $");
|
1999-04-22 07:40:46 +04:00
|
|
|
#endif /* not lint */
|
|
|
|
|
1999-02-22 00:48:07 +03:00
|
|
|
#include <sys/param.h>
|
2000-06-04 05:53:51 +04:00
|
|
|
#include <sys/sched.h>
|
1999-02-22 00:48:07 +03:00
|
|
|
#include <sys/sysctl.h>
|
|
|
|
#include <sys/user.h>
|
2000-12-01 05:19:43 +03:00
|
|
|
|
1999-02-22 00:48:07 +03:00
|
|
|
#include <curses.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <pwd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <tzfile.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
#include "systat.h"
|
2005-12-25 00:14:50 +03:00
|
|
|
#include "extern.h"
|
1999-02-22 00:48:07 +03:00
|
|
|
#include "ps.h"
|
|
|
|
|
2000-07-05 15:03:20 +04:00
|
|
|
int compare_pctcpu_noidle(const void *, const void *);
|
2002-05-04 22:44:27 +04:00
|
|
|
char *state2str(struct kinfo_proc2 *);
|
|
|
|
char *tty2str(struct kinfo_proc2 *);
|
|
|
|
int rss2int(struct kinfo_proc2 *);
|
|
|
|
int vsz2int(struct kinfo_proc2 *);
|
|
|
|
char *comm2str(struct kinfo_proc2 *);
|
|
|
|
double pmem2float(struct kinfo_proc2 *);
|
|
|
|
char *start2str(struct kinfo_proc2 *);
|
|
|
|
char *time2str(struct kinfo_proc2 *);
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
static time_t now;
|
|
|
|
|
1999-12-22 17:46:14 +03:00
|
|
|
#define SHOWUSER_ANY (uid_t)-1
|
|
|
|
static uid_t showuser = SHOWUSER_ANY;
|
|
|
|
|
2000-01-09 02:12:36 +03:00
|
|
|
#ifndef P_ZOMBIE
|
|
|
|
#define P_ZOMBIE(p) ((p)->p_stat == SZOMB)
|
|
|
|
#endif
|
|
|
|
|
1999-02-22 00:48:07 +03:00
|
|
|
void
|
2000-07-05 15:03:20 +04:00
|
|
|
labelps(void)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
mvwaddstr(wnd, 0, 0, "USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2000-07-05 15:03:20 +04:00
|
|
|
showps(void)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
int i, k, y, vsz, rss;
|
2005-02-27 01:12:33 +03:00
|
|
|
const char *user, *comm, *state, *tty, *start, *time_str;
|
1999-02-22 00:48:07 +03:00
|
|
|
pid_t pid;
|
1999-06-19 09:35:14 +04:00
|
|
|
double pctcpu, pctmem;
|
2002-05-04 22:44:27 +04:00
|
|
|
struct kinfo_proc2 *kp;
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
now = 0; /* force start2str to reget current time */
|
|
|
|
|
|
|
|
qsort(pt, nproc + 1, sizeof (struct p_times), compare_pctcpu_noidle);
|
|
|
|
|
|
|
|
y = 1;
|
|
|
|
i = nproc + 1;
|
|
|
|
if (i > getmaxy(wnd)-2)
|
|
|
|
i = getmaxy(wnd)-1;
|
1999-12-22 17:46:14 +03:00
|
|
|
for (k = 0; i > 0 ; k++) {
|
1999-02-22 00:48:07 +03:00
|
|
|
if (pt[k].pt_kp == NULL) /* We're all the way down to the imaginary idle proc */
|
1999-12-22 17:46:14 +03:00
|
|
|
break;
|
1999-02-22 00:48:07 +03:00
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
kp = pt[k].pt_kp;
|
|
|
|
if (showuser != SHOWUSER_ANY && kp->p_uid != showuser)
|
1999-12-22 17:46:14 +03:00
|
|
|
continue;
|
2002-05-04 22:44:27 +04:00
|
|
|
user = user_from_uid(kp->p_uid, 0);
|
|
|
|
pid = kp->p_pid;
|
1999-06-19 09:35:14 +04:00
|
|
|
pctcpu = 100.0 * pt[k].pt_pctcpu;
|
1999-02-22 00:48:07 +03:00
|
|
|
pctmem = pmem2float(pt[k].pt_kp);
|
|
|
|
vsz = vsz2int(pt[k].pt_kp);
|
|
|
|
rss = rss2int(pt[k].pt_kp);
|
|
|
|
tty = tty2str(pt[k].pt_kp);
|
|
|
|
state = state2str(pt[k].pt_kp);
|
|
|
|
start = start2str(pt[k].pt_kp);
|
2005-02-27 01:12:33 +03:00
|
|
|
time_str = time2str(pt[k].pt_kp);
|
1999-02-22 00:48:07 +03:00
|
|
|
comm = comm2str(pt[k].pt_kp);
|
|
|
|
/*comm = pt[k].pt_kp->kp_proc.p_comm; */
|
|
|
|
|
|
|
|
wmove(wnd, y, 0);
|
|
|
|
wclrtoeol(wnd);
|
1999-12-22 17:46:14 +03:00
|
|
|
mvwprintw(wnd, y++, 0,
|
|
|
|
"%-8.8s%5d %4.1f %4.1f %6d %5d %-3s %-4s %7s %10.10s %s",
|
2005-02-27 01:12:33 +03:00
|
|
|
user, pid, pctcpu, pctmem, vsz, rss, tty, state, start,
|
|
|
|
time_str, comm);
|
1999-12-22 17:46:14 +03:00
|
|
|
i--;
|
1999-02-22 00:48:07 +03:00
|
|
|
}
|
1999-12-22 17:46:14 +03:00
|
|
|
wmove(wnd, y, 0);
|
|
|
|
wclrtobot(wnd);
|
1999-02-22 00:48:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2000-07-05 15:03:20 +04:00
|
|
|
compare_pctcpu_noidle(const void *a, const void *b)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
2005-02-27 01:12:33 +03:00
|
|
|
if (((const struct p_times *) a)->pt_kp == NULL)
|
1999-02-22 00:48:07 +03:00
|
|
|
return 1;
|
|
|
|
|
2005-02-27 01:12:33 +03:00
|
|
|
if (((const struct p_times *) b)->pt_kp == NULL)
|
1999-02-22 00:48:07 +03:00
|
|
|
return -1;
|
|
|
|
|
2005-02-27 01:12:33 +03:00
|
|
|
return (((const struct p_times *) a)->pt_pctcpu >
|
|
|
|
((const struct p_times *) b)->pt_pctcpu)? -1: 1;
|
1999-02-22 00:48:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/* from here down adapted from .../src/usr.bin/ps/print.c . Any mistakes are my own, however. */
|
|
|
|
char *
|
2002-05-04 22:44:27 +04:00
|
|
|
state2str(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
int flag;
|
|
|
|
char *cp;
|
|
|
|
char buf[5];
|
|
|
|
static char statestr[4];
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
flag = kp->p_flag;
|
1999-02-22 00:48:07 +03:00
|
|
|
cp = buf;
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
switch (kp->p_stat) {
|
2003-01-18 13:52:16 +03:00
|
|
|
case LSSTOP:
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp = 'T';
|
|
|
|
break;
|
|
|
|
|
2003-01-18 13:52:16 +03:00
|
|
|
case LSSLEEP:
|
|
|
|
if (flag & L_SINTR) /* interruptable (long) */
|
2009-04-14 03:20:27 +04:00
|
|
|
*cp = kp->p_slptime >= (uint32_t)maxslp ? 'I' : 'S';
|
1999-02-22 00:48:07 +03:00
|
|
|
else
|
|
|
|
*cp = 'D';
|
|
|
|
break;
|
|
|
|
|
2003-01-18 13:52:16 +03:00
|
|
|
case LSRUN:
|
|
|
|
case LSIDL:
|
|
|
|
case LSONPROC:
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp = 'R';
|
|
|
|
break;
|
|
|
|
|
2003-01-18 13:52:16 +03:00
|
|
|
case LSZOMB:
|
|
|
|
#ifdef LSDEAD
|
|
|
|
case LSDEAD:
|
2000-01-09 02:12:36 +03:00
|
|
|
#endif
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp = 'Z';
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
*cp = '?';
|
|
|
|
}
|
|
|
|
cp++;
|
2002-05-04 22:44:27 +04:00
|
|
|
if (kp->p_nice < NZERO)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = '<';
|
2002-05-04 22:44:27 +04:00
|
|
|
else if (kp->p_nice > NZERO)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = 'N';
|
2007-02-18 01:49:56 +03:00
|
|
|
if (flag & P_TRACED)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = 'X';
|
2007-02-18 01:49:56 +03:00
|
|
|
if (flag & P_WEXIT &&
|
2002-05-04 22:44:27 +04:00
|
|
|
/* XXX - I don't like this */
|
2007-02-10 01:08:48 +03:00
|
|
|
(kp->p_stat != LSZOMB))
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = 'E';
|
2007-02-18 01:49:56 +03:00
|
|
|
if (flag & P_PPWAIT)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = 'V';
|
2002-05-04 22:44:27 +04:00
|
|
|
if (kp->p_eflag & EPROC_SLEADER)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = 's';
|
2007-02-18 01:49:56 +03:00
|
|
|
if ((flag & P_CONTROLT) && kp->p__pgid == kp->p_tpgid)
|
1999-02-22 00:48:07 +03:00
|
|
|
*cp++ = '+';
|
|
|
|
*cp = '\0';
|
1999-12-20 20:08:52 +03:00
|
|
|
snprintf(statestr, sizeof(statestr), "%-s", buf);
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
return statestr;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2002-05-04 22:44:27 +04:00
|
|
|
tty2str(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
static char ttystr[4];
|
2005-02-27 01:12:33 +03:00
|
|
|
char *tty_name;
|
1999-02-22 00:48:07 +03:00
|
|
|
|
2008-12-29 04:48:19 +03:00
|
|
|
if (kp->p_tdev == (uint32_t)NODEV ||
|
2005-02-27 01:12:33 +03:00
|
|
|
(tty_name = devname(kp->p_tdev, S_IFCHR)) == NULL)
|
2003-05-15 05:00:07 +04:00
|
|
|
strlcpy(ttystr, "??", sizeof(ttystr));
|
1999-02-22 00:48:07 +03:00
|
|
|
else {
|
2005-02-27 01:12:33 +03:00
|
|
|
if (strncmp(tty_name, "tty", 3) == 0 ||
|
|
|
|
strncmp(tty_name, "dty", 3) == 0)
|
|
|
|
tty_name += 3;
|
|
|
|
snprintf(ttystr, sizeof(ttystr), "%s%c", tty_name,
|
2002-05-04 22:44:27 +04:00
|
|
|
kp->p_eflag & EPROC_CTTY ? ' ' : '-');
|
1999-02-22 00:48:07 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return ttystr;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define pgtok(a) (((a)*getpagesize())/1024)
|
|
|
|
|
|
|
|
int
|
2002-05-04 22:44:27 +04:00
|
|
|
vsz2int(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
- add new RLIMIT_AS (aka RLIMIT_VMEM) resource that limits the total
address space available to processes. this limit exists in most other
modern unix variants, and like most of them, our defaults are unlimited.
remove the old mmap / rlimit.datasize hack.
- adds the VMCMD_STACK flag to all the stack-creation vmcmd callers.
it is currently unused, but was added a few years ago.
- add a pair of new process size values to kinfo_proc2{}. one is the
total size of the process memory map, and the other is the total size
adjusted for unused stack space (since most processes have a lot of
this...)
- patch sh, and csh to notice RLIMIT_AS. (in some cases, the alias
RLIMIT_VMEM was already present and used if availble.)
- patch ps, top and systat to notice the new k_vm_vsize member of
kinfo_proc2{}.
- update irix, svr4, svr4_32, linux and osf1 emulations to support
this information. (freebsd could be done, but that it's best left
as part of the full-update of compat/freebsd.)
this addresses PR 7897. it also gives correct memory usage values,
which have never been entirely correct (since mmap), and have been
very incorrect since jemalloc() was enabled.
tested on i386 and sparc64, build tested on several other platforms.
thanks to many folks for feedback and testing but most espcially
chuq and yamt for critical suggestions that lead to this patch not
having a special ugliness i wasn't happy with anyway :-)
2009-03-29 05:02:48 +04:00
|
|
|
i = pgtok(kp->p_vm_msize);
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
return ((i < 0) ? 0 : i);
|
2002-05-04 22:44:27 +04:00
|
|
|
}
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
int
|
2002-05-04 22:44:27 +04:00
|
|
|
rss2int(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
i = pgtok(kp->p_vm_rssize);
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
/* XXX don't have info about shared */
|
|
|
|
return ((i < 0) ? 0 : i);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2002-05-04 22:44:27 +04:00
|
|
|
comm2str(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
2005-02-27 01:12:33 +03:00
|
|
|
char **argv;
|
1999-02-22 00:48:07 +03:00
|
|
|
static char commstr[41];
|
|
|
|
|
|
|
|
commstr[0]='\0';
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
argv = kvm_getargv2(kd, kp, 40);
|
2005-02-27 01:12:33 +03:00
|
|
|
if (argv != NULL) {
|
|
|
|
while (*argv) {
|
|
|
|
strlcat(commstr, *argv, sizeof(commstr));
|
|
|
|
argv++;
|
2003-05-18 01:03:21 +04:00
|
|
|
strlcat(commstr, " ", sizeof(commstr));
|
1999-02-22 00:48:07 +03:00
|
|
|
}
|
2006-02-13 19:01:58 +03:00
|
|
|
} else {
|
|
|
|
const char *fmt;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Commands that don't set an argv vector are printed with
|
|
|
|
* square brackets if they are system commands. Otherwise
|
|
|
|
* they are printed within parentheses.
|
|
|
|
*/
|
2007-02-18 01:49:56 +03:00
|
|
|
if (kp->p_flag & P_SYSTEM)
|
2006-02-13 19:01:58 +03:00
|
|
|
fmt = "[%s]";
|
|
|
|
else
|
|
|
|
fmt = "(%s)";
|
|
|
|
|
|
|
|
snprintf(commstr, sizeof(commstr), fmt, kp->p_comm);
|
|
|
|
}
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
return commstr;
|
|
|
|
}
|
|
|
|
|
1999-06-19 09:35:14 +04:00
|
|
|
double
|
2002-05-04 22:44:27 +04:00
|
|
|
pmem2float(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
double fracmem;
|
2001-07-14 11:09:11 +04:00
|
|
|
int szptudot = 0;
|
1999-02-22 00:48:07 +03:00
|
|
|
|
2001-07-14 11:09:11 +04:00
|
|
|
#ifdef USPACE
|
1999-02-22 00:48:07 +03:00
|
|
|
/* XXX want pmap ptpages, segtab, etc. (per architecture) */
|
|
|
|
szptudot = USPACE/getpagesize();
|
2001-07-14 11:09:11 +04:00
|
|
|
#endif
|
1999-02-22 00:48:07 +03:00
|
|
|
/* XXX don't have info about shared */
|
2002-05-04 22:44:27 +04:00
|
|
|
fracmem = ((double)kp->p_vm_rssize + szptudot)/mempages;
|
1999-02-22 00:48:07 +03:00
|
|
|
return (fracmem >= 0) ? 100.0 * fracmem : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2002-05-04 22:44:27 +04:00
|
|
|
start2str(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
struct timeval u_start;
|
|
|
|
struct tm *tp;
|
|
|
|
time_t startt;
|
|
|
|
static char startstr[10];
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
u_start.tv_sec = kp->p_ustart_sec;
|
|
|
|
u_start.tv_usec = kp->p_ustart_usec;
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
startt = u_start.tv_sec;
|
|
|
|
tp = localtime(&startt);
|
|
|
|
if (now == 0)
|
|
|
|
time(&now);
|
|
|
|
if (now - u_start.tv_sec < 24 * SECSPERHOUR) {
|
|
|
|
/* I *hate* SCCS... */
|
2000-12-20 04:17:49 +03:00
|
|
|
static char fmt[] = "%l:%" "M%p";
|
1999-02-22 00:48:07 +03:00
|
|
|
strftime(startstr, sizeof(startstr) - 1, fmt, tp);
|
|
|
|
} else if (now - u_start.tv_sec < 7 * SECSPERDAY) {
|
|
|
|
/* I *hate* SCCS... */
|
2000-12-20 04:17:49 +03:00
|
|
|
static char fmt[] = "%a%" "I%p";
|
1999-02-22 00:48:07 +03:00
|
|
|
strftime(startstr, sizeof(startstr) - 1, fmt, tp);
|
|
|
|
} else
|
|
|
|
strftime(startstr, sizeof(startstr) - 1, "%e%b%y", tp);
|
|
|
|
|
|
|
|
return startstr;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *
|
2002-05-04 22:44:27 +04:00
|
|
|
time2str(struct kinfo_proc2 *kp)
|
1999-02-22 00:48:07 +03:00
|
|
|
{
|
|
|
|
long secs;
|
|
|
|
long psecs; /* "parts" of a second. first micro, then centi */
|
|
|
|
static char timestr[10];
|
|
|
|
|
2002-05-04 22:44:27 +04:00
|
|
|
/* XXX - I don't like this. */
|
2004-01-11 22:15:50 +03:00
|
|
|
if (kp->p_stat == SZOMB) {
|
1999-02-22 00:48:07 +03:00
|
|
|
secs = 0;
|
|
|
|
psecs = 0;
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* This counts time spent handling interrupts. We could
|
|
|
|
* fix this, but it is not 100% trivial (and interrupt
|
|
|
|
* time fractions only work on the sparc anyway). XXX
|
|
|
|
*/
|
2002-05-04 22:44:27 +04:00
|
|
|
secs = kp->p_rtime_sec;
|
|
|
|
psecs = kp->p_rtime_usec;
|
|
|
|
#if 0
|
|
|
|
if (sumrusage) {
|
1999-02-22 00:48:07 +03:00
|
|
|
secs += k->ki_u.u_cru.ru_utime.tv_sec +
|
|
|
|
k->ki_u.u_cru.ru_stime.tv_sec;
|
|
|
|
psecs += k->ki_u.u_cru.ru_utime.tv_usec +
|
|
|
|
k->ki_u.u_cru.ru_stime.tv_usec;
|
2002-05-04 22:44:27 +04:00
|
|
|
}
|
|
|
|
#endif
|
1999-02-22 00:48:07 +03:00
|
|
|
/*
|
|
|
|
* round and scale to 100's
|
|
|
|
*/
|
|
|
|
psecs = (psecs + 5000) / 10000;
|
|
|
|
secs += psecs / 100;
|
|
|
|
psecs = psecs % 100;
|
|
|
|
}
|
2002-05-04 22:44:27 +04:00
|
|
|
snprintf(timestr, sizeof(timestr), "%3ld:%02ld.%02ld", secs/60,
|
|
|
|
secs%60, psecs);
|
1999-02-22 00:48:07 +03:00
|
|
|
|
|
|
|
return timestr;
|
|
|
|
}
|
1999-12-22 17:46:14 +03:00
|
|
|
|
|
|
|
void
|
2000-07-05 15:03:20 +04:00
|
|
|
ps_user(char *args)
|
1999-12-22 17:46:14 +03:00
|
|
|
{
|
|
|
|
uid_t uid;
|
|
|
|
|
2005-02-27 01:12:33 +03:00
|
|
|
if (args == NULL || *args == 0 || strcmp(args, "+") == 0) {
|
1999-12-22 17:46:14 +03:00
|
|
|
uid = SHOWUSER_ANY;
|
|
|
|
} else if (uid_from_user(args, &uid) != 0) {
|
|
|
|
error("%s: unknown user", args);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
showuser = uid;
|
|
|
|
display(0);
|
|
|
|
}
|