11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1990, 1993, 1994 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * Redistribution and use in source and binary forms, with or without 61556Srgrimes * modification, are permitted provided that the following conditions 71556Srgrimes * are met: 81556Srgrimes * 1. Redistributions of source code must retain the above copyright 91556Srgrimes * notice, this list of conditions and the following disclaimer. 101556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111556Srgrimes * notice, this list of conditions and the following disclaimer in the 121556Srgrimes * documentation and/or other materials provided with the distribution. 131556Srgrimes * 4. Neither the name of the University nor the names of its contributors 141556Srgrimes * may be used to endorse or promote products derived from this software 151556Srgrimes * without specific prior written permission. 161556Srgrimes * 171556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271556Srgrimes * SUCH DAMAGE. 281556Srgrimes */ 291556Srgrimes 3090143Smarkm#if 0 311556Srgrimes#ifndef lint 3236049Scharnierstatic char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; 3390143Smarkm#endif /* not lint */ 3436049Scharnier#endif 35110391Scharnier 3699110Sobrien#include <sys/cdefs.h> 3799110Sobrien__FBSDID("$FreeBSD$"); 381556Srgrimes 391556Srgrimes#include <sys/param.h> 401556Srgrimes#include <sys/time.h> 411556Srgrimes#include <sys/resource.h> 421556Srgrimes#include <sys/proc.h> 431556Srgrimes#include <sys/stat.h> 441556Srgrimes 45105831Srwatson#include <sys/mac.h> 4611890Sphk#include <sys/user.h> 471556Srgrimes#include <sys/sysctl.h> 48217192Skib#include <sys/vmmeter.h> 491556Srgrimes 501556Srgrimes#include <err.h> 5190878Simp#include <grp.h> 5273369Sache#include <langinfo.h> 5372343Sache#include <locale.h> 541556Srgrimes#include <math.h> 551556Srgrimes#include <nlist.h> 5690878Simp#include <pwd.h> 571556Srgrimes#include <stddef.h> 58205271Sjmallett#include <stdint.h> 591556Srgrimes#include <stdio.h> 601556Srgrimes#include <stdlib.h> 6190143Smarkm#include <string.h> 6216835Speter#include <unistd.h> 631556Srgrimes#include <vis.h> 641556Srgrimes 651556Srgrimes#include "ps.h" 661556Srgrimes 67225868Strasz#define COMMAND_WIDTH 16 68225868Strasz#define ARGUMENTS_WIDTH 16 69225868Strasz 70103274Speter#define ps_pgtok(a) (((a) * getpagesize()) / 1024) 7190143Smarkm 721556Srgrimesvoid 7390110Simpprintheader(void) 741556Srgrimes{ 751556Srgrimes VAR *v; 761556Srgrimes struct varent *vent; 771556Srgrimes 78130999Sgad STAILQ_FOREACH(vent, &varlist, next_ve) 79130999Sgad if (*vent->header != '\0') 80106251Stjr break; 81130999Sgad if (!vent) 82106251Stjr return; 83130999Sgad 84130999Sgad STAILQ_FOREACH(vent, &varlist, next_ve) { 851556Srgrimes v = vent->var; 861556Srgrimes if (v->flag & LJUST) { 87130999Sgad if (STAILQ_NEXT(vent, next_ve) == NULL) /* last one */ 88109504Sjmallett (void)printf("%s", vent->header); 891556Srgrimes else 90109504Sjmallett (void)printf("%-*s", v->width, vent->header); 911556Srgrimes } else 92109504Sjmallett (void)printf("%*s", v->width, vent->header); 93130999Sgad if (STAILQ_NEXT(vent, next_ve) != NULL) 941556Srgrimes (void)putchar(' '); 951556Srgrimes } 961556Srgrimes (void)putchar('\n'); 971556Srgrimes} 981556Srgrimes 99225868Straszchar * 10097958Sjmallettarguments(KINFO *k, VARENT *ve) 10197958Sjmallett{ 102225868Strasz char *vis_args; 10397958Sjmallett 10497958Sjmallett if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 10597958Sjmallett errx(1, "malloc failed"); 10697958Sjmallett strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 107225868Strasz 108225868Strasz if (STAILQ_NEXT(ve, next_ve) != NULL && strlen(vis_args) > ARGUMENTS_WIDTH) 109225868Strasz vis_args[ARGUMENTS_WIDTH] = '\0'; 110225868Strasz 111225868Strasz return (vis_args); 11297958Sjmallett} 11397958Sjmallett 114225868Straszchar * 11590110Simpcommand(KINFO *k, VARENT *ve) 1161556Srgrimes{ 117225868Strasz char *vis_args, *vis_env, *str; 1181556Srgrimes 11919068Speter if (cflag) { 120130999Sgad /* If it is the last field, then don't pad */ 121173004Sjulian if (STAILQ_NEXT(ve, next_ve) == NULL) { 122225868Strasz asprintf(&str, "%s%s%s%s", 123225868Strasz k->ki_d.prefix ? k->ki_d.prefix : "", 124225868Strasz k->ki_p->ki_comm, 125225868Strasz (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 126225868Strasz (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 127173004Sjulian } else 128225868Strasz str = strdup(k->ki_p->ki_comm); 129225868Strasz 130225868Strasz return (str); 13119068Speter } 1321556Srgrimes if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 13397877Sjmallett errx(1, "malloc failed"); 1341556Srgrimes strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 1351556Srgrimes 136130999Sgad if (STAILQ_NEXT(ve, next_ve) == NULL) { 1371556Srgrimes /* last field */ 138192239Sbrian 139192239Sbrian if (k->ki_env) { 140192239Sbrian if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) 141192239Sbrian == NULL) 142192239Sbrian errx(1, "malloc failed"); 143192239Sbrian strvis(vis_env, k->ki_env, 144192239Sbrian VIS_TAB | VIS_NL | VIS_NOSLASH); 145192239Sbrian } else 146192239Sbrian vis_env = NULL; 147192239Sbrian 148225868Strasz asprintf(&str, "%s%s%s%s", 149225868Strasz k->ki_d.prefix ? k->ki_d.prefix : "", 150225868Strasz vis_env ? vis_env : "", 151225868Strasz vis_env ? " " : "", 152225868Strasz vis_args); 153225868Strasz 154192239Sbrian if (vis_env != NULL) 155192239Sbrian free(vis_env); 156225868Strasz free(vis_args); 157225868Strasz } else { 158192239Sbrian /* ki_d.prefix & ki_env aren't shown for interim fields */ 159225868Strasz str = vis_args; 160225868Strasz 161225868Strasz if (strlen(str) > COMMAND_WIDTH) 162225868Strasz str[COMMAND_WIDTH] = '\0'; 163225868Strasz } 164225868Strasz 165225868Strasz return (str); 1661556Srgrimes} 1671556Srgrimes 168225868Straszchar * 16990110Simpucomm(KINFO *k, VARENT *ve) 1701556Srgrimes{ 171225868Strasz char *str; 1721556Srgrimes 173173004Sjulian if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ 174225868Strasz asprintf(&str, "%s%s%s%s", 175225868Strasz k->ki_d.prefix ? k->ki_d.prefix : "", 176225868Strasz k->ki_p->ki_comm, 177225868Strasz (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 178225868Strasz (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 179189078Sattilio } else { 180189078Sattilio if (showthreads && k->ki_p->ki_numthreads > 1) 181225868Strasz asprintf(&str, "%s/%s", k->ki_p->ki_comm, k->ki_p->ki_tdname); 182189078Sattilio else 183225868Strasz str = strdup(k->ki_p->ki_comm); 184189078Sattilio } 185225868Strasz return (str); 1861556Srgrimes} 1871556Srgrimes 188225868Straszchar * 189230287Sedtdnam(KINFO *k, VARENT *ve __unused) 190173004Sjulian{ 191225868Strasz char *str; 192173004Sjulian 193173004Sjulian if (showthreads && k->ki_p->ki_numthreads > 1) 194225868Strasz str = strdup(k->ki_p->ki_tdname); 195184925Semaste else 196225868Strasz str = strdup(" "); 197225868Strasz 198225868Strasz return (str); 199173004Sjulian} 200173004Sjulian 201225868Straszchar * 202230287Sedlogname(KINFO *k, VARENT *ve __unused) 2031556Srgrimes{ 2041556Srgrimes 205225868Strasz if (*k->ki_p->ki_login == '\0') 206225868Strasz return (NULL); 207225868Strasz return (strdup(k->ki_p->ki_login)); 2081556Srgrimes} 2091556Srgrimes 210225868Straszchar * 211230287Sedstate(KINFO *k, VARENT *ve __unused) 2121556Srgrimes{ 213172207Sjeff int flag, tdflags; 214225868Strasz char *cp, *buf; 2151556Srgrimes 216225868Strasz buf = malloc(16); 217225868Strasz if (buf == NULL) 218225868Strasz errx(1, "malloc failed"); 219225868Strasz 22069896Smckusick flag = k->ki_p->ki_flag; 22183366Sjulian tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ 2221556Srgrimes cp = buf; 2231556Srgrimes 22469896Smckusick switch (k->ki_p->ki_stat) { 2251556Srgrimes 2261556Srgrimes case SSTOP: 2271556Srgrimes *cp = 'T'; 2281556Srgrimes break; 2291556Srgrimes 2301556Srgrimes case SSLEEP: 23183366Sjulian if (tdflags & TDF_SINTR) /* interruptable (long) */ 23269896Smckusick *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; 2331556Srgrimes else 2341556Srgrimes *cp = 'D'; 2351556Srgrimes break; 2361556Srgrimes 2371556Srgrimes case SRUN: 2381556Srgrimes case SIDL: 2391556Srgrimes *cp = 'R'; 2401556Srgrimes break; 2411556Srgrimes 24265557Sjasone case SWAIT: 24365557Sjasone *cp = 'W'; 24465557Sjasone break; 24565557Sjasone 246104388Sjhb case SLOCK: 247104388Sjhb *cp = 'L'; 24865557Sjasone break; 24965557Sjasone 2501556Srgrimes case SZOMB: 2511556Srgrimes *cp = 'Z'; 2521556Srgrimes break; 2531556Srgrimes 2541556Srgrimes default: 2551556Srgrimes *cp = '?'; 2561556Srgrimes } 2571556Srgrimes cp++; 258172207Sjeff if (!(flag & P_INMEM)) 2591556Srgrimes *cp++ = 'W'; 26069896Smckusick if (k->ki_p->ki_nice < NZERO) 2611556Srgrimes *cp++ = '<'; 26269896Smckusick else if (k->ki_p->ki_nice > NZERO) 2631556Srgrimes *cp++ = 'N'; 2641556Srgrimes if (flag & P_TRACED) 2651556Srgrimes *cp++ = 'X'; 26669896Smckusick if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) 2671556Srgrimes *cp++ = 'E'; 2681556Srgrimes if (flag & P_PPWAIT) 2691556Srgrimes *cp++ = 'V'; 27069896Smckusick if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) 2711556Srgrimes *cp++ = 'L'; 27269896Smckusick if (k->ki_p->ki_kiflag & KI_SLEADER) 2731556Srgrimes *cp++ = 's'; 27469896Smckusick if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid) 2751556Srgrimes *cp++ = '+'; 27646155Sphk if (flag & P_JAILED) 27746155Sphk *cp++ = 'J'; 2781556Srgrimes *cp = '\0'; 279225868Strasz return (buf); 2801556Srgrimes} 2811556Srgrimes 282130974Sgad#define scalepri(x) ((x) - PZERO) 283130974Sgad 284225868Straszchar * 285230287Sedpri(KINFO *k, VARENT *ve __unused) 2861556Srgrimes{ 287225868Strasz char *str; 2881556Srgrimes 289225868Strasz asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_level)); 290225868Strasz return (str); 2911556Srgrimes} 2921556Srgrimes 293225868Straszchar * 294230287Sedupr(KINFO *k, VARENT *ve __unused) 295130974Sgad{ 296225868Strasz char *str; 297130974Sgad 298225868Strasz asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_user)); 299225868Strasz return (str); 300130974Sgad} 301130974Sgad#undef scalepri 302130974Sgad 303225868Straszchar * 304230287Seduname(KINFO *k, VARENT *ve __unused) 3051556Srgrimes{ 3061556Srgrimes 307225868Strasz return (strdup(user_from_uid(k->ki_p->ki_uid, 0))); 3081556Srgrimes} 3091556Srgrimes 310225868Straszchar * 311230287Sedegroupname(KINFO *k, VARENT *ve __unused) 312223086Strasz{ 313223086Strasz 314225868Strasz return (strdup(group_from_gid(k->ki_p->ki_groups[0], 0))); 315223086Strasz} 316223086Strasz 317225868Straszchar * 318230287Sedrgroupname(KINFO *k, VARENT *ve __unused) 31997961Sjmallett{ 32097961Sjmallett 321225868Strasz return (strdup(group_from_gid(k->ki_p->ki_rgid, 0))); 32297961Sjmallett} 32397961Sjmallett 324225868Straszchar * 325230287Sedruname(KINFO *k, VARENT *ve __unused) 3261556Srgrimes{ 3271556Srgrimes 328225868Strasz return (strdup(user_from_uid(k->ki_p->ki_ruid, 0))); 3291556Srgrimes} 3301556Srgrimes 331225868Straszchar * 332230287Sedtdev(KINFO *k, VARENT *ve __unused) 3331556Srgrimes{ 3341556Srgrimes dev_t dev; 335225868Strasz char *str; 3361556Srgrimes 33769896Smckusick dev = k->ki_p->ki_tdev; 3381556Srgrimes if (dev == NODEV) 339226939Strasz str = strdup("-"); 340225847Sed else 341225868Strasz asprintf(&str, "%#jx", (uintmax_t)dev); 342225868Strasz 343225868Strasz return (str); 3441556Srgrimes} 3451556Srgrimes 346225868Straszchar * 347230287Sedtname(KINFO *k, VARENT *ve __unused) 3481556Srgrimes{ 3491556Srgrimes dev_t dev; 350225868Strasz char *ttname, *str; 3511556Srgrimes 35269896Smckusick dev = k->ki_p->ki_tdev; 3531556Srgrimes if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 354226939Strasz str = strdup("- "); 3551556Srgrimes else { 3563301Sache if (strncmp(ttname, "tty", 3) == 0 || 3573301Sache strncmp(ttname, "cua", 3) == 0) 3581556Srgrimes ttname += 3; 359155876Scognet if (strncmp(ttname, "pts/", 4) == 0) 360155876Scognet ttname += 4; 361225868Strasz asprintf(&str, "%s%c", ttname, 362113485Scharnier k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); 3631556Srgrimes } 364225868Strasz 365225868Strasz return (str); 3661556Srgrimes} 3671556Srgrimes 368225868Straszchar * 369230287Sedlongtname(KINFO *k, VARENT *ve __unused) 3701556Srgrimes{ 3711556Srgrimes dev_t dev; 372225868Strasz const char *ttname; 3731556Srgrimes 37469896Smckusick dev = k->ki_p->ki_tdev; 3751556Srgrimes if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 376226939Strasz ttname = "-"; 377225868Strasz 378225868Strasz return (strdup(ttname)); 3791556Srgrimes} 3801556Srgrimes 381225868Straszchar * 382230287Sedstarted(KINFO *k, VARENT *ve __unused) 3831556Srgrimes{ 38437231Sbde time_t then; 3851556Srgrimes struct tm *tp; 386113485Scharnier static int use_ampm = -1; 387225868Strasz size_t buflen = 100; 388225868Strasz char *buf; 3891556Srgrimes 390238488Sjilles if (!k->ki_valid) 391238488Sjilles return (NULL); 392238488Sjilles 393225868Strasz buf = malloc(buflen); 394225868Strasz if (buf == NULL) 395225868Strasz errx(1, "malloc failed"); 396225868Strasz 39773369Sache if (use_ampm < 0) 39873369Sache use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 39969896Smckusick then = k->ki_p->ki_start.tv_sec; 40037231Sbde tp = localtime(&then); 40169896Smckusick if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 402225868Strasz (void)strftime(buf, buflen, 403113485Scharnier use_ampm ? "%l:%M%p" : "%k:%M ", tp); 40469896Smckusick } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 405225868Strasz (void)strftime(buf, buflen, 406113485Scharnier use_ampm ? "%a%I%p" : "%a%H ", tp); 4071556Srgrimes } else 408225868Strasz (void)strftime(buf, buflen, "%e%b%y", tp); 409225868Strasz return (buf); 4101556Srgrimes} 4111556Srgrimes 412225868Straszchar * 413230287Sedlstarted(KINFO *k, VARENT *ve __unused) 4141556Srgrimes{ 41537231Sbde time_t then; 416225868Strasz char *buf; 417225868Strasz size_t buflen = 100; 4181556Srgrimes 419238488Sjilles if (!k->ki_valid) 420238488Sjilles return (NULL); 421238488Sjilles 422225868Strasz buf = malloc(buflen); 423225868Strasz if (buf == NULL) 424225868Strasz errx(1, "malloc failed"); 425225868Strasz 42669896Smckusick then = k->ki_p->ki_start.tv_sec; 427225868Strasz (void)strftime(buf, buflen, "%c", localtime(&then)); 428225868Strasz return (buf); 4291556Srgrimes} 4301556Srgrimes 431225868Straszchar * 432230287Sedlockname(KINFO *k, VARENT *ve __unused) 43369372Sjhb{ 434225868Strasz char *str; 43569372Sjhb 436104388Sjhb if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 437104388Sjhb if (k->ki_p->ki_lockname[0] != 0) 438225868Strasz str = strdup(k->ki_p->ki_lockname); 43969372Sjhb else 440225868Strasz str = strdup("???"); 44169372Sjhb } else 442225868Strasz str = NULL; 443225868Strasz 444225868Strasz return (str); 44569372Sjhb} 44669372Sjhb 447225868Straszchar * 448230287Sedwchan(KINFO *k, VARENT *ve __unused) 4491556Srgrimes{ 450225868Strasz char *str; 4511556Srgrimes 45269896Smckusick if (k->ki_p->ki_wchan) { 45369896Smckusick if (k->ki_p->ki_wmesg[0] != 0) 454225868Strasz str = strdup(k->ki_p->ki_wmesg); 4551556Srgrimes else 456225868Strasz asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 457113485Scharnier } else 458225868Strasz str = NULL; 459225868Strasz 460225868Strasz return (str); 46191028Sdillon} 46291028Sdillon 463225868Straszchar * 464230287Sednwchan(KINFO *k, VARENT *ve __unused) 465118857Sharti{ 466225868Strasz char *str; 467118857Sharti 468225868Strasz if (k->ki_p->ki_wchan) 469225868Strasz asprintf(&str, "%0lx", (long)k->ki_p->ki_wchan); 470225868Strasz else 471225868Strasz str = NULL; 472225868Strasz 473225868Strasz return (str); 474118857Sharti} 475118857Sharti 476225868Straszchar * 477230287Sedmwchan(KINFO *k, VARENT *ve __unused) 47891028Sdillon{ 479225868Strasz char *str; 48091028Sdillon 48191028Sdillon if (k->ki_p->ki_wchan) { 48291028Sdillon if (k->ki_p->ki_wmesg[0] != 0) 483225868Strasz str = strdup(k->ki_p->ki_wmesg); 48491028Sdillon else 485225868Strasz asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 486104388Sjhb } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 487104388Sjhb if (k->ki_p->ki_lockname[0]) { 488225868Strasz str = strdup(k->ki_p->ki_lockname); 489113485Scharnier } else 490225868Strasz str = strdup("???"); 491113485Scharnier } else 492225868Strasz str = NULL; 493225868Strasz 494225868Strasz return (str); 4951556Srgrimes} 4961556Srgrimes 497225868Straszchar * 498230287Sedvsize(KINFO *k, VARENT *ve __unused) 4991556Srgrimes{ 500225868Strasz char *str; 5011556Srgrimes 502225868Strasz asprintf(&str, "%lu", (u_long)(k->ki_p->ki_size / 1024)); 503225868Strasz return (str); 5041556Srgrimes} 5051556Srgrimes 506225868Straszstatic char * 507230287Sedprinttime(KINFO *k, VARENT *ve __unused, long secs, long psecs) 508219713Skib/* psecs is "parts" of a second. first micro, then centi */ 5091556Srgrimes{ 510113485Scharnier static char decimal_point; 511225868Strasz char *str; 5121556Srgrimes 513113485Scharnier if (decimal_point == '\0') 51472343Sache decimal_point = localeconv()->decimal_point[0]; 515130856Sgad if (!k->ki_valid) { 51636497Sbde secs = 0; 51736497Sbde psecs = 0; 5181556Srgrimes } else { 519219713Skib /* round and scale to 100's */ 52036497Sbde psecs = (psecs + 5000) / 10000; 52136497Sbde secs += psecs / 100; 52236497Sbde psecs = psecs % 100; 5231556Srgrimes } 524225868Strasz asprintf(&str, "%ld:%02ld%c%02ld", 525113485Scharnier secs / 60, secs % 60, decimal_point, psecs); 526225868Strasz return (str); 5271556Srgrimes} 5281556Srgrimes 529225868Straszchar * 530219713Skibcputime(KINFO *k, VARENT *ve) 531219713Skib{ 532219713Skib long secs, psecs; 533219713Skib 534219713Skib /* 535219713Skib * This counts time spent handling interrupts. We could 536219713Skib * fix this, but it is not 100% trivial (and interrupt 537219713Skib * time fractions only work on the sparc anyway). XXX 538219713Skib */ 539219713Skib secs = k->ki_p->ki_runtime / 1000000; 540219713Skib psecs = k->ki_p->ki_runtime % 1000000; 541219713Skib if (sumrusage) { 542219713Skib secs += k->ki_p->ki_childtime.tv_sec; 543219713Skib psecs += k->ki_p->ki_childtime.tv_usec; 544219713Skib } 545225868Strasz return (printtime(k, ve, secs, psecs)); 546219713Skib} 547219713Skib 548225868Straszchar * 549219713Skibsystime(KINFO *k, VARENT *ve) 550219713Skib{ 551219713Skib long secs, psecs; 552219713Skib 553219713Skib secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 554219713Skib psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; 555219713Skib if (sumrusage) { 556219713Skib secs += k->ki_p->ki_childstime.tv_sec; 557219713Skib psecs += k->ki_p->ki_childstime.tv_usec; 558219713Skib } 559225868Strasz return (printtime(k, ve, secs, psecs)); 560219713Skib} 561219713Skib 562225868Straszchar * 563219713Skibusertime(KINFO *k, VARENT *ve) 564219713Skib{ 565219713Skib long secs, psecs; 566219713Skib 567219713Skib secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 568219713Skib psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; 569219713Skib if (sumrusage) { 570219713Skib secs += k->ki_p->ki_childutime.tv_sec; 571219713Skib psecs += k->ki_p->ki_childutime.tv_usec; 572219713Skib } 573225868Strasz return (printtime(k, ve, secs, psecs)); 574219713Skib} 575219713Skib 576225868Straszchar * 577230287Sedelapsed(KINFO *k, VARENT *ve __unused) 57897965Sjmallett{ 579113485Scharnier time_t val; 580113485Scharnier int days, hours, mins, secs; 581225868Strasz char *str; 58297965Sjmallett 583225868Strasz if (!k->ki_valid) 584225868Strasz return (NULL); 585113485Scharnier val = now - k->ki_p->ki_start.tv_sec; 586113485Scharnier days = val / (24 * 60 * 60); 587113485Scharnier val %= 24 * 60 * 60; 588113485Scharnier hours = val / (60 * 60); 589113485Scharnier val %= 60 * 60; 590113485Scharnier mins = val / 60; 591113485Scharnier secs = val % 60; 592113485Scharnier if (days != 0) 593225868Strasz asprintf(&str, "%3d-%02d:%02d:%02d", days, hours, mins, secs); 594113485Scharnier else if (hours != 0) 595225868Strasz asprintf(&str, "%02d:%02d:%02d", hours, mins, secs); 596113485Scharnier else 597225868Strasz asprintf(&str, "%02d:%02d", mins, secs); 598225868Strasz 599225868Strasz return (str); 60097965Sjmallett} 60197965Sjmallett 602225868Straszchar * 603230287Sedelapseds(KINFO *k, VARENT *ve __unused) 604205271Sjmallett{ 605205271Sjmallett time_t val; 606225868Strasz char *str; 607205271Sjmallett 608225868Strasz if (!k->ki_valid) 609225868Strasz return (NULL); 610205271Sjmallett val = now - k->ki_p->ki_start.tv_sec; 611225868Strasz asprintf(&str, "%jd", (intmax_t)val); 612225868Strasz return (str); 613205271Sjmallett} 614205271Sjmallett 6151556Srgrimesdouble 61690143Smarkmgetpcpu(const KINFO *k) 6171556Srgrimes{ 6181556Srgrimes static int failure; 6191556Srgrimes 6201556Srgrimes if (!nlistread) 6211556Srgrimes failure = donlist(); 6221556Srgrimes if (failure) 6231556Srgrimes return (0.0); 6241556Srgrimes 6251556Srgrimes#define fxtofl(fixpt) ((double)(fixpt) / fscale) 6261556Srgrimes 6271556Srgrimes /* XXX - I don't like this */ 628172207Sjeff if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0) 6291556Srgrimes return (0.0); 6301556Srgrimes if (rawcpu) 63169896Smckusick return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 63269896Smckusick return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 63369896Smckusick (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 6341556Srgrimes} 6351556Srgrimes 636225868Straszchar * 637230287Sedpcpu(KINFO *k, VARENT *ve __unused) 6381556Srgrimes{ 639225868Strasz char *str; 6401556Srgrimes 641225868Strasz asprintf(&str, "%.1f", getpcpu(k)); 642225868Strasz return (str); 6431556Srgrimes} 6441556Srgrimes 64590143Smarkmstatic double 64690110Simpgetpmem(KINFO *k) 6471556Srgrimes{ 6481556Srgrimes static int failure; 6491556Srgrimes double fracmem; 6501556Srgrimes 6511556Srgrimes if (!nlistread) 6521556Srgrimes failure = donlist(); 6531556Srgrimes if (failure) 6541556Srgrimes return (0.0); 6551556Srgrimes 656172207Sjeff if ((k->ki_p->ki_flag & P_INMEM) == 0) 6571556Srgrimes return (0.0); 6581556Srgrimes /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 6591556Srgrimes /* XXX don't have info about shared */ 660113485Scharnier fracmem = ((float)k->ki_p->ki_rssize) / mempages; 6611556Srgrimes return (100.0 * fracmem); 6621556Srgrimes} 6631556Srgrimes 664225868Straszchar * 665230287Sedpmem(KINFO *k, VARENT *ve __unused) 6661556Srgrimes{ 667225868Strasz char *str; 6681556Srgrimes 669225868Strasz asprintf(&str, "%.1f", getpmem(k)); 670225868Strasz return (str); 6711556Srgrimes} 6721556Srgrimes 673225868Straszchar * 674230287Sedpagein(KINFO *k, VARENT *ve __unused) 6751556Srgrimes{ 676225868Strasz char *str; 6771556Srgrimes 678225868Strasz asprintf(&str, "%ld", k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 679225868Strasz return (str); 6801556Srgrimes} 6811556Srgrimes 68290143Smarkm/* ARGSUSED */ 683225868Straszchar * 684230287Sedmaxrss(KINFO *k __unused, VARENT *ve __unused) 6851556Srgrimes{ 6861556Srgrimes 68727856Speter /* XXX not yet */ 688225868Strasz return (NULL); 6891556Srgrimes} 6901556Srgrimes 691225868Straszchar * 692230287Sedpriorityr(KINFO *k, VARENT *ve __unused) 69336352Ssteve{ 69490143Smarkm struct priority *lpri; 695225868Strasz char *str; 69672377Sjake unsigned class, level; 697127512Sgad 698127512Sgad lpri = &k->ki_p->ki_pri; 69990143Smarkm class = lpri->pri_class; 70090143Smarkm level = lpri->pri_level; 70172377Sjake switch (class) { 702131215Sgad case PRI_ITHD: 703225868Strasz asprintf(&str, "intr:%u", level); 704131215Sgad break; 70572377Sjake case PRI_REALTIME: 706225868Strasz asprintf(&str, "real:%u", level); 70736352Ssteve break; 70872377Sjake case PRI_TIMESHARE: 709225868Strasz asprintf(&str, "normal"); 71036352Ssteve break; 71172377Sjake case PRI_IDLE: 712225868Strasz asprintf(&str, "idle:%u", level); 71336352Ssteve break; 71436352Ssteve default: 715225868Strasz asprintf(&str, "%u:%u", class, level); 71636352Ssteve break; 71736352Ssteve } 718225868Strasz return (str); 71936352Ssteve} 72036352Ssteve 7211556Srgrimes/* 7221556Srgrimes * Generic output routines. Print fields from various prototype 7231556Srgrimes * structures. 7241556Srgrimes */ 725225868Straszstatic char * 72699547Sjmallettprintval(void *bp, VAR *v) 7271556Srgrimes{ 7281556Srgrimes static char ofmt[32] = "%"; 72997843Sjmallett const char *fcp; 730225868Strasz char *cp, *str; 7311556Srgrimes 7321556Srgrimes cp = ofmt + 1; 7331556Srgrimes fcp = v->fmt; 7347165Sjoerg while ((*cp++ = *fcp++)); 7351556Srgrimes 736113395Stjr#define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 737113395Stjr 7381556Srgrimes switch (v->type) { 7391556Srgrimes case CHAR: 740225868Strasz (void)asprintf(&str, ofmt, *(char *)bp); 7411556Srgrimes break; 7421556Srgrimes case UCHAR: 743225868Strasz (void)asprintf(&str, ofmt, *(u_char *)bp); 7441556Srgrimes break; 7451556Srgrimes case SHORT: 746225868Strasz (void)asprintf(&str, ofmt, *(short *)bp); 7471556Srgrimes break; 7481556Srgrimes case USHORT: 749225868Strasz (void)asprintf(&str, ofmt, *(u_short *)bp); 7501556Srgrimes break; 75139160Sdfr case INT: 752225868Strasz (void)asprintf(&str, ofmt, *(int *)bp); 75339160Sdfr break; 75439160Sdfr case UINT: 755225868Strasz (void)asprintf(&str, ofmt, CHKINF127(*(u_int *)bp)); 75639160Sdfr break; 7571556Srgrimes case LONG: 758225868Strasz (void)asprintf(&str, ofmt, *(long *)bp); 7591556Srgrimes break; 7601556Srgrimes case ULONG: 761225868Strasz (void)asprintf(&str, ofmt, *(u_long *)bp); 7621556Srgrimes break; 7631556Srgrimes case KPTR: 764225868Strasz (void)asprintf(&str, ofmt, *(u_long *)bp); 7651556Srgrimes break; 766103497Sjmallett case PGTOK: 767225868Strasz (void)asprintf(&str, ofmt, ps_pgtok(*(u_long *)bp)); 768103438Sjmallett break; 7691556Srgrimes default: 7701556Srgrimes errx(1, "unknown type %d", v->type); 7711556Srgrimes } 772225868Strasz 773225868Strasz return (str); 7741556Srgrimes} 7751556Srgrimes 776225868Straszchar * 77790110Simpkvar(KINFO *k, VARENT *ve) 7781556Srgrimes{ 7791556Srgrimes VAR *v; 7801556Srgrimes 7811556Srgrimes v = ve->var; 782225868Strasz return (printval((char *)((char *)k->ki_p + v->off), v)); 7831556Srgrimes} 7841556Srgrimes 785225868Straszchar * 78690110Simprvar(KINFO *k, VARENT *ve) 7871556Srgrimes{ 7881556Srgrimes VAR *v; 7891556Srgrimes 7901556Srgrimes v = ve->var; 791225868Strasz if (!k->ki_valid) 792225868Strasz return (NULL); 793225868Strasz return (printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v)); 7941556Srgrimes} 79586922Sgreen 796225868Straszchar * 797230287Sedemulname(KINFO *k, VARENT *ve __unused) 798130830Sgad{ 799130830Sgad 800225868Strasz return (strdup(k->ki_p->ki_emul)); 801130830Sgad} 802130830Sgad 803225868Straszchar * 804230287Sedlabel(KINFO *k, VARENT *ve __unused) 80586922Sgreen{ 806105831Srwatson char *string; 807109460Sjmallett mac_t proclabel; 808105831Srwatson int error; 80986922Sgreen 810105831Srwatson string = NULL; 811109460Sjmallett if (mac_prepare_process_label(&proclabel) == -1) { 812132433Stjr warn("mac_prepare_process_label"); 813105831Srwatson goto out; 814105831Srwatson } 815109460Sjmallett error = mac_get_pid(k->ki_p->ki_pid, proclabel); 816105831Srwatson if (error == 0) { 817109460Sjmallett if (mac_to_text(proclabel, &string) == -1) 818105831Srwatson string = NULL; 819105831Srwatson } 820109460Sjmallett mac_free(proclabel); 821105831Srwatsonout: 822225868Strasz return (string); 82386922Sgreen} 824105831Srwatson 825225868Straszchar * 826230287Sedloginclass(KINFO *k, VARENT *ve __unused) 827219307Strasz{ 828219307Strasz 829219307Strasz /* 830219307Strasz * Don't display login class for system processes; 831219307Strasz * login classes are used for resource limits, 832219307Strasz * and limits don't apply to system processes. 833219307Strasz */ 834219307Strasz if (k->ki_p->ki_flag & P_SYSTEM) { 835225868Strasz return (strdup("-")); 836219307Strasz } 837260195Strasz return (strdup(k->ki_p->ki_loginclass)); 838219967Strasz} 839