* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)kern_sysctl.c 7.20 (Berkeley) %G%
#define snderr(e) { error = (e); goto release;}
extern int kinfo_doproc(), kinfo_rtable(), kinfo_vnode(), kinfo_file();
extern int kinfo_meter();
struct kinfo_lock kinfo_lock
;
getkerninfo(p
, uap
, retval
)
int bufsize
; /* max size of users buffer */
int needed
, locked
, (*server
)(), error
= 0;
switch (ki_type(uap
->op
)) {
if (uap
->where
== NULL
|| uap
->size
== NULL
) {
error
= (*server
)(uap
->op
, NULL
, NULL
, uap
->arg
, &needed
);
if (error
= copyin((caddr_t
)uap
->size
, (caddr_t
)&bufsize
,
while (kinfo_lock
.kl_lock
) {
sleep((caddr_t
)&kinfo_lock
, PRIBIO
+1);
if (!useracc(uap
->where
, bufsize
, B_WRITE
))
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
));
if (kinfo_lock
.kl_want
) {
wakeup((caddr_t
)&kinfo_lock
);
* try over estimating by 5 procs
#define KINFO_PROCSLOP (5 * sizeof (struct kinfo_proc))
kinfo_doproc(op
, where
, acopysize
, arg
, aneeded
)
int *acopysize
, arg
, *aneeded
;
register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
int buflen
= where
!= NULL
? *acopysize
: 0;
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_ucred
->cr_uid
!= (uid_t
)arg
)
if (p
->p_cred
->p_ruid
!= (uid_t
)arg
)
if (buflen
>= sizeof (struct kinfo_proc
)) {
if (error
= copyout((caddr_t
)p
, &dp
->kp_proc
,
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
;
* Fill in an eproc structure for the specified process.
register struct eproc
*ep
;
ep
->e_sess
= p
->p_pgrp
->pg_session
;
ep
->e_pcred
= *p
->p_cred
;
ep
->e_ucred
= *p
->p_ucred
;
if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
/* ep->e_vm.vm_pmap = XXX; */
register struct vmspace
*vm
= p
->p_vmspace
;
ep
->e_vm
.vm_rssize
= vm
->vm_rssize
;
ep
->e_vm
.vm_tsize
= vm
->vm_tsize
;
ep
->e_vm
.vm_dsize
= vm
->vm_dsize
;
ep
->e_vm
.vm_ssize
= vm
->vm_ssize
;
ep
->e_vm
.vm_pmap
= vm
->vm_pmap
;
ep
->e_ppid
= p
->p_pptr
->p_pid
;
ep
->e_pgid
= p
->p_pgrp
->pg_id
;
ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
(tp
= ep
->e_sess
->s_ttyp
)) {
ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
ep
->e_tsess
= tp
->t_session
;
ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
ep
->e_flag
|= EPROC_SLEADER
;
strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
ep
->e_xsize
= ep
->e_xrssize
= 0;
ep
->e_xccount
= ep
->e_xswrss
= 0;
kinfo_file(op
, where
, acopysize
, arg
, aneeded
)
int *acopysize
, arg
, *aneeded
;
int buflen
, needed
, error
;
* overestimate by 10 files
*aneeded
= sizeof (filehead
) +
(nfiles
+ 10) * sizeof (struct file
);
if (buflen
> sizeof (filehead
)) {
if (error
= copyout((caddr_t
)&filehead
, where
,
buflen
-= sizeof (filehead
);
where
+= sizeof (filehead
);
needed
+= sizeof (filehead
);
* followed by an array of file structures
for (fp
= filehead
; fp
!= NULL
; fp
= fp
->f_filef
) {
if (buflen
> sizeof (struct file
)) {
if (error
= copyout((caddr_t
)fp
, where
,
buflen
-= sizeof (struct file
);
where
+= sizeof (struct file
);
needed
+= sizeof (struct file
);
*acopysize
= where
- start
;