1df8bae1dSRodney W. Grimes /* 2df8bae1dSRodney W. Grimes * Copyright (c) 1993 Jan-Simon Pendry 3df8bae1dSRodney W. Grimes * Copyright (c) 1993 4df8bae1dSRodney W. Grimes * The Regents of the University of California. All rights reserved. 5df8bae1dSRodney W. Grimes * 6df8bae1dSRodney W. Grimes * This code is derived from software contributed to Berkeley by 7df8bae1dSRodney W. Grimes * Jan-Simon Pendry. 8df8bae1dSRodney W. Grimes * 9df8bae1dSRodney W. Grimes * Redistribution and use in source and binary forms, with or without 10df8bae1dSRodney W. Grimes * modification, are permitted provided that the following conditions 11df8bae1dSRodney W. Grimes * are met: 12df8bae1dSRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 13df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer. 14df8bae1dSRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 15df8bae1dSRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 16df8bae1dSRodney W. Grimes * documentation and/or other materials provided with the distribution. 17df8bae1dSRodney W. Grimes * 3. All advertising materials mentioning features or use of this software 18df8bae1dSRodney W. Grimes * must display the following acknowledgement: 19df8bae1dSRodney W. Grimes * This product includes software developed by the University of 20df8bae1dSRodney W. Grimes * California, Berkeley and its contributors. 21df8bae1dSRodney W. Grimes * 4. Neither the name of the University nor the names of its contributors 22df8bae1dSRodney W. Grimes * may be used to endorse or promote products derived from this software 23df8bae1dSRodney W. Grimes * without specific prior written permission. 24df8bae1dSRodney W. Grimes * 25df8bae1dSRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 26df8bae1dSRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 27df8bae1dSRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 28df8bae1dSRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 29df8bae1dSRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30df8bae1dSRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31df8bae1dSRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32df8bae1dSRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33df8bae1dSRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34df8bae1dSRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35df8bae1dSRodney W. Grimes * SUCH DAMAGE. 36df8bae1dSRodney W. Grimes * 37996c772fSJohn Dyson * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 38df8bae1dSRodney W. Grimes * 39996c772fSJohn Dyson * From: 40c3aac50fSPeter Wemm * $FreeBSD$ 41df8bae1dSRodney W. Grimes */ 42df8bae1dSRodney W. Grimes 43df8bae1dSRodney W. Grimes #include <sys/param.h> 44df8bae1dSRodney W. Grimes #include <sys/systm.h> 45fb919e4dSMark Murray #include <sys/exec.h> 46fb919e4dSMark Murray #include <sys/lock.h> 47fb919e4dSMark Murray #include <sys/mutex.h> 4801137630SRobert Watson #include <sys/jail.h> 4901137630SRobert Watson #include <sys/malloc.h> 50fb919e4dSMark Murray #include <sys/proc.h> 51df8bae1dSRodney W. Grimes #include <sys/resourcevar.h> 52fb919e4dSMark Murray #include <sys/tty.h> 53fb919e4dSMark Murray #include <sys/vnode.h> 54df8bae1dSRodney W. Grimes 5563a99273SMarcel Moolenaar #include <vm/vm.h> 5663a99273SMarcel Moolenaar #include <vm/pmap.h> 5763a99273SMarcel Moolenaar #include <vm/vm_param.h> 58fb919e4dSMark Murray 5999d300a1SRuslan Ermilov #include <fs/procfs/procfs.h> 6063a99273SMarcel Moolenaar 61b8c8516aSEivind Eklund #define DOCHECK() do { if (ps >= psbuf+sizeof(psbuf)) goto bailout; } while (0) 62df8bae1dSRodney W. Grimes int 63df8bae1dSRodney W. Grimes procfs_dostatus(curp, p, pfs, uio) 64df8bae1dSRodney W. Grimes struct proc *curp; 65df8bae1dSRodney W. Grimes struct proc *p; 66df8bae1dSRodney W. Grimes struct pfsnode *pfs; 67df8bae1dSRodney W. Grimes struct uio *uio; 68df8bae1dSRodney W. Grimes { 69df8bae1dSRodney W. Grimes struct session *sess; 70df8bae1dSRodney W. Grimes struct tty *tp; 71df8bae1dSRodney W. Grimes struct ucred *cr; 723273a63eSMike Barcroft char *ps, *pc; 73df8bae1dSRodney W. Grimes char *sep; 74df8bae1dSRodney W. Grimes int pid, ppid, pgid, sid; 75df8bae1dSRodney W. Grimes int i; 76df8bae1dSRodney W. Grimes int xlen; 77df8bae1dSRodney W. Grimes int error; 78b8c8516aSEivind Eklund char psbuf[256]; /* XXX - conservative */ 79df8bae1dSRodney W. Grimes 80df8bae1dSRodney W. Grimes if (uio->uio_rw != UIO_READ) 81df8bae1dSRodney W. Grimes return (EOPNOTSUPP); 82df8bae1dSRodney W. Grimes 83df8bae1dSRodney W. Grimes pid = p->p_pid; 8430ac5d0fSJohn Baldwin PROC_LOCK(p); 85e0f9d286SPeter Wemm ppid = p->p_pptr ? p->p_pptr->p_pid : 0; 8630ac5d0fSJohn Baldwin PROC_UNLOCK(p); 87df8bae1dSRodney W. Grimes pgid = p->p_pgrp->pg_id; 88df8bae1dSRodney W. Grimes sess = p->p_pgrp->pg_session; 89df8bae1dSRodney W. Grimes sid = sess->s_leader ? sess->s_leader->p_pid : 0; 90df8bae1dSRodney W. Grimes 911d08058fSWolfram Schneider /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg 921d08058fSWolfram Schneider euid ruid rgid,egid,groups[1 .. NGROUPS] 931d08058fSWolfram Schneider */ 94b8c8516aSEivind Eklund KASSERT(sizeof(psbuf) > MAXCOMLEN, 95b8c8516aSEivind Eklund ("Too short buffer for new MAXCOMLEN")); 96b8c8516aSEivind Eklund 97df8bae1dSRodney W. Grimes ps = psbuf; 983273a63eSMike Barcroft pc = p->p_comm; 993273a63eSMike Barcroft xlen = strlen(p->p_comm); 1003273a63eSMike Barcroft do { 1013273a63eSMike Barcroft if (*pc < 33 || *pc > 126 || *pc == '\\') 1023273a63eSMike Barcroft ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\\%03o", 1033273a63eSMike Barcroft *pc); 1043273a63eSMike Barcroft else 1053273a63eSMike Barcroft *ps++ = *pc; 106b8c8516aSEivind Eklund DOCHECK(); 1073273a63eSMike Barcroft } while (++pc < p->p_comm + xlen); 108b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 109b8c8516aSEivind Eklund " %d %d %d %d ", pid, ppid, pgid, sid); 110b8c8516aSEivind Eklund DOCHECK(); 111df8bae1dSRodney W. Grimes if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp)) 112b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 113b8c8516aSEivind Eklund "%d,%d ", major(tp->t_dev), minor(tp->t_dev)); 114df8bae1dSRodney W. Grimes else 115b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 116b8c8516aSEivind Eklund "%d,%d ", -1, -1); 117b8c8516aSEivind Eklund DOCHECK(); 118df8bae1dSRodney W. Grimes 119df8bae1dSRodney W. Grimes sep = ""; 120df8bae1dSRodney W. Grimes if (sess->s_ttyvp) { 121b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%sctty", sep); 122df8bae1dSRodney W. Grimes sep = ","; 123b8c8516aSEivind Eklund DOCHECK(); 124df8bae1dSRodney W. Grimes } 125df8bae1dSRodney W. Grimes if (SESS_LEADER(p)) { 126b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%ssldr", sep); 127df8bae1dSRodney W. Grimes sep = ","; 128b8c8516aSEivind Eklund DOCHECK(); 129df8bae1dSRodney W. Grimes } 130b8c8516aSEivind Eklund if (*sep != ',') { 131b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "noflags"); 132b8c8516aSEivind Eklund DOCHECK(); 133b8c8516aSEivind Eklund } 134df8bae1dSRodney W. Grimes 1359ed346baSBosko Milekic mtx_lock_spin(&sched_lock); 136b9393356SJohn Baldwin if (p->p_sflag & PS_INMEM) { 137df8bae1dSRodney W. Grimes struct timeval ut, st; 138df8bae1dSRodney W. Grimes 1399d3a4425SDmitrij Tejblum calcru(p, &ut, &st, (struct timeval *) NULL); 1409ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 141b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 1424ff021c6SPeter Wemm " %lld,%ld %ld,%ld %ld,%ld", 1434ff021c6SPeter Wemm (long long)p->p_stats->p_start.tv_sec, 1449d3a4425SDmitrij Tejblum p->p_stats->p_start.tv_usec, 1454ff021c6SPeter Wemm (long)ut.tv_sec, ut.tv_usec, 1464ff021c6SPeter Wemm (long)st.tv_sec, st.tv_usec); 147b9393356SJohn Baldwin } else { 1489ed346baSBosko Milekic mtx_unlock_spin(&sched_lock); 149b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 150b8c8516aSEivind Eklund " -1,-1 -1,-1 -1,-1"); 151b9393356SJohn Baldwin } 152b8c8516aSEivind Eklund DOCHECK(); 153df8bae1dSRodney W. Grimes 154b40ce416SJulian Elischer if (p->p_flag & P_KSES) { 155b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s", 156b40ce416SJulian Elischer "-kse- "); 157b40ce416SJulian Elischer } else { 158b40ce416SJulian Elischer ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s", 159b40ce416SJulian Elischer (p->p_thread.td_wchan && p->p_thread.td_wmesg) ? 160b40ce416SJulian Elischer p->p_thread.td_wmesg : "nochan"); 161b40ce416SJulian Elischer } 162b8c8516aSEivind Eklund DOCHECK(); 163df8bae1dSRodney W. Grimes 164df8bae1dSRodney W. Grimes cr = p->p_ucred; 165df8bae1dSRodney W. Grimes 166b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", 167ac1e407bSBruce Evans (u_long)cr->cr_uid, 168b1fc0ec1SRobert Watson (u_long)cr->cr_ruid, 169b1fc0ec1SRobert Watson (u_long)cr->cr_rgid); 170b8c8516aSEivind Eklund DOCHECK(); 1711d08058fSWolfram Schneider 172b1fc0ec1SRobert Watson /* egid (cr->cr_svgid) is equal to cr_ngroups[0] 1731d08058fSWolfram Schneider see also getegid(2) in /sys/kern/kern_prot.c */ 1741d08058fSWolfram Schneider 175b8c8516aSEivind Eklund for (i = 0; i < cr->cr_ngroups; i++) { 176b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 177b8c8516aSEivind Eklund ",%lu", (u_long)cr->cr_groups[i]); 178b8c8516aSEivind Eklund DOCHECK(); 179b8c8516aSEivind Eklund } 18075c13541SPoul-Henning Kamp 18101137630SRobert Watson if (jailed(p->p_ucred)) { 18201137630SRobert Watson mtx_lock(&p->p_ucred->cr_prison->pr_mtx); 183b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 18491421ba2SRobert Watson " %s", p->p_ucred->cr_prison->pr_host); 18501137630SRobert Watson mtx_unlock(&p->p_ucred->cr_prison->pr_mtx); 18601137630SRobert Watson } else { 187b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " -"); 18801137630SRobert Watson } 189b8c8516aSEivind Eklund DOCHECK(); 190b8c8516aSEivind Eklund ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n"); 191b8c8516aSEivind Eklund DOCHECK(); 192df8bae1dSRodney W. Grimes 193df8bae1dSRodney W. Grimes xlen = ps - psbuf; 194df8bae1dSRodney W. Grimes xlen -= uio->uio_offset; 195df8bae1dSRodney W. Grimes ps = psbuf + uio->uio_offset; 196996c772fSJohn Dyson xlen = imin(xlen, uio->uio_resid); 197df8bae1dSRodney W. Grimes if (xlen <= 0) 198df8bae1dSRodney W. Grimes error = 0; 199df8bae1dSRodney W. Grimes else 200df8bae1dSRodney W. Grimes error = uiomove(ps, xlen, uio); 201df8bae1dSRodney W. Grimes 202df8bae1dSRodney W. Grimes return (error); 203b8c8516aSEivind Eklund 204b8c8516aSEivind Eklund bailout: 205b8c8516aSEivind Eklund return (ENOMEM); 206df8bae1dSRodney W. Grimes } 20775ba7757SPeter Wemm 20875ba7757SPeter Wemm int 20975ba7757SPeter Wemm procfs_docmdline(curp, p, pfs, uio) 21075ba7757SPeter Wemm struct proc *curp; 21175ba7757SPeter Wemm struct proc *p; 21275ba7757SPeter Wemm struct pfsnode *pfs; 21375ba7757SPeter Wemm struct uio *uio; 21475ba7757SPeter Wemm { 21575ba7757SPeter Wemm char *ps; 21675ba7757SPeter Wemm int xlen; 21775ba7757SPeter Wemm int error; 2186153cb20SPoul-Henning Kamp char *buf, *bp; 2196153cb20SPoul-Henning Kamp int buflen; 22063a99273SMarcel Moolenaar struct ps_strings pstr; 22163a99273SMarcel Moolenaar int i; 22263a99273SMarcel Moolenaar size_t bytes_left, done; 22363a99273SMarcel Moolenaar 22475ba7757SPeter Wemm if (uio->uio_rw != UIO_READ) 22575ba7757SPeter Wemm return (EOPNOTSUPP); 22675ba7757SPeter Wemm 22775ba7757SPeter Wemm /* 2286153cb20SPoul-Henning Kamp * If we are using the ps/cmdline caching, use that. Otherwise 2296153cb20SPoul-Henning Kamp * revert back to the old way which only implements full cmdline 2306153cb20SPoul-Henning Kamp * for the currept process and just p->p_comm for all other 2316153cb20SPoul-Henning Kamp * processes. 23263a99273SMarcel Moolenaar * Note that if the argv is no longer available, we deliberately 23363a99273SMarcel Moolenaar * don't fall back on p->p_comm or return an error: the authentic 23463a99273SMarcel Moolenaar * Linux behaviour is to return zero-length in this case. 23575ba7757SPeter Wemm */ 23663a99273SMarcel Moolenaar 237a0f75161SRobert Watson if (p->p_args && (ps_argsopen || !p_cansee(curp, p))) { 2386153cb20SPoul-Henning Kamp bp = p->p_args->ar_args; 2396153cb20SPoul-Henning Kamp buflen = p->p_args->ar_length; 2406153cb20SPoul-Henning Kamp buf = 0; 2416153cb20SPoul-Henning Kamp } else if (p != curp) { 2426153cb20SPoul-Henning Kamp bp = p->p_comm; 2436153cb20SPoul-Henning Kamp buflen = MAXCOMLEN; 2446153cb20SPoul-Henning Kamp buf = 0; 2456153cb20SPoul-Henning Kamp } else { 2466153cb20SPoul-Henning Kamp buflen = 256; 2476153cb20SPoul-Henning Kamp MALLOC(buf, char *, buflen + 1, M_TEMP, M_WAITOK); 2486153cb20SPoul-Henning Kamp bp = buf; 2496153cb20SPoul-Henning Kamp ps = buf; 25063a99273SMarcel Moolenaar error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr)); 2516153cb20SPoul-Henning Kamp if (error) { 2526153cb20SPoul-Henning Kamp FREE(buf, M_TEMP); 25363a99273SMarcel Moolenaar return (error); 2546153cb20SPoul-Henning Kamp } 2556153cb20SPoul-Henning Kamp bytes_left = buflen; 25663a99273SMarcel Moolenaar for (i = 0; bytes_left && (i < pstr.ps_nargvstr); i++) { 25763a99273SMarcel Moolenaar error = copyinstr(pstr.ps_argvstr[i], ps, 25863a99273SMarcel Moolenaar bytes_left, &done); 25963a99273SMarcel Moolenaar /* If too long or malformed, just truncate */ 26063a99273SMarcel Moolenaar if (error) { 26163a99273SMarcel Moolenaar error = 0; 26263a99273SMarcel Moolenaar break; 26363a99273SMarcel Moolenaar } 26463a99273SMarcel Moolenaar ps += done; 26563a99273SMarcel Moolenaar bytes_left -= done; 26663a99273SMarcel Moolenaar } 2676153cb20SPoul-Henning Kamp buflen = ps - buf; 26863a99273SMarcel Moolenaar } 26975ba7757SPeter Wemm 2706153cb20SPoul-Henning Kamp buflen -= uio->uio_offset; 2716153cb20SPoul-Henning Kamp ps = bp + uio->uio_offset; 2726153cb20SPoul-Henning Kamp xlen = min(buflen, uio->uio_resid); 27375ba7757SPeter Wemm if (xlen <= 0) 27475ba7757SPeter Wemm error = 0; 27575ba7757SPeter Wemm else 27675ba7757SPeter Wemm error = uiomove(ps, xlen, uio); 2776153cb20SPoul-Henning Kamp if (buf) 2786153cb20SPoul-Henning Kamp FREE(buf, M_TEMP); 27975ba7757SPeter Wemm return (error); 28075ba7757SPeter Wemm } 281