* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* @(#)kern_sysctl.c 7.10 (Berkeley) %G%
#define snderr(e) { error = (e); goto release;}
extern int kinfo_doproc(), kinfo_rtable(), kinfo_vnode();
struct kinfo_lock kinfo_lock
;
getkerninfo(p
, uap
, retval
)
int bufsize
, /* max size of users buffer */
needed
, locked
, (*server
)(), error
= 0;
if (error
= copyin((caddr_t
)uap
->size
,
(caddr_t
)&bufsize
, sizeof (bufsize
)))
switch (ki_type(uap
->op
)) {
if (uap
->where
== NULL
|| uap
->size
== NULL
) {
error
= (*server
)(uap
->op
, NULL
, NULL
, uap
->arg
, &needed
);
while (kinfo_lock
.kl_lock
) {
sleep(&kinfo_lock
, PRIBIO
+1);
if (!useracc(uap
->where
, bufsize
, B_WRITE
))
* lock down target pages - NEED DEADLOCK AVOIDANCE
if (bufsize
> ((int)ptob(freemem
) - (20 * 1024))) /* XXX */
if (server
!= kinfo_vnode
) /* XXX */
vslock(uap
->where
, bufsize
);
error
= (*server
)(uap
->op
, uap
->where
, &bufsize
, uap
->arg
, &needed
);
if (server
!= kinfo_vnode
) /* XXX */
vsunlock(uap
->where
, locked
, B_WRITE
);
error
= copyout((caddr_t
)&bufsize
,
(caddr_t
)uap
->size
, sizeof (bufsize
));
* try over estimating by 5 procs
#define KINFO_PROCSLOP (5 * sizeof (struct kinfo_proc))
kinfo_doproc(op
, where
, acopysize
, arg
, aneeded
)
int *acopysize
, *aneeded
;
register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
for (; p
!= NULL
; p
= p
->p_nxt
) {
* TODO - make more efficient (see notes below).
/* could do this with just a lookup */
if (p
->p_pid
!= (pid_t
)arg
)
/* could do this by traversing pgrp */
if (p
->p_pgrp
->pg_id
!= (pid_t
)arg
)
if ((p
->p_flag
&SCTTY
) == 0 ||
p
->p_session
->s_ttyp
== NULL
||
p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)arg
)
if (p
->p_uid
!= (uid_t
)arg
)
if (p
->p_ruid
!= (uid_t
)arg
)
if (where
!= NULL
&& buflen
>= sizeof (struct kinfo_proc
)) {
register struct text
*txt
;
if (error
= copyout((caddr_t
)p
, &dp
->kp_proc
,
eproc
.e_sess
= p
->p_pgrp
->pg_session
;
eproc
.e_pgid
= p
->p_pgrp
->pg_id
;
eproc
.e_jobc
= p
->p_pgrp
->pg_jobc
;
(tp
= eproc
.e_sess
->s_ttyp
)) {
eproc
.e_tdev
= tp
->t_dev
;
eproc
.e_tpgid
= tp
->t_pgrp
?
eproc
.e_tsess
= tp
->t_session
;
eproc
.e_flag
= eproc
.e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
eproc
.e_flag
|= EPROC_SLEADER
;
strncpy(eproc
.e_wmesg
, p
->p_wmesg
, WMESGLEN
);
eproc
.e_xsize
= txt
->x_size
;
eproc
.e_xrssize
= txt
->x_rssize
;
eproc
.e_xccount
= txt
->x_ccount
;
eproc
.e_xswrss
= txt
->x_swrss
;
eproc
.e_xsize
= eproc
.e_xrssize
=
eproc
.e_xccount
= eproc
.e_xswrss
= 0;
if (error
= copyout((caddr_t
)&eproc
, &dp
->kp_eproc
,
buflen
-= sizeof (struct kinfo_proc
);
needed
+= sizeof (struct kinfo_proc
);
*acopysize
= (caddr_t
)dp
- where
;
needed
+= KINFO_PROCSLOP
;