2 * Copyright (c) 1993 Jan-Simon Pendry
4 * The Regents of the University of California. All rights reserved.
6 * This code is derived from software contributed to Berkeley by
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
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
37 * @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
40 * $FreeBSD: src/sys/miscfs/procfs/procfs_status.c,v 1.20.2.4 2002/01/22 17:22:59 nectar Exp $
41 * $DragonFly: src/sys/vfs/procfs/procfs_status.c,v 1.15 2007/02/19 01:14:24 corecode Exp $
44 #include <sys/param.h>
45 #include <sys/systm.h>
46 #include <sys/malloc.h>
49 #include <sys/vnode.h>
51 #include <sys/resourcevar.h>
52 #include <vfs/procfs/procfs.h>
56 #include <vm/vm_param.h>
59 #define DOCHECK() do { if (ps >= psbuf+sizeof(psbuf)) goto bailout; } while (0)
61 procfs_dostatus(struct proc
*curp
, struct lwp
*lp
, struct pfsnode
*pfs
,
64 struct proc
*p
= lp
->lwp_proc
;
70 int pid
, ppid
, pgid
, sid
;
74 char psbuf
[256]; /* XXX - conservative */
76 if (uio
->uio_rw
!= UIO_READ
)
80 ppid
= p
->p_pptr
? p
->p_pptr
->p_pid
: 0;
81 pgid
= p
->p_pgrp
->pg_id
;
82 sess
= p
->p_pgrp
->pg_session
;
83 sid
= sess
->s_leader
? sess
->s_leader
->p_pid
: 0;
85 /* comm pid ppid pgid sid maj,min ctty,sldr start ut st wmsg
86 euid ruid rgid,egid,groups[1 .. NGROUPS]
88 KASSERT(sizeof(psbuf
) > MAXCOMLEN
,
89 ("Too short buffer for new MAXCOMLEN"));
92 bcopy(p
->p_comm
, ps
, MAXCOMLEN
);
96 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
97 " %d %d %d %d ", pid
, ppid
, pgid
, sid
);
99 if ((p
->p_flag
&P_CONTROLT
) && (tp
= sess
->s_ttyp
))
100 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
101 "%d,%d ", major(tp
->t_dev
), minor(tp
->t_dev
));
103 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
109 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, "%sctty", sep
);
113 if (SESS_LEADER(p
)) {
114 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, "%ssldr", sep
);
119 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, "noflags");
123 if (p
->p_flag
& P_SWAPPEDOUT
) {
124 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
125 " -1,-1 -1,-1 -1,-1");
130 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
131 " %ld,%ld %ld,%ld %ld,%ld",
134 ru
.ru_utime
.tv_sec
, ru
.ru_utime
.tv_usec
,
135 ru
.ru_stime
.tv_sec
, ru
.ru_stime
.tv_usec
);
139 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, " %s",
140 (lp
->lwp_wchan
&& lp
->lwp_wmesg
) ? lp
->lwp_wmesg
: "nochan");
145 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, " %lu %lu %lu",
147 (u_long
)p
->p_ucred
->cr_ruid
,
148 (u_long
)p
->p_ucred
->cr_rgid
);
151 /* egid (p->p_ucred->cr_svgid) is equal to cr_ngroups[0]
152 see also getegid(2) in /sys/kern/kern_prot.c */
154 for (i
= 0; i
< cr
->cr_ngroups
; i
++) {
155 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
156 ",%lu", (u_long
)cr
->cr_groups
[i
]);
160 if (p
->p_ucred
->cr_prison
)
161 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
,
162 " %s", p
->p_ucred
->cr_prison
->pr_host
);
164 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, " -");
166 ps
+= ksnprintf(ps
, psbuf
+ sizeof(psbuf
) - ps
, "\n");
170 xlen
-= uio
->uio_offset
;
171 ps
= psbuf
+ uio
->uio_offset
;
172 xlen
= imin(xlen
, uio
->uio_resid
);
176 error
= uiomove_frombuf(ps
, xlen
, uio
);
185 procfs_docmdline(struct proc
*curp
, struct lwp
*lp
, struct pfsnode
*pfs
,
188 struct proc
*p
= lp
->lwp_proc
;
194 struct ps_strings pstr
;
197 size_t bytes_left
, done
;
199 if (uio
->uio_rw
!= UIO_READ
)
203 * If we are using the ps/cmdline caching, use that. Otherwise
204 * revert back to the old way which only implements full cmdline
205 * for the currept process and just p->p_comm for all other
207 * Note that if the argv is no longer available, we deliberately
208 * don't fall back on p->p_comm or return an error: the authentic
209 * Linux behaviour is to return zero-length in this case.
213 (ps_argsopen
|| (CHECKIO(curp
, p
) &&
214 (p
->p_flag
& P_INEXEC
) == 0 && !p_trespass(curp
->p_ucred
, p
->p_ucred
)))
216 bp
= p
->p_args
->ar_args
;
217 buflen
= p
->p_args
->ar_length
;
219 } else if (p
!= curp
) {
225 MALLOC(buf
, char *, buflen
+ 1, M_TEMP
, M_WAITOK
);
228 error
= copyin((void*)PS_STRINGS
, &pstr
, sizeof(pstr
));
233 if (pstr
.ps_nargvstr
> ARG_MAX
) {
237 MALLOC(ps_argvstr
, char **, pstr
.ps_nargvstr
* sizeof(char *),
239 error
= copyin((void *)pstr
.ps_argvstr
, ps_argvstr
,
240 pstr
.ps_nargvstr
* sizeof(char *));
242 FREE(ps_argvstr
, M_TEMP
);
247 for (i
= 0; bytes_left
&& (i
< pstr
.ps_nargvstr
); i
++) {
248 error
= copyinstr(ps_argvstr
[i
], ps
,
250 /* If too long or malformed, just truncate */
259 FREE(ps_argvstr
, M_TEMP
);
262 buflen
-= uio
->uio_offset
;
263 ps
= bp
+ uio
->uio_offset
;
264 xlen
= min(buflen
, uio
->uio_resid
);
268 error
= uiomove_frombuf(bp
, buflen
, uio
);