Deleted Added
full compact
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}