procfs_status.c (87275) | procfs_status.c (87321) |
---|---|
1/* 2 * Copyright (c) 1993 Jan-Simon Pendry 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * --- 23 unchanged lines hidden (view full) --- 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 38 * 39 * From: | 1/* 2 * Copyright (c) 1993 Jan-Simon Pendry 3 * Copyright (c) 1993 4 * The Regents of the University of California. All rights reserved. 5 * 6 * This code is derived from software contributed to Berkeley by 7 * Jan-Simon Pendry. 8 * --- 23 unchanged lines hidden (view full) --- 32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 35 * SUCH DAMAGE. 36 * 37 * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94 38 * 39 * From: |
40 * $FreeBSD: head/sys/fs/procfs/procfs_status.c 87275 2001-12-03 16:12:27Z rwatson $ | 40 * $FreeBSD: head/sys/fs/procfs/procfs_status.c 87321 2001-12-04 01:35:06Z des $ |
41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/exec.h> 46#include <sys/lock.h> 47#include <sys/mutex.h> 48#include <sys/jail.h> 49#include <sys/malloc.h> 50#include <sys/proc.h> 51#include <sys/resourcevar.h> | 41 */ 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/exec.h> 46#include <sys/lock.h> 47#include <sys/mutex.h> 48#include <sys/jail.h> 49#include <sys/malloc.h> 50#include <sys/proc.h> 51#include <sys/resourcevar.h> |
52#include <sys/sbuf.h> |
|
52#include <sys/tty.h> | 53#include <sys/tty.h> |
53#include <sys/vnode.h> | |
54 55#include <vm/vm.h> 56#include <vm/pmap.h> 57#include <vm/vm_param.h> 58 | 54 55#include <vm/vm.h> 56#include <vm/pmap.h> 57#include <vm/vm_param.h> 58 |
59#include <fs/pseudofs/pseudofs.h> |
|
59#include <fs/procfs/procfs.h> 60 | 60#include <fs/procfs/procfs.h> 61 |
61#define DOCHECK() do { if (ps >= psbuf+sizeof(psbuf)) goto bailout; } while (0) | |
62int | 62int |
63procfs_dostatus(curp, p, pfs, uio) 64 struct proc *curp; 65 struct proc *p; 66 struct pfsnode *pfs; 67 struct uio *uio; | 63procfs_doprocstatus(PFS_FILL_ARGS) |
68{ 69 struct session *sess; 70 struct tty *tp; 71 struct ucred *cr; | 64{ 65 struct session *sess; 66 struct tty *tp; 67 struct ucred *cr; |
72 char *ps, *pc; | 68 char *pc; |
73 char *sep; 74 int pid, ppid, pgid, sid; 75 int i; | 69 char *sep; 70 int pid, ppid, pgid, sid; 71 int i; |
76 int xlen; 77 int error; 78 char psbuf[256]; /* XXX - conservative */ | |
79 | 72 |
80 if (uio->uio_rw != UIO_READ) 81 return (EOPNOTSUPP); 82 | |
83 pid = p->p_pid; 84 PROC_LOCK(p); 85 ppid = p->p_pptr ? p->p_pptr->p_pid : 0; 86 PROC_UNLOCK(p); 87 pgid = p->p_pgrp->pg_id; 88 sess = p->p_pgrp->pg_session; 89 sid = sess->s_leader ? sess->s_leader->p_pid : 0; 90 91/* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg 92 euid ruid rgid,egid,groups[1 .. NGROUPS] 93*/ | 73 pid = p->p_pid; 74 PROC_LOCK(p); 75 ppid = p->p_pptr ? p->p_pptr->p_pid : 0; 76 PROC_UNLOCK(p); 77 pgid = p->p_pgrp->pg_id; 78 sess = p->p_pgrp->pg_session; 79 sid = sess->s_leader ? sess->s_leader->p_pid : 0; 80 81/* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg 82 euid ruid rgid,egid,groups[1 .. NGROUPS] 83*/ |
94 KASSERT(sizeof(psbuf) > MAXCOMLEN, 95 ("Too short buffer for new MAXCOMLEN")); | |
96 | 84 |
97 ps = psbuf; | |
98 pc = p->p_comm; | 85 pc = p->p_comm; |
99 xlen = strlen(p->p_comm); | |
100 do { 101 if (*pc < 33 || *pc > 126 || *pc == '\\') | 86 do { 87 if (*pc < 33 || *pc > 126 || *pc == '\\') |
102 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\\%03o", 103 *pc); | 88 sbuf_printf(sb, "\\%03o", *pc); |
104 else | 89 else |
105 *ps++ = *pc; 106 DOCHECK(); 107 } while (++pc < p->p_comm + xlen); 108 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 109 " %d %d %d %d ", pid, ppid, pgid, sid); 110 DOCHECK(); | 90 sbuf_putc(sb, *pc); 91 } while (*++pc); 92 sbuf_printf(sb, " %d %d %d %d ", pid, ppid, pgid, sid); |
111 if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp)) | 93 if ((p->p_flag&P_CONTROLT) && (tp = sess->s_ttyp)) |
112 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 113 "%d,%d ", major(tp->t_dev), minor(tp->t_dev)); | 94 sbuf_printf(sb, "%d,%d ", major(tp->t_dev), minor(tp->t_dev)); |
114 else | 95 else |
115 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 116 "%d,%d ", -1, -1); 117 DOCHECK(); | 96 sbuf_printf(sb, "%d,%d ", -1, -1); |
118 119 sep = ""; 120 if (sess->s_ttyvp) { | 97 98 sep = ""; 99 if (sess->s_ttyvp) { |
121 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%sctty", sep); | 100 sbuf_printf(sb, "%sctty", sep); |
122 sep = ","; | 101 sep = ","; |
123 DOCHECK(); | |
124 } 125 if (SESS_LEADER(p)) { | 102 } 103 if (SESS_LEADER(p)) { |
126 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "%ssldr", sep); | 104 sbuf_printf(sb, "%ssldr", sep); |
127 sep = ","; | 105 sep = ","; |
128 DOCHECK(); | |
129 } 130 if (*sep != ',') { | 106 } 107 if (*sep != ',') { |
131 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "noflags"); 132 DOCHECK(); | 108 sbuf_printf(sb, "noflags"); |
133 } 134 135 mtx_lock_spin(&sched_lock); 136 if (p->p_sflag & PS_INMEM) { 137 struct timeval ut, st; 138 139 calcru(p, &ut, &st, (struct timeval *) NULL); 140 mtx_unlock_spin(&sched_lock); | 109 } 110 111 mtx_lock_spin(&sched_lock); 112 if (p->p_sflag & PS_INMEM) { 113 struct timeval ut, st; 114 115 calcru(p, &ut, &st, (struct timeval *) NULL); 116 mtx_unlock_spin(&sched_lock); |
141 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 142 " %lld,%ld %ld,%ld %ld,%ld", | 117 sbuf_printf(sb, " %lld,%ld %ld,%ld %ld,%ld", |
143 (long long)p->p_stats->p_start.tv_sec, 144 p->p_stats->p_start.tv_usec, | 118 (long long)p->p_stats->p_start.tv_sec, 119 p->p_stats->p_start.tv_usec, |
145 (long)ut.tv_sec, ut.tv_usec, 146 (long)st.tv_sec, st.tv_usec); | 120 ut.tv_sec, ut.tv_usec, 121 st.tv_sec, st.tv_usec); |
147 } else { 148 mtx_unlock_spin(&sched_lock); | 122 } else { 123 mtx_unlock_spin(&sched_lock); |
149 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 150 " -1,-1 -1,-1 -1,-1"); | 124 sbuf_printf(sb, " -1,-1 -1,-1 -1,-1"); |
151 } | 125 } |
152 DOCHECK(); | |
153 154 if (p->p_flag & P_KSES) { | 126 127 if (p->p_flag & P_KSES) { |
155 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s", 156 "-kse- "); | 128 sbuf_printf(sb, " %s", "-kse- "); |
157 } else { | 129 } else { |
158 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %s", | 130 sbuf_printf(sb, " %s", |
159 (p->p_thread.td_wchan && p->p_thread.td_wmesg) ? 160 p->p_thread.td_wmesg : "nochan"); 161 } | 131 (p->p_thread.td_wchan && p->p_thread.td_wmesg) ? 132 p->p_thread.td_wmesg : "nochan"); 133 } |
162 DOCHECK(); | |
163 164 cr = p->p_ucred; 165 | 134 135 cr = p->p_ucred; 136 |
166 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " %lu %lu %lu", | 137 sbuf_printf(sb, " %lu %lu %lu", |
167 (u_long)cr->cr_uid, 168 (u_long)cr->cr_ruid, 169 (u_long)cr->cr_rgid); | 138 (u_long)cr->cr_uid, 139 (u_long)cr->cr_ruid, 140 (u_long)cr->cr_rgid); |
170 DOCHECK(); | |
171 172 /* egid (cr->cr_svgid) is equal to cr_ngroups[0] 173 see also getegid(2) in /sys/kern/kern_prot.c */ 174 175 for (i = 0; i < cr->cr_ngroups; i++) { | 141 142 /* egid (cr->cr_svgid) is equal to cr_ngroups[0] 143 see also getegid(2) in /sys/kern/kern_prot.c */ 144 145 for (i = 0; i < cr->cr_ngroups; i++) { |
176 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 177 ",%lu", (u_long)cr->cr_groups[i]); 178 DOCHECK(); | 146 sbuf_printf(sb, ",%lu", (u_long)cr->cr_groups[i]); |
179 } 180 181 if (jailed(p->p_ucred)) { 182 mtx_lock(&p->p_ucred->cr_prison->pr_mtx); | 147 } 148 149 if (jailed(p->p_ucred)) { 150 mtx_lock(&p->p_ucred->cr_prison->pr_mtx); |
183 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, 184 " %s", p->p_ucred->cr_prison->pr_host); | 151 sbuf_printf(sb, " %s", p->p_ucred->cr_prison->pr_host); |
185 mtx_unlock(&p->p_ucred->cr_prison->pr_mtx); 186 } else { | 152 mtx_unlock(&p->p_ucred->cr_prison->pr_mtx); 153 } else { |
187 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, " -"); | 154 sbuf_printf(sb, " -"); |
188 } | 155 } |
189 DOCHECK(); 190 ps += snprintf(ps, psbuf + sizeof(psbuf) - ps, "\n"); 191 DOCHECK(); | 156 sbuf_printf(sb, "\n"); |
192 | 157 |
193 xlen = ps - psbuf; 194 xlen -= uio->uio_offset; 195 ps = psbuf + uio->uio_offset; 196 xlen = imin(xlen, uio->uio_resid); 197 if (xlen <= 0) 198 error = 0; 199 else 200 error = uiomove(ps, xlen, uio); 201 202 return (error); 203 204bailout: 205 return (ENOMEM); | 158 return (0); |
206} 207 208int | 159} 160 161int |
209procfs_docmdline(curp, p, pfs, uio) 210 struct proc *curp; 211 struct proc *p; 212 struct pfsnode *pfs; 213 struct uio *uio; | 162procfs_doproccmdline(PFS_FILL_ARGS) |
214{ | 163{ |
215 char *ps; 216 int xlen; 217 int error; 218 char *buf, *bp; 219 int buflen; | |
220 struct ps_strings pstr; | 164 struct ps_strings pstr; |
221 int i; 222 size_t bytes_left, done; | 165 int error, i; |
223 | 166 |
224 if (uio->uio_rw != UIO_READ) 225 return (EOPNOTSUPP); 226 | |
227 /* 228 * If we are using the ps/cmdline caching, use that. Otherwise 229 * revert back to the old way which only implements full cmdline 230 * for the currept process and just p->p_comm for all other 231 * processes. 232 * Note that if the argv is no longer available, we deliberately 233 * don't fall back on p->p_comm or return an error: the authentic 234 * Linux behaviour is to return zero-length in this case. 235 */ 236 | 167 /* 168 * If we are using the ps/cmdline caching, use that. Otherwise 169 * revert back to the old way which only implements full cmdline 170 * for the currept process and just p->p_comm for all other 171 * processes. 172 * Note that if the argv is no longer available, we deliberately 173 * don't fall back on p->p_comm or return an error: the authentic 174 * Linux behaviour is to return zero-length in this case. 175 */ 176 |
237 if (p->p_args && (ps_argsopen || !p_cansee(curp, p))) { 238 bp = p->p_args->ar_args; 239 buflen = p->p_args->ar_length; 240 buf = 0; 241 } else if (p != curp) { 242 bp = p->p_comm; 243 buflen = MAXCOMLEN; 244 buf = 0; | 177 if (p->p_args && (ps_argsopen || !p_cansee(td->td_proc, p))) { 178 sbuf_bcpy(sb, p->p_args->ar_args, p->p_args->ar_length); 179 } else if (p != td->td_proc) { 180 sbuf_printf(sb, "%.*s", MAXCOMLEN, p->p_comm); |
245 } else { | 181 } else { |
246 buflen = 256; 247 MALLOC(buf, char *, buflen + 1, M_TEMP, M_WAITOK); 248 bp = buf; 249 ps = buf; | |
250 error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr)); | 182 error = copyin((void*)PS_STRINGS, &pstr, sizeof(pstr)); |
251 if (error) { 252 FREE(buf, M_TEMP); | 183 if (error) |
253 return (error); | 184 return (error); |
185 for (i = 0; i < pstr.ps_nargvstr; i++) { 186 sbuf_copyin(sb, pstr.ps_argvstr[i], 0); 187 sbuf_printf(sb, "%c", '\0'); |
|
254 } | 188 } |
255 bytes_left = buflen; 256 for (i = 0; bytes_left && (i < pstr.ps_nargvstr); i++) { 257 error = copyinstr(pstr.ps_argvstr[i], ps, 258 bytes_left, &done); 259 /* If too long or malformed, just truncate */ 260 if (error) { 261 error = 0; 262 break; 263 } 264 ps += done; 265 bytes_left -= done; 266 } 267 buflen = ps - buf; | |
268 } 269 | 189 } 190 |
270 buflen -= uio->uio_offset; 271 ps = bp + uio->uio_offset; 272 xlen = min(buflen, uio->uio_resid); 273 if (xlen <= 0) 274 error = 0; 275 else 276 error = uiomove(ps, xlen, uio); 277 if (buf) 278 FREE(buf, M_TEMP); 279 return (error); | 191 return (0); |
280} | 192} |