print.c revision 225868
153541Sshin/*- 253541Sshin * Copyright (c) 1990, 1993, 1994 353541Sshin * The Regents of the University of California. All rights reserved. 453541Sshin * 553541Sshin * Redistribution and use in source and binary forms, with or without 653541Sshin * modification, are permitted provided that the following conditions 753541Sshin * are met: 853541Sshin * 1. Redistributions of source code must retain the above copyright 953541Sshin * notice, this list of conditions and the following disclaimer. 1053541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1153541Sshin * notice, this list of conditions and the following disclaimer in the 1253541Sshin * documentation and/or other materials provided with the distribution. 1353541Sshin * 4. Neither the name of the University nor the names of its contributors 1453541Sshin * may be used to endorse or promote products derived from this software 1553541Sshin * without specific prior written permission. 1653541Sshin * 1753541Sshin * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 1853541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1953541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2053541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2153541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2253541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2353541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2453541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2553541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2653541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2753541Sshin * SUCH DAMAGE. 2853541Sshin */ 2953541Sshin 3053541Sshin#if 0 3153541Sshin#ifndef lint 3253541Sshinstatic char sccsid[] = "@(#)print.c 8.6 (Berkeley) 4/16/94"; 3353541Sshin#endif /* not lint */ 3453541Sshin#endif 3553541Sshin 3653541Sshin#include <sys/cdefs.h> 3753541Sshin__FBSDID("$FreeBSD: head/bin/ps/print.c 225868 2011-09-29 06:31:42Z trasz $"); 3853541Sshin 3953541Sshin#include <sys/param.h> 4053541Sshin#include <sys/time.h> 4153541Sshin#include <sys/resource.h> 4253541Sshin#include <sys/proc.h> 4353541Sshin#include <sys/stat.h> 4453541Sshin 4553541Sshin#include <sys/mac.h> 4653541Sshin#include <sys/user.h> 4753541Sshin#include <sys/sysctl.h> 4853541Sshin#include <sys/vmmeter.h> 4953541Sshin 5053541Sshin#include <err.h> 5153541Sshin#include <grp.h> 5253541Sshin#include <langinfo.h> 5353541Sshin#include <locale.h> 5453541Sshin#include <math.h> 5553541Sshin#include <nlist.h> 5653541Sshin#include <pwd.h> 5753541Sshin#include <stddef.h> 5853541Sshin#include <stdint.h> 5953541Sshin#include <stdio.h> 6053541Sshin#include <stdlib.h> 6153541Sshin#include <string.h> 6253541Sshin#include <unistd.h> 6353541Sshin#include <vis.h> 6453541Sshin 6553541Sshin#include "ps.h" 6653541Sshin 6755009Sshin#define COMMAND_WIDTH 16 6878064Sume#define ARGUMENTS_WIDTH 16 6955009Sshin 7053541Sshin#define ps_pgtok(a) (((a) * getpagesize()) / 1024) 7195759Stanimura 7295759Stanimuravoid 7353541Sshinprintheader(void) 7495759Stanimura{ 7553541Sshin VAR *v; 7695759Stanimura struct varent *vent; 7795759Stanimura 7853541Sshin STAILQ_FOREACH(vent, &varlist, next_ve) 7953541Sshin if (*vent->header != '\0') 8095759Stanimura break; 8153541Sshin if (!vent) 8253541Sshin return; 8353541Sshin 8495759Stanimura STAILQ_FOREACH(vent, &varlist, next_ve) { 8553541Sshin v = vent->var; 8653541Sshin if (v->flag & LJUST) { 8753541Sshin if (STAILQ_NEXT(vent, next_ve) == NULL) /* last one */ 8853541Sshin (void)printf("%s", vent->header); 8953541Sshin else 9095759Stanimura (void)printf("%-*s", v->width, vent->header); 9195759Stanimura } else 9262587Sitojun (void)printf("%*s", v->width, vent->header); 9395759Stanimura if (STAILQ_NEXT(vent, next_ve) != NULL) 9456723Sshin (void)putchar(' '); 9553541Sshin } 9695759Stanimura (void)putchar('\n'); 9753541Sshin} 9895759Stanimura 9962587Sitojunchar * 10062587Sitojunarguments(KINFO *k, VARENT *ve) 10162587Sitojun{ 10253541Sshin VAR *v; 10353541Sshin char *vis_args; 10453541Sshin 10553541Sshin v = ve->var; 10653541Sshin if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 10753541Sshin errx(1, "malloc failed"); 108105199Ssam strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 109105199Ssam 110105199Ssam if (STAILQ_NEXT(ve, next_ve) != NULL && strlen(vis_args) > ARGUMENTS_WIDTH) 111105199Ssam vis_args[ARGUMENTS_WIDTH] = '\0'; 112105199Ssam 11353541Sshin return (vis_args); 11453541Sshin} 11553541Sshin 11653541Sshinchar * 11753541Sshincommand(KINFO *k, VARENT *ve) 11853541Sshin{ 11953541Sshin VAR *v; 12053541Sshin char *vis_args, *vis_env, *str; 12153541Sshin 12253541Sshin v = ve->var; 12353541Sshin if (cflag) { 12453541Sshin /* If it is the last field, then don't pad */ 12553541Sshin if (STAILQ_NEXT(ve, next_ve) == NULL) { 12653541Sshin asprintf(&str, "%s%s%s%s", 12778064Sume k->ki_d.prefix ? k->ki_d.prefix : "", 12878064Sume k->ki_p->ki_comm, 12953541Sshin (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 13053541Sshin (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 13153541Sshin } else 13253541Sshin str = strdup(k->ki_p->ki_comm); 13353541Sshin 13453541Sshin return (str); 13553541Sshin } 13653541Sshin if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) 13753541Sshin errx(1, "malloc failed"); 13853541Sshin strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); 13953541Sshin 14053541Sshin if (STAILQ_NEXT(ve, next_ve) == NULL) { 14153541Sshin /* last field */ 14253541Sshin 14378064Sume if (k->ki_env) { 14453541Sshin if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) 14553541Sshin == NULL) 14678064Sume errx(1, "malloc failed"); 14778064Sume strvis(vis_env, k->ki_env, 14883934Sbrooks VIS_TAB | VIS_NL | VIS_NOSLASH); 14978064Sume } else 15078064Sume vis_env = NULL; 15178064Sume 15253541Sshin asprintf(&str, "%s%s%s%s", 15378064Sume k->ki_d.prefix ? k->ki_d.prefix : "", 15453541Sshin vis_env ? vis_env : "", 15553541Sshin vis_env ? " " : "", 15653541Sshin vis_args); 15755009Sshin 15853541Sshin if (vis_env != NULL) 15953541Sshin free(vis_env); 16053541Sshin free(vis_args); 16153541Sshin } else { 16253541Sshin /* ki_d.prefix & ki_env aren't shown for interim fields */ 16353541Sshin str = vis_args; 16453541Sshin 16553541Sshin if (strlen(str) > COMMAND_WIDTH) 16653541Sshin str[COMMAND_WIDTH] = '\0'; 16753541Sshin } 16878064Sume 16978064Sume return (str); 17078064Sume} 17178064Sume 17278064Sumechar * 17378064Sumeucomm(KINFO *k, VARENT *ve) 17478064Sume{ 17553541Sshin VAR *v; 17653541Sshin char *str; 17753541Sshin 17878064Sume v = ve->var; 17978064Sume if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ 18078064Sume asprintf(&str, "%s%s%s%s", 18178064Sume k->ki_d.prefix ? k->ki_d.prefix : "", 18278064Sume k->ki_p->ki_comm, 183111145Sjlemon (showthreads && k->ki_p->ki_numthreads > 1) ? "/" : "", 18478064Sume (showthreads && k->ki_p->ki_numthreads > 1) ? k->ki_p->ki_tdname : ""); 18578064Sume } else { 18678064Sume if (showthreads && k->ki_p->ki_numthreads > 1) 18778064Sume asprintf(&str, "%s/%s", k->ki_p->ki_comm, k->ki_p->ki_tdname); 18878064Sume else 189105199Ssam str = strdup(k->ki_p->ki_comm); 190105199Ssam } 191105199Ssam return (str); 192105199Ssam} 193105199Ssam 194105199Ssamchar * 195105199Ssamtdnam(KINFO *k, VARENT *ve) 196105199Ssam{ 197105199Ssam VAR *v; 19853541Sshin char *str; 19997658Stanimura 20097658Stanimura v = ve->var; 20153541Sshin if (showthreads && k->ki_p->ki_numthreads > 1) 20253541Sshin str = strdup(k->ki_p->ki_tdname); 20353541Sshin else 20453541Sshin str = strdup(" "); 20553541Sshin 20653541Sshin return (str); 20753541Sshin} 20853541Sshin 20953541Sshinchar * 21078064Sumelogname(KINFO *k, VARENT *ve) 21197658Stanimura{ 21253541Sshin VAR *v; 21353541Sshin 21453541Sshin v = ve->var; 21553541Sshin if (*k->ki_p->ki_login == '\0') 21653541Sshin return (NULL); 21753541Sshin return (strdup(k->ki_p->ki_login)); 21878064Sume} 21978064Sume 22078064Sumechar * 22178064Sumestate(KINFO *k, VARENT *ve) 222111145Sjlemon{ 22378064Sume int flag, tdflags; 22478064Sume char *cp, *buf; 22578064Sume VAR *v; 22678064Sume 22778064Sume buf = malloc(16); 22878064Sume if (buf == NULL) 229105199Ssam errx(1, "malloc failed"); 230105199Ssam 231105199Ssam v = ve->var; 232105199Ssam flag = k->ki_p->ki_flag; 233105199Ssam tdflags = k->ki_p->ki_tdflags; /* XXXKSE */ 234105199Ssam cp = buf; 235105199Ssam 236105199Ssam switch (k->ki_p->ki_stat) { 237105199Ssam 238105199Ssam case SSTOP: 23953541Sshin *cp = 'T'; 24097658Stanimura break; 24197658Stanimura 24253541Sshin case SSLEEP: 24353541Sshin if (tdflags & TDF_SINTR) /* interruptable (long) */ 24453541Sshin *cp = k->ki_p->ki_slptime >= MAXSLP ? 'I' : 'S'; 24553541Sshin else 24653541Sshin *cp = 'D'; 24753541Sshin break; 24853541Sshin 24953541Sshin case SRUN: 25078064Sume case SIDL: 25197658Stanimura *cp = 'R'; 25253541Sshin break; 25353541Sshin 25478064Sume case SWAIT: 25578064Sume *cp = 'W'; 25678064Sume break; 25753541Sshin 25853541Sshin case SLOCK: 25953541Sshin *cp = 'L'; 26053541Sshin break; 26153541Sshin 26253541Sshin case SZOMB: 26353541Sshin *cp = 'Z'; 26453541Sshin break; 26553541Sshin 26653541Sshin default: 26753541Sshin *cp = '?'; 26853541Sshin } 26953541Sshin cp++; 27062587Sitojun if (!(flag & P_INMEM)) 27162587Sitojun *cp++ = 'W'; 27262587Sitojun if (k->ki_p->ki_nice < NZERO) 27362587Sitojun *cp++ = '<'; 27462587Sitojun else if (k->ki_p->ki_nice > NZERO) 27562587Sitojun *cp++ = 'N'; 27662587Sitojun if (flag & P_TRACED) 27762587Sitojun *cp++ = 'X'; 27862587Sitojun if (flag & P_WEXIT && k->ki_p->ki_stat != SZOMB) 27978064Sume *cp++ = 'E'; 28078064Sume if (flag & P_PPWAIT) 28198211Shsu *cp++ = 'V'; 28262587Sitojun if ((flag & P_SYSTEM) || k->ki_p->ki_lock > 0) 28362587Sitojun *cp++ = 'L'; 28462587Sitojun if (k->ki_p->ki_kiflag & KI_SLEADER) 28562587Sitojun *cp++ = 's'; 28662587Sitojun if ((flag & P_CONTROLT) && k->ki_p->ki_pgid == k->ki_p->ki_tpgid) 28762587Sitojun *cp++ = '+'; 28862587Sitojun if (flag & P_JAILED) 28962587Sitojun *cp++ = 'J'; 29062587Sitojun *cp = '\0'; 29162587Sitojun return (buf); 29262587Sitojun} 29362587Sitojun 29462587Sitojun#define scalepri(x) ((x) - PZERO) 29562587Sitojun 29662587Sitojunchar * 29762587Sitojunpri(KINFO *k, VARENT *ve) 29878064Sume{ 29962587Sitojun VAR *v; 30062587Sitojun char *str; 30162587Sitojun 30278064Sume v = ve->var; 30362587Sitojun asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_level)); 30462587Sitojun return (str); 30562587Sitojun} 30678064Sume 30762587Sitojunchar * 30862587Sitojunupr(KINFO *k, VARENT *ve) 30991346Salfred{ 31078064Sume VAR *v; 31162587Sitojun char *str; 31262587Sitojun 31353541Sshin v = ve->var; 31453541Sshin asprintf(&str, "%d", scalepri(k->ki_p->ki_pri.pri_user)); 31553541Sshin return (str); 31653541Sshin} 31753541Sshin#undef scalepri 31853541Sshin 31953541Sshinchar * 32053541Sshinuname(KINFO *k, VARENT *ve) 32153541Sshin{ 32253541Sshin VAR *v; 32353541Sshin 32453541Sshin v = ve->var; 32553541Sshin return (strdup(user_from_uid(k->ki_p->ki_uid, 0))); 326120941Sume} 32753541Sshin 32853541Sshinchar * 32953541Sshinegroupname(KINFO *k, VARENT *ve) 33053541Sshin{ 33153541Sshin VAR *v; 33253541Sshin 33353541Sshin v = ve->var; 334121472Sume return (strdup(group_from_gid(k->ki_p->ki_groups[0], 0))); 33553541Sshin} 33653541Sshin 33753541Sshinchar * 338121472Sumergroupname(KINFO *k, VARENT *ve) 33953541Sshin{ 34053541Sshin VAR *v; 34153541Sshin 34253541Sshin v = ve->var; 34353541Sshin return (strdup(group_from_gid(k->ki_p->ki_rgid, 0))); 34453541Sshin} 34553541Sshin 34653541Sshinchar * 34753541Sshinruname(KINFO *k, VARENT *ve) 348121472Sume{ 34953541Sshin VAR *v; 35053541Sshin 35153541Sshin v = ve->var; 35253541Sshin return (strdup(user_from_uid(k->ki_p->ki_ruid, 0))); 35353541Sshin} 35453541Sshin 355121472Sumechar * 356121472Sumetdev(KINFO *k, VARENT *ve) 357121472Sume{ 358121472Sume VAR *v; 35953541Sshin dev_t dev; 360121472Sume char *str; 361121472Sume 362121472Sume v = ve->var; 36353541Sshin dev = k->ki_p->ki_tdev; 36453541Sshin if (dev == NODEV) 36553541Sshin str = strdup("??"); 36653541Sshin else 36753541Sshin asprintf(&str, "%#jx", (uintmax_t)dev); 36853541Sshin 36953541Sshin return (str); 37053541Sshin} 37153541Sshin 37253541Sshinchar * 37353541Sshintname(KINFO *k, VARENT *ve) 37453541Sshin{ 37553541Sshin VAR *v; 37653541Sshin dev_t dev; 37753541Sshin char *ttname, *str; 37853541Sshin 37953541Sshin v = ve->var; 380111119Simp dev = k->ki_p->ki_tdev; 38153541Sshin if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 38253541Sshin str = strdup("?? "); 38353541Sshin else { 38453541Sshin if (strncmp(ttname, "tty", 3) == 0 || 38553541Sshin strncmp(ttname, "cua", 3) == 0) 38653541Sshin ttname += 3; 38753541Sshin if (strncmp(ttname, "pts/", 4) == 0) 38853541Sshin ttname += 4; 38953541Sshin asprintf(&str, "%s%c", ttname, 39053541Sshin k->ki_p->ki_kiflag & KI_CTTY ? ' ' : '-'); 39153541Sshin } 39253541Sshin 39353541Sshin return (str); 39453541Sshin} 39553541Sshin 39653541Sshinchar * 39753541Sshinlongtname(KINFO *k, VARENT *ve) 39853541Sshin{ 39953541Sshin VAR *v; 40053541Sshin dev_t dev; 401121472Sume const char *ttname; 402121472Sume 403121472Sume v = ve->var; 40453541Sshin dev = k->ki_p->ki_tdev; 40583130Sjlemon if (dev == NODEV || (ttname = devname(dev, S_IFCHR)) == NULL) 40653541Sshin ttname = "??"; 40753541Sshin 40853541Sshin return (strdup(ttname)); 40953541Sshin} 41053541Sshin 41153541Sshinchar * 41253541Sshinstarted(KINFO *k, VARENT *ve) 413120941Sume{ 414120941Sume VAR *v; 41553541Sshin time_t then; 41653541Sshin struct tm *tp; 41753541Sshin static int use_ampm = -1; 418120941Sume size_t buflen = 100; 419120941Sume char *buf; 42053541Sshin 42153541Sshin buf = malloc(buflen); 42253541Sshin if (buf == NULL) 42353541Sshin errx(1, "malloc failed"); 42453541Sshin 42553541Sshin v = ve->var; 426121472Sume if (!k->ki_valid) 427121472Sume return (NULL); 428121472Sume if (use_ampm < 0) 429121472Sume use_ampm = (*nl_langinfo(T_FMT_AMPM) != '\0'); 430121472Sume then = k->ki_p->ki_start.tv_sec; 431121472Sume tp = localtime(&then); 43253541Sshin if (now - k->ki_p->ki_start.tv_sec < 24 * 3600) { 433121472Sume (void)strftime(buf, buflen, 434121472Sume use_ampm ? "%l:%M%p" : "%k:%M ", tp); 435121472Sume } else if (now - k->ki_p->ki_start.tv_sec < 7 * 86400) { 43655009Sshin (void)strftime(buf, buflen, 43755009Sshin use_ampm ? "%a%I%p" : "%a%H ", tp); 43855009Sshin } else 43955009Sshin (void)strftime(buf, buflen, "%e%b%y", tp); 44053541Sshin return (buf); 44153541Sshin} 44253541Sshin 44353541Sshinchar * 44453541Sshinlstarted(KINFO *k, VARENT *ve) 44553541Sshin{ 44653541Sshin VAR *v; 44753541Sshin time_t then; 44853541Sshin char *buf; 44953541Sshin size_t buflen = 100; 45053541Sshin 45153541Sshin buf = malloc(buflen); 45253541Sshin if (buf == NULL) 45353541Sshin errx(1, "malloc failed"); 45453541Sshin 45553541Sshin v = ve->var; 45653541Sshin if (!k->ki_valid) 45753541Sshin return (NULL); 45853541Sshin then = k->ki_p->ki_start.tv_sec; 45953541Sshin (void)strftime(buf, buflen, "%c", localtime(&then)); 46053541Sshin return (buf); 46153541Sshin} 46253541Sshin 46353541Sshinchar * 46453541Sshinlockname(KINFO *k, VARENT *ve) 46553541Sshin{ 46653541Sshin VAR *v; 46753541Sshin char *str; 46853541Sshin 46953541Sshin v = ve->var; 47053541Sshin if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 47153541Sshin if (k->ki_p->ki_lockname[0] != 0) 47253541Sshin str = strdup(k->ki_p->ki_lockname); 473121472Sume else 474105194Ssam str = strdup("???"); 47553541Sshin } else 47653541Sshin str = NULL; 47753541Sshin 47853541Sshin return (str); 47978064Sume} 48078064Sume 48153541Sshinchar * 48253541Sshinwchan(KINFO *k, VARENT *ve) 48353541Sshin{ 48453541Sshin VAR *v; 48553541Sshin char *str; 48653541Sshin 48753541Sshin v = ve->var; 48853541Sshin if (k->ki_p->ki_wchan) { 48978064Sume if (k->ki_p->ki_wmesg[0] != 0) 490121472Sume str = strdup(k->ki_p->ki_wmesg); 491121472Sume else 49253541Sshin asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 49378064Sume } else 494120856Sume str = NULL; 49553541Sshin 49653541Sshin return (str); 49753541Sshin} 49853541Sshin 49953541Sshinchar * 50053541Sshinnwchan(KINFO *k, VARENT *ve) 50153541Sshin{ 50253541Sshin VAR *v; 50353541Sshin char *str; 50453541Sshin 50553541Sshin v = ve->var; 50653541Sshin if (k->ki_p->ki_wchan) 50753541Sshin asprintf(&str, "%0lx", (long)k->ki_p->ki_wchan); 50853541Sshin else 50953541Sshin str = NULL; 51053541Sshin 51153541Sshin return (str); 512120856Sume} 51353541Sshin 51453541Sshinchar * 51553541Sshinmwchan(KINFO *k, VARENT *ve) 51653541Sshin{ 51753541Sshin VAR *v; 51853541Sshin char *str; 51953541Sshin 52053541Sshin v = ve->var; 52156723Sshin if (k->ki_p->ki_wchan) { 52256723Sshin if (k->ki_p->ki_wmesg[0] != 0) 52356723Sshin str = strdup(k->ki_p->ki_wmesg); 52456723Sshin else 52556723Sshin asprintf(&str, "%lx", (long)k->ki_p->ki_wchan); 52656723Sshin } else if (k->ki_p->ki_kiflag & KI_LOCKBLOCK) { 52756723Sshin if (k->ki_p->ki_lockname[0]) { 52856723Sshin str = strdup(k->ki_p->ki_lockname); 52956723Sshin } else 530121578Sume str = strdup("???"); 531121578Sume } else 532121578Sume str = NULL; 53353541Sshin 53453541Sshin return (str); 53553541Sshin} 53653541Sshin 53753541Sshinchar * 53853541Sshinvsize(KINFO *k, VARENT *ve) 53953541Sshin{ 54053541Sshin VAR *v; 54156723Sshin char *str; 54256723Sshin 54356723Sshin v = ve->var; 54456723Sshin asprintf(&str, "%lu", (u_long)(k->ki_p->ki_size / 1024)); 54556723Sshin return (str); 54656723Sshin} 54756723Sshin 54856723Sshinstatic char * 54956723Sshinprinttime(KINFO *k, VARENT *ve, long secs, long psecs) 550121578Sume/* psecs is "parts" of a second. first micro, then centi */ 551121578Sume{ 552121578Sume VAR *v; 55353541Sshin static char decimal_point; 55453541Sshin char *str; 55553541Sshin 55653541Sshin if (decimal_point == '\0') 55753541Sshin decimal_point = localeconv()->decimal_point[0]; 55853541Sshin v = ve->var; 55953541Sshin if (!k->ki_valid) { 56053541Sshin secs = 0; 56153541Sshin psecs = 0; 56253541Sshin } else { 56353541Sshin /* round and scale to 100's */ 56483366Sjulian psecs = (psecs + 5000) / 10000; 56553541Sshin secs += psecs / 100; 56653541Sshin psecs = psecs % 100; 56753541Sshin } 56853541Sshin asprintf(&str, "%ld:%02ld%c%02ld", 56953541Sshin secs / 60, secs % 60, decimal_point, psecs); 57053541Sshin return (str); 57153541Sshin} 57293593Sjhb 57353541Sshinchar * 57453541Sshincputime(KINFO *k, VARENT *ve) 57555009Sshin{ 57655009Sshin long secs, psecs; 57755009Sshin 57853541Sshin /* 57983366Sjulian * This counts time spent handling interrupts. We could 58053541Sshin * fix this, but it is not 100% trivial (and interrupt 58153541Sshin * time fractions only work on the sparc anyway). XXX 58253541Sshin */ 58353541Sshin secs = k->ki_p->ki_runtime / 1000000; 58453541Sshin psecs = k->ki_p->ki_runtime % 1000000; 58553541Sshin if (sumrusage) { 58653541Sshin secs += k->ki_p->ki_childtime.tv_sec; 58753541Sshin psecs += k->ki_p->ki_childtime.tv_usec; 58853541Sshin } 58953541Sshin return (printtime(k, ve, secs, psecs)); 59053541Sshin} 59153541Sshin 59253541Sshinchar * 59353541Sshinsystime(KINFO *k, VARENT *ve) 59453541Sshin{ 59553541Sshin long secs, psecs; 59653541Sshin 59753541Sshin secs = k->ki_p->ki_rusage.ru_stime.tv_sec; 59853541Sshin psecs = k->ki_p->ki_rusage.ru_stime.tv_usec; 59953541Sshin if (sumrusage) { 60053541Sshin secs += k->ki_p->ki_childstime.tv_sec; 60153541Sshin psecs += k->ki_p->ki_childstime.tv_usec; 60253541Sshin } 60357535Sshin return (printtime(k, ve, secs, psecs)); 60457535Sshin} 60553541Sshin 60653541Sshinchar * 60753541Sshinusertime(KINFO *k, VARENT *ve) 60853541Sshin{ 60953541Sshin long secs, psecs; 61053541Sshin 61153541Sshin secs = k->ki_p->ki_rusage.ru_utime.tv_sec; 61253541Sshin psecs = k->ki_p->ki_rusage.ru_utime.tv_usec; 61353541Sshin if (sumrusage) { 61453541Sshin secs += k->ki_p->ki_childutime.tv_sec; 61553541Sshin psecs += k->ki_p->ki_childutime.tv_usec; 61653541Sshin } 61753541Sshin return (printtime(k, ve, secs, psecs)); 61853541Sshin} 61953541Sshin 62053541Sshinchar * 62153541Sshinelapsed(KINFO *k, VARENT *ve) 62253541Sshin{ 62353541Sshin VAR *v; 62453541Sshin time_t val; 62597658Stanimura int days, hours, mins, secs; 62653541Sshin char *str; 62753541Sshin 62853541Sshin v = ve->var; 62953541Sshin if (!k->ki_valid) 63053541Sshin return (NULL); 63153541Sshin val = now - k->ki_p->ki_start.tv_sec; 63283366Sjulian days = val / (24 * 60 * 60); 63353541Sshin val %= 24 * 60 * 60; 63453541Sshin hours = val / (60 * 60); 63553541Sshin val %= 60 * 60; 63653541Sshin mins = val / 60; 63753541Sshin secs = val % 60; 63853541Sshin if (days != 0) 63953541Sshin asprintf(&str, "%3d-%02d:%02d:%02d", days, hours, mins, secs); 64053541Sshin else if (hours != 0) 64153541Sshin asprintf(&str, "%02d:%02d:%02d", hours, mins, secs); 64262587Sitojun else 64362587Sitojun asprintf(&str, "%02d:%02d", mins, secs); 64462587Sitojun 64562587Sitojun return (str); 64662587Sitojun} 64753541Sshin 64853541Sshinchar * 64953541Sshinelapseds(KINFO *k, VARENT *ve) 65053541Sshin{ 65153541Sshin VAR *v; 65253541Sshin time_t val; 65353541Sshin char *str; 654120856Sume 65553541Sshin v = ve->var; 65653541Sshin if (!k->ki_valid) 65753541Sshin return (NULL); 65853541Sshin val = now - k->ki_p->ki_start.tv_sec; 65953541Sshin asprintf(&str, "%jd", (intmax_t)val); 66053541Sshin return (str); 66183366Sjulian} 66253541Sshin 66353541Sshindouble 66453541Sshingetpcpu(const KINFO *k) 66553541Sshin{ 66653541Sshin static int failure; 66762587Sitojun 66862587Sitojun if (!nlistread) 66962587Sitojun failure = donlist(); 67053541Sshin if (failure) 67153541Sshin return (0.0); 67253541Sshin 67353541Sshin#define fxtofl(fixpt) ((double)(fixpt) / fscale) 67453541Sshin 67553541Sshin /* XXX - I don't like this */ 67653541Sshin if (k->ki_p->ki_swtime == 0 || (k->ki_p->ki_flag & P_INMEM) == 0) 67762587Sitojun return (0.0); 67862587Sitojun if (rawcpu) 67962587Sitojun return (100.0 * fxtofl(k->ki_p->ki_pctcpu)); 68062587Sitojun return (100.0 * fxtofl(k->ki_p->ki_pctcpu) / 68162587Sitojun (1.0 - exp(k->ki_p->ki_swtime * log(fxtofl(ccpu))))); 68262587Sitojun} 68362587Sitojun 68462587Sitojunchar * 68553541Sshinpcpu(KINFO *k, VARENT *ve) 68653541Sshin{ 68753541Sshin VAR *v; 68853541Sshin char *str; 68953541Sshin 69053541Sshin v = ve->var; 69153541Sshin asprintf(&str, "%.1f", getpcpu(k)); 69253541Sshin return (str); 69353541Sshin} 69453541Sshin 69553541Sshinstatic double 69653541Sshingetpmem(KINFO *k) 69753541Sshin{ 69853541Sshin static int failure; 69953541Sshin double fracmem; 70053541Sshin 70153541Sshin if (!nlistread) 70253541Sshin failure = donlist(); 70353541Sshin if (failure) 70453541Sshin return (0.0); 70553541Sshin 70683366Sjulian if ((k->ki_p->ki_flag & P_INMEM) == 0) 70753541Sshin return (0.0); 70853541Sshin /* XXX want pmap ptpages, segtab, etc. (per architecture) */ 70953541Sshin /* XXX don't have info about shared */ 71053541Sshin fracmem = ((float)k->ki_p->ki_rssize) / mempages; 71153541Sshin return (100.0 * fracmem); 71262587Sitojun} 71353541Sshin 71453541Sshinchar * 71553541Sshinpmem(KINFO *k, VARENT *ve) 71653541Sshin{ 71753541Sshin VAR *v; 71853541Sshin char *str; 71953541Sshin 72053541Sshin v = ve->var; 72153541Sshin asprintf(&str, "%.1f", getpmem(k)); 72253541Sshin return (str); 72353541Sshin} 72453541Sshin 72553541Sshinchar * 72653541Sshinpagein(KINFO *k, VARENT *ve) 72753541Sshin{ 72853541Sshin VAR *v; 72953541Sshin char *str; 73062587Sitojun 73162587Sitojun v = ve->var; 73253541Sshin asprintf(&str, "%ld", k->ki_valid ? k->ki_p->ki_rusage.ru_majflt : 0); 73362587Sitojun return (str); 73462587Sitojun} 73562587Sitojun 73662587Sitojun/* ARGSUSED */ 73762587Sitojunchar * 73853541Sshinmaxrss(KINFO *k __unused, VARENT *ve) 73953541Sshin{ 74053541Sshin VAR *v; 74153541Sshin 74253541Sshin v = ve->var; 74353541Sshin /* XXX not yet */ 74453541Sshin return (NULL); 74553541Sshin} 74653541Sshin 74753541Sshinchar * 748priorityr(KINFO *k, VARENT *ve) 749{ 750 VAR *v; 751 struct priority *lpri; 752 char *str; 753 unsigned class, level; 754 755 v = ve->var; 756 lpri = &k->ki_p->ki_pri; 757 class = lpri->pri_class; 758 level = lpri->pri_level; 759 switch (class) { 760 case PRI_ITHD: 761 asprintf(&str, "intr:%u", level); 762 break; 763 case PRI_REALTIME: 764 asprintf(&str, "real:%u", level); 765 break; 766 case PRI_TIMESHARE: 767 asprintf(&str, "normal"); 768 break; 769 case PRI_IDLE: 770 asprintf(&str, "idle:%u", level); 771 break; 772 default: 773 asprintf(&str, "%u:%u", class, level); 774 break; 775 } 776 return (str); 777} 778 779/* 780 * Generic output routines. Print fields from various prototype 781 * structures. 782 */ 783static char * 784printval(void *bp, VAR *v) 785{ 786 static char ofmt[32] = "%"; 787 const char *fcp; 788 char *cp, *str; 789 790 cp = ofmt + 1; 791 fcp = v->fmt; 792 while ((*cp++ = *fcp++)); 793 794#define CHKINF127(n) (((n) > 127) && (v->flag & INF127) ? 127 : (n)) 795 796 switch (v->type) { 797 case CHAR: 798 (void)asprintf(&str, ofmt, *(char *)bp); 799 break; 800 case UCHAR: 801 (void)asprintf(&str, ofmt, *(u_char *)bp); 802 break; 803 case SHORT: 804 (void)asprintf(&str, ofmt, *(short *)bp); 805 break; 806 case USHORT: 807 (void)asprintf(&str, ofmt, *(u_short *)bp); 808 break; 809 case INT: 810 (void)asprintf(&str, ofmt, *(int *)bp); 811 break; 812 case UINT: 813 (void)asprintf(&str, ofmt, CHKINF127(*(u_int *)bp)); 814 break; 815 case LONG: 816 (void)asprintf(&str, ofmt, *(long *)bp); 817 break; 818 case ULONG: 819 (void)asprintf(&str, ofmt, *(u_long *)bp); 820 break; 821 case KPTR: 822 (void)asprintf(&str, ofmt, *(u_long *)bp); 823 break; 824 case PGTOK: 825 (void)asprintf(&str, ofmt, ps_pgtok(*(u_long *)bp)); 826 break; 827 default: 828 errx(1, "unknown type %d", v->type); 829 } 830 831 return (str); 832} 833 834char * 835kvar(KINFO *k, VARENT *ve) 836{ 837 VAR *v; 838 839 v = ve->var; 840 return (printval((char *)((char *)k->ki_p + v->off), v)); 841} 842 843char * 844rvar(KINFO *k, VARENT *ve) 845{ 846 VAR *v; 847 848 v = ve->var; 849 if (!k->ki_valid) 850 return (NULL); 851 return (printval((char *)((char *)(&k->ki_p->ki_rusage) + v->off), v)); 852} 853 854char * 855emulname(KINFO *k, VARENT *ve) 856{ 857 VAR *v; 858 859 v = ve->var; 860 if (k->ki_p->ki_emul == NULL) 861 return (NULL); 862 return (strdup(k->ki_p->ki_emul)); 863} 864 865char * 866label(KINFO *k, VARENT *ve) 867{ 868 char *string; 869 VAR *v; 870 mac_t proclabel; 871 int error; 872 873 v = ve->var; 874 string = NULL; 875 if (mac_prepare_process_label(&proclabel) == -1) { 876 warn("mac_prepare_process_label"); 877 goto out; 878 } 879 error = mac_get_pid(k->ki_p->ki_pid, proclabel); 880 if (error == 0) { 881 if (mac_to_text(proclabel, &string) == -1) 882 string = NULL; 883 } 884 mac_free(proclabel); 885out: 886 return (string); 887} 888 889char * 890loginclass(KINFO *k, VARENT *ve) 891{ 892 VAR *v; 893 char *s; 894 895 v = ve->var; 896 /* 897 * Don't display login class for system processes; 898 * login classes are used for resource limits, 899 * and limits don't apply to system processes. 900 */ 901 if (k->ki_p->ki_flag & P_SYSTEM) { 902 return (strdup("-")); 903 } 904 s = k->ki_p->ki_loginclass; 905 if (s == NULL) 906 return (NULL); 907 return (strdup(s)); 908} 909