linprocfs.c revision 67589
159412Smsmith/* 265577Sdes * Copyright (c) 2000 Dag-Erling Co�dan Sm�rgrav 365577Sdes * Copyright (c) 1999 Pierre Beyssac 459412Smsmith * Copyright (c) 1993 Jan-Simon Pendry 559412Smsmith * Copyright (c) 1993 659412Smsmith * The Regents of the University of California. All rights reserved. 759412Smsmith * 859412Smsmith * This code is derived from software contributed to Berkeley by 959412Smsmith * Jan-Simon Pendry. 1059412Smsmith * 1159412Smsmith * Redistribution and use in source and binary forms, with or without 1259412Smsmith * modification, are permitted provided that the following conditions 1359412Smsmith * are met: 1459412Smsmith * 1. Redistributions of source code must retain the above copyright 1559412Smsmith * notice, this list of conditions and the following disclaimer. 1659412Smsmith * 2. Redistributions in binary form must reproduce the above copyright 1759412Smsmith * notice, this list of conditions and the following disclaimer in the 1859412Smsmith * documentation and/or other materials provided with the distribution. 1959412Smsmith * 3. All advertising materials mentioning features or use of this software 2059412Smsmith * must display the following acknowledgement: 2159412Smsmith * This product includes software developed by the University of 2259412Smsmith * California, Berkeley and its contributors. 2359412Smsmith * 4. Neither the name of the University nor the names of its contributors 2459412Smsmith * may be used to endorse or promote products derived from this software 2559412Smsmith * without specific prior written permission. 2659412Smsmith * 2759412Smsmith * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2859412Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2959412Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 3059412Smsmith * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 3159412Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 3259412Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 3359412Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3459412Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3559412Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3659412Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3759412Smsmith * SUCH DAMAGE. 3859412Smsmith * 3959412Smsmith * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 4059412Smsmith * 4159412Smsmith * $FreeBSD: head/sys/compat/linprocfs/linprocfs.c 67589 2000-10-25 22:38:23Z des $ 4259412Smsmith */ 4359412Smsmith 4459412Smsmith#include <sys/param.h> 4565633Sdes#include <sys/blist.h> 4665633Sdes#include <sys/dkstat.h> 4765633Sdes#include <sys/jail.h> 4865633Sdes#include <sys/kernel.h> 4965633Sdes#include <sys/proc.h> 5065633Sdes#include <sys/resourcevar.h> 5159412Smsmith#include <sys/systm.h> 5265633Sdes#include <sys/tty.h> 5359412Smsmith#include <sys/vnode.h> 5459412Smsmith 5559412Smsmith#include <vm/vm.h> 5659412Smsmith#include <vm/pmap.h> 5767588Sdes#include <vm/vm_map.h> 5859412Smsmith#include <vm/vm_param.h> 5960860Sdes#include <vm/vm_object.h> 6059412Smsmith#include <vm/swap_pager.h> 6159412Smsmith#include <sys/vmmeter.h> 6259412Smsmith#include <sys/exec.h> 6359412Smsmith 6467589Sdes#include <machine/clock.h> 6567589Sdes#include <machine/cputypes.h> 6659412Smsmith#include <machine/md_var.h> 6759412Smsmith 6865633Sdes#include <i386/linux/linprocfs/linprocfs.h> 6959412Smsmith 7067588Sdes/* 7167588Sdes * Various conversion macros 7267588Sdes */ 7367588Sdes#define T2J(x) (((x) * 100) / (stathz ? stathz : hz)) /* ticks to jiffies */ 7467588Sdes#define T2S(x) ((x) / (stathz ? stathz : hz)) /* ticks to seconds */ 7567588Sdes#define B2K(x) ((x) >> 10) /* bytes to kbytes */ 7667588Sdes#define P2B(x) ((x) << PAGE_SHIFT) /* pages to bytes */ 7767588Sdes#define P2K(x) ((x) << (PAGE_SHIFT - 10)) /* pages to kbytes */ 7865633Sdes 7959412Smsmithint 8059412Smsmithlinprocfs_domeminfo(curp, p, pfs, uio) 8159412Smsmith struct proc *curp; 8259412Smsmith struct proc *p; 8359412Smsmith struct pfsnode *pfs; 8459412Smsmith struct uio *uio; 8559412Smsmith{ 8659412Smsmith char *ps; 8759412Smsmith int xlen; 8859412Smsmith char psbuf[512]; /* XXX - conservative */ 8959412Smsmith unsigned long memtotal; /* total memory in bytes */ 9059412Smsmith unsigned long memused; /* used memory in bytes */ 9159412Smsmith unsigned long memfree; /* free memory in bytes */ 9259412Smsmith unsigned long memshared; /* shared memory ??? */ 9359412Smsmith unsigned long buffers, cached; /* buffer / cache memory ??? */ 9459412Smsmith unsigned long swaptotal; /* total swap space in bytes */ 9559412Smsmith unsigned long swapused; /* used swap space in bytes */ 9659412Smsmith unsigned long swapfree; /* free swap space in bytes */ 9760860Sdes vm_object_t object; 9859412Smsmith 9959412Smsmith if (uio->uio_rw != UIO_READ) 10059412Smsmith return (EOPNOTSUPP); 10159412Smsmith 10259412Smsmith memtotal = physmem * PAGE_SIZE; 10359412Smsmith /* 10459412Smsmith * The correct thing here would be: 10559412Smsmith * 10659412Smsmith memfree = cnt.v_free_count * PAGE_SIZE; 10759412Smsmith memused = memtotal - memfree; 10859412Smsmith * 10959412Smsmith * but it might mislead linux binaries into thinking there 11059412Smsmith * is very little memory left, so we cheat and tell them that 11159412Smsmith * all memory that isn't wired down is free. 11259412Smsmith */ 11359412Smsmith memused = cnt.v_wire_count * PAGE_SIZE; 11459412Smsmith memfree = memtotal - memused; 11564560Sbde if (swapblist == NULL) { 11664560Sbde swaptotal = 0; 11764560Sbde swapfree = 0; 11864560Sbde } else { 11964560Sbde swaptotal = swapblist->bl_blocks * 1024; /* XXX why 1024? */ 12064560Sbde swapfree = swapblist->bl_root->u.bmu_avail * PAGE_SIZE; 12164560Sbde } 12259412Smsmith swapused = swaptotal - swapfree; 12360860Sdes memshared = 0; 12460860Sdes for (object = TAILQ_FIRST(&vm_object_list); object != NULL; 12560860Sdes object = TAILQ_NEXT(object, object_list)) 12660860Sdes if (object->shadow_count > 1) 12760860Sdes memshared += object->resident_page_count; 12860860Sdes memshared *= PAGE_SIZE; 12959412Smsmith /* 13059412Smsmith * We'd love to be able to write: 13159412Smsmith * 13259412Smsmith buffers = bufspace; 13359412Smsmith * 13459412Smsmith * but bufspace is internal to vfs_bio.c and we don't feel 13559412Smsmith * like unstaticizing it just for linprocfs's sake. 13659412Smsmith */ 13759412Smsmith buffers = 0; 13859412Smsmith cached = cnt.v_cache_count * PAGE_SIZE; 13959412Smsmith 14059412Smsmith ps = psbuf; 14159412Smsmith ps += sprintf(ps, 14259412Smsmith " total: used: free: shared: buffers: cached:\n" 14359412Smsmith "Mem: %lu %lu %lu %lu %lu %lu\n" 14459412Smsmith "Swap: %lu %lu %lu\n" 14559412Smsmith "MemTotal: %9lu kB\n" 14659412Smsmith "MemFree: %9lu kB\n" 14759412Smsmith "MemShared:%9lu kB\n" 14859412Smsmith "Buffers: %9lu kB\n" 14959412Smsmith "Cached: %9lu kB\n" 15059412Smsmith "SwapTotal:%9lu kB\n" 15159412Smsmith "SwapFree: %9lu kB\n", 15259412Smsmith memtotal, memused, memfree, memshared, buffers, cached, 15359412Smsmith swaptotal, swapused, swapfree, 15467588Sdes B2K(memtotal), B2K(memfree), 15567588Sdes B2K(memshared), B2K(buffers), B2K(cached), 15667588Sdes B2K(swaptotal), B2K(swapfree)); 15759412Smsmith 15859412Smsmith xlen = ps - psbuf; 15959412Smsmith xlen -= uio->uio_offset; 16059412Smsmith ps = psbuf + uio->uio_offset; 16159412Smsmith xlen = imin(xlen, uio->uio_resid); 16265633Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 16359412Smsmith} 16459412Smsmith 16559412Smsmithint 16659412Smsmithlinprocfs_docpuinfo(curp, p, pfs, uio) 16759412Smsmith struct proc *curp; 16859412Smsmith struct proc *p; 16959412Smsmith struct pfsnode *pfs; 17059412Smsmith struct uio *uio; 17159412Smsmith{ 17259412Smsmith char *ps; 17359412Smsmith int xlen; 17459412Smsmith char psbuf[512]; /* XXX - conservative */ 17567589Sdes int class; 17667589Sdes int i; 17759412Smsmith#if 0 17859412Smsmith extern char *cpu_model; /* Yuck */ 17959412Smsmith#endif 18067589Sdes /* We default the flags to include all non-conflicting flags, 18167589Sdes and the Intel versions of conflicting flags. Note the space 18267589Sdes before each name; that is significant, and should be 18367589Sdes preserved. */ 18459412Smsmith 18567589Sdes static char *flags[] = { 18667589Sdes "fpu", "vme", "de", "pse", "tsc", 18767589Sdes "msr", "pae", "mce", "cx8", "apic", 18867589Sdes "sep", "sep", "mtrr", "pge", "mca", 18967589Sdes "cmov", "pat", "pse36", "pn", "b19", 19067589Sdes "b20", "b21", "mmxext", "mmx", "fxsr", 19167589Sdes "xmm", "b26", "b27", "b28", "b29", 19267589Sdes "3dnowext", "3dnow" 19367589Sdes }; 19467589Sdes 19559412Smsmith if (uio->uio_rw != UIO_READ) 19659412Smsmith return (EOPNOTSUPP); 19759412Smsmith 19859412Smsmith switch (cpu_class) { 19959412Smsmith case CPUCLASS_286: 20067589Sdes class = 2; 20159412Smsmith break; 20259412Smsmith case CPUCLASS_386: 20367589Sdes class = 3; 20459412Smsmith break; 20559412Smsmith case CPUCLASS_486: 20667589Sdes class = 4; 20759412Smsmith break; 20859412Smsmith case CPUCLASS_586: 20967589Sdes class = 5; 21059412Smsmith break; 21159412Smsmith case CPUCLASS_686: 21267589Sdes class = 6; 21359412Smsmith break; 21459412Smsmith default: 21567589Sdes class = 0; 21659412Smsmith break; 21759412Smsmith } 21859412Smsmith 21959412Smsmith ps = psbuf; 22059412Smsmith ps += sprintf(ps, 22159412Smsmith "processor : %d\n" 22259412Smsmith "vendor_id : %.20s\n" 22367589Sdes "cpu family : %d\n" 22467589Sdes "model : %d\n" 22559412Smsmith "stepping : %d\n", 22667589Sdes 0, cpu_vendor, class, cpu, cpu_id & 0xf); 22759412Smsmith 22867589Sdes ps += sprintf(ps, 22967589Sdes "flags :"); 23067589Sdes 23167589Sdes if (!strcmp(cpu_vendor, "AuthenticAMD") && (class < 6)) { 23267589Sdes flags[16] = "fcmov"; 23367589Sdes } else if (!strcmp(cpu_vendor, "CyrixInstead")) { 23467589Sdes flags[24] = "cxmmx"; 23567589Sdes } 23667589Sdes 23767589Sdes for (i = 0; i < 32; i++) 23867589Sdes if (cpu_feature & (1 << i)) 23967589Sdes ps += sprintf(ps, " %s", flags[i]); 24067589Sdes ps += sprintf(ps, "\n"); 24167589Sdes if (class >= 5) { 24267589Sdes ps += sprintf(ps, 24367589Sdes "cpu MHz : %d.%02d\n", 24467589Sdes (tsc_freq + 4999) / 1000000, 24567589Sdes ((tsc_freq + 4999) / 10000) % 100); 24667589Sdes } 24767589Sdes 24859412Smsmith xlen = ps - psbuf; 24959412Smsmith xlen -= uio->uio_offset; 25059412Smsmith ps = psbuf + uio->uio_offset; 25159412Smsmith xlen = imin(xlen, uio->uio_resid); 25265633Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 25359412Smsmith} 25465633Sdes 25565633Sdesint 25665633Sdeslinprocfs_dostat(curp, p, pfs, uio) 25765633Sdes struct proc *curp; 25865633Sdes struct proc *p; 25965633Sdes struct pfsnode *pfs; 26065633Sdes struct uio *uio; 26165633Sdes{ 26265633Sdes char *ps; 26365633Sdes char psbuf[512]; 26465633Sdes int xlen; 26565633Sdes 26665633Sdes ps = psbuf; 26765633Sdes ps += sprintf(ps, 26865633Sdes "cpu %ld %ld %ld %ld\n" 26965633Sdes "disk 0 0 0 0\n" 27065633Sdes "page %u %u\n" 27165633Sdes "swap %u %u\n" 27265633Sdes "intr %u\n" 27365633Sdes "ctxt %u\n" 27465633Sdes "btime %ld\n", 27565633Sdes T2J(cp_time[CP_USER]), 27665633Sdes T2J(cp_time[CP_NICE]), 27765633Sdes T2J(cp_time[CP_SYS] /*+ cp_time[CP_INTR]*/), 27865633Sdes T2J(cp_time[CP_IDLE]), 27965633Sdes cnt.v_vnodepgsin, 28065633Sdes cnt.v_vnodepgsout, 28165633Sdes cnt.v_swappgsin, 28265633Sdes cnt.v_swappgsout, 28365633Sdes cnt.v_intr, 28465633Sdes cnt.v_swtch, 28565633Sdes boottime.tv_sec); 28665633Sdes xlen = ps - psbuf; 28765633Sdes xlen -= uio->uio_offset; 28865633Sdes ps = psbuf + uio->uio_offset; 28965633Sdes xlen = imin(xlen, uio->uio_resid); 29065633Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 29165633Sdes} 29265633Sdes 29365633Sdesint 29465633Sdeslinprocfs_douptime(curp, p, pfs, uio) 29565633Sdes struct proc *curp; 29665633Sdes struct proc *p; 29765633Sdes struct pfsnode *pfs; 29865633Sdes struct uio *uio; 29965633Sdes{ 30065633Sdes char *ps; 30165633Sdes int xlen; 30265633Sdes char psbuf[64]; 30365633Sdes struct timeval tv; 30465633Sdes 30565633Sdes getmicrouptime(&tv); 30665633Sdes ps = psbuf; 30765633Sdes ps += sprintf(ps, "%ld.%02ld %ld.%02ld\n", 30865633Sdes tv.tv_sec, tv.tv_usec / 10000, 30965633Sdes T2S(cp_time[CP_IDLE]), T2J(cp_time[CP_IDLE]) % 100); 31065633Sdes xlen = ps - psbuf; 31165633Sdes xlen -= uio->uio_offset; 31265633Sdes ps = psbuf + uio->uio_offset; 31365633Sdes xlen = imin(xlen, uio->uio_resid); 31465633Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 31565633Sdes} 31665633Sdes 31765633Sdesint 31865633Sdeslinprocfs_doversion(curp, p, pfs, uio) 31965633Sdes struct proc *curp; 32065633Sdes struct proc *p; 32165633Sdes struct pfsnode *pfs; 32265633Sdes struct uio *uio; 32365633Sdes{ 32465633Sdes char *ps; 32565633Sdes int xlen; 32665633Sdes 32765633Sdes ps = version; /* XXX not entirely correct */ 32865633Sdes for (xlen = 0; ps[xlen] != '\n'; ++xlen) 32965633Sdes /* nothing */ ; 33065633Sdes ++xlen; 33165633Sdes xlen -= uio->uio_offset; 33265633Sdes ps += uio->uio_offset; 33365633Sdes xlen = imin(xlen, uio->uio_resid); 33465633Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 33565633Sdes} 33665633Sdes 33767588Sdesint 33867588Sdeslinprocfs_doprocstat(curp, p, pfs, uio) 33967588Sdes struct proc *curp; 34067588Sdes struct proc *p; 34167588Sdes struct pfsnode *pfs; 34267588Sdes struct uio *uio; 34367588Sdes{ 34467588Sdes char *ps, psbuf[1024]; 34567588Sdes int xlen; 34667588Sdes 34767588Sdes ps = psbuf; 34867588Sdes ps += sprintf(ps, "%d", p->p_pid); 34967588Sdes#define PS_ADD(name, fmt, arg) ps += sprintf(ps, " " fmt, arg) 35067588Sdes PS_ADD("comm", "(%s)", p->p_comm); 35167588Sdes PS_ADD("statr", "%c", '0'); /* XXX */ 35267588Sdes PS_ADD("ppid", "%d", p->p_pptr->p_pid); 35367588Sdes PS_ADD("pgrp", "%d", p->p_pgid); 35467588Sdes PS_ADD("session", "%d", p->p_session->s_sid); 35567588Sdes PS_ADD("tty", "%d", 0); /* XXX */ 35667588Sdes PS_ADD("tpgid", "%d", 0); /* XXX */ 35767588Sdes PS_ADD("flags", "%u", 0); /* XXX */ 35867588Sdes PS_ADD("minflt", "%u", 0); /* XXX */ 35967588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 36067588Sdes PS_ADD("majflt", "%u", 0); /* XXX */ 36167588Sdes PS_ADD("cminflt", "%u", 0); /* XXX */ 36267588Sdes PS_ADD("utime", "%d", 0); /* XXX */ 36367588Sdes PS_ADD("stime", "%d", 0); /* XXX */ 36467588Sdes PS_ADD("cutime", "%d", 0); /* XXX */ 36567588Sdes PS_ADD("cstime", "%d", 0); /* XXX */ 36667588Sdes PS_ADD("counter", "%d", 0); /* XXX */ 36767588Sdes PS_ADD("priority", "%d", 0); /* XXX */ 36867588Sdes PS_ADD("timeout", "%u", 0); /* XXX */ 36967588Sdes PS_ADD("itrealvalue", "%u", 0); /* XXX */ 37067588Sdes PS_ADD("starttime", "%d", 0); /* XXX */ 37167588Sdes PS_ADD("vsize", "%u", 0); /* XXX */ 37267588Sdes PS_ADD("rss", "%u", 0); /* XXX */ 37367588Sdes PS_ADD("rlim", "%u", 0); /* XXX */ 37467588Sdes PS_ADD("startcode", "%u", 0); /* XXX */ 37567588Sdes PS_ADD("endcode", "%u", 0); /* XXX */ 37667588Sdes PS_ADD("startstack", "%u", 0); /* XXX */ 37767588Sdes PS_ADD("kstkesp", "%u", 0); /* XXX */ 37867588Sdes PS_ADD("kstkeip", "%u", 0); /* XXX */ 37967588Sdes PS_ADD("signal", "%d", 0); /* XXX */ 38067588Sdes PS_ADD("blocked", "%d", 0); /* XXX */ 38167588Sdes PS_ADD("sigignore", "%d", 0); /* XXX */ 38267588Sdes PS_ADD("sigcatch", "%d", 0); /* XXX */ 38367588Sdes PS_ADD("wchan", "%u", 0); /* XXX */ 38467588Sdes#undef PS_ADD 38567588Sdes ps += sprintf(ps, "\n"); 38667588Sdes 38767588Sdes xlen = ps - psbuf; 38867588Sdes xlen -= uio->uio_offset; 38967588Sdes ps = psbuf + uio->uio_offset; 39067588Sdes xlen = imin(xlen, uio->uio_resid); 39167588Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 39267588Sdes} 39367588Sdes 39467588Sdes/* 39567588Sdes * Map process state to descriptive letter. Note that this does not 39667588Sdes * quite correspond to what Linux outputs, but it's close enough. 39767588Sdes */ 39867588Sdesstatic char *state_str[] = { 39967588Sdes "? (unknown)", 40067588Sdes "I (idle)", 40167588Sdes "R (running)", 40267588Sdes "S (sleeping)", 40367588Sdes "T (stopped)", 40467588Sdes "Z (zombie)", 40567588Sdes "W (waiting)", 40667588Sdes "M (mutex)" 40767588Sdes}; 40867588Sdes 40967588Sdesint 41067588Sdeslinprocfs_doprocstatus(curp, p, pfs, uio) 41167588Sdes struct proc *curp; 41267588Sdes struct proc *p; 41367588Sdes struct pfsnode *pfs; 41467588Sdes struct uio *uio; 41567588Sdes{ 41667588Sdes char *ps, psbuf[1024]; 41767588Sdes char *state; 41867588Sdes int i, xlen; 41967588Sdes 42067588Sdes ps = psbuf; 42167588Sdes 42267588Sdes if (p->p_stat > sizeof state_str / sizeof *state_str) 42367588Sdes state = state_str[0]; 42467588Sdes else 42567588Sdes state = state_str[(int)p->p_stat]; 42667588Sdes 42767588Sdes#define PS_ADD ps += sprintf 42867588Sdes PS_ADD(ps, "Name:\t%s\n", p->p_comm); /* XXX escape */ 42967588Sdes PS_ADD(ps, "State:\t%s\n", state); 43067588Sdes 43167588Sdes /* 43267588Sdes * Credentials 43367588Sdes */ 43467588Sdes PS_ADD(ps, "Pid:\t%d\n", p->p_pid); 43567588Sdes PS_ADD(ps, "PPid:\t%d\n", p->p_pptr->p_pid); 43667588Sdes PS_ADD(ps, "Uid:\t%d %d %d %d\n", p->p_cred->p_ruid, 43767588Sdes p->p_ucred->cr_uid, 43867588Sdes p->p_cred->p_svuid, 43967588Sdes /* FreeBSD doesn't have fsuid */ 44067588Sdes p->p_ucred->cr_uid); 44167588Sdes PS_ADD(ps, "Gid:\t%d %d %d %d\n", p->p_cred->p_rgid, 44267588Sdes p->p_ucred->cr_gid, 44367588Sdes p->p_cred->p_svgid, 44467588Sdes /* FreeBSD doesn't have fsgid */ 44567588Sdes p->p_ucred->cr_gid); 44667588Sdes PS_ADD(ps, "Groups:\t"); 44767588Sdes for (i = 0; i < p->p_ucred->cr_ngroups; i++) 44867588Sdes PS_ADD(ps, "%d ", p->p_ucred->cr_groups[i]); 44967588Sdes PS_ADD(ps, "\n"); 45067588Sdes 45167588Sdes /* 45267588Sdes * Memory 45367588Sdes */ 45467588Sdes PS_ADD(ps, "VmSize:\t%8u kB\n", B2K(p->p_vmspace->vm_map.size)); 45567588Sdes PS_ADD(ps, "VmLck:\t%8u kB\n", P2K(0)); /* XXX */ 45667588Sdes /* XXX vm_rssize seems to always be zero, how can this be? */ 45767588Sdes PS_ADD(ps, "VmRss:\t%8u kB\n", P2K(p->p_vmspace->vm_rssize)); 45867588Sdes PS_ADD(ps, "VmData:\t%8u kB\n", P2K(p->p_vmspace->vm_dsize)); 45967588Sdes PS_ADD(ps, "VmStk:\t%8u kB\n", P2K(p->p_vmspace->vm_ssize)); 46067588Sdes PS_ADD(ps, "VmExe:\t%8u kB\n", P2K(p->p_vmspace->vm_tsize)); 46167588Sdes PS_ADD(ps, "VmLib:\t%8u kB\n", P2K(0)); /* XXX */ 46267588Sdes 46367588Sdes /* 46467588Sdes * Signal masks 46567588Sdes * 46667588Sdes * We support up to 128 signals, while Linux supports 32, 46767588Sdes * but we only define 32 (the same 32 as Linux, to boot), so 46867588Sdes * just show the lower 32 bits of each mask. XXX hack. 46967588Sdes * 47067588Sdes * NB: on certain platforms (Sparc at least) Linux actually 47167588Sdes * supports 64 signals, but this code is a long way from 47267588Sdes * running on anything but i386, so ignore that for now. 47367588Sdes */ 47467588Sdes PS_ADD(ps, "SigPnd:\t%08x\n", p->p_siglist.__bits[0]); 47567588Sdes PS_ADD(ps, "SigBlk:\t%08x\n", 0); /* XXX */ 47667588Sdes PS_ADD(ps, "SigIgn:\t%08x\n", p->p_sigignore.__bits[0]); 47767588Sdes PS_ADD(ps, "SigCgt:\t%08x\n", p->p_sigcatch.__bits[0]); 47867588Sdes 47967588Sdes /* 48067588Sdes * Linux also prints the capability masks, but we don't have 48167588Sdes * capabilities yet, and when we do get them they're likely to 48267588Sdes * be meaningless to Linux programs, so we lie. XXX 48367588Sdes */ 48467588Sdes PS_ADD(ps, "CapInh:\t%016x\n", 0); 48567588Sdes PS_ADD(ps, "CapPrm:\t%016x\n", 0); 48667588Sdes PS_ADD(ps, "CapEff:\t%016x\n", 0); 48767588Sdes#undef PS_ADD 48867588Sdes 48967588Sdes xlen = ps - psbuf; 49067588Sdes xlen -= uio->uio_offset; 49167588Sdes ps = psbuf + uio->uio_offset; 49267588Sdes xlen = imin(xlen, uio->uio_resid); 49367588Sdes return (xlen <= 0 ? 0 : uiomove(ps, xlen, uio)); 49467588Sdes} 495