* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)kern_sysctl.c 7.18 (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;
if (error
= copyin((caddr_t
)uap
->size
, (caddr_t
)&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
))
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_ucred
->cr_uid
!= (uid_t
)arg
)
if (p
->p_cred
->p_ruid
!= (uid_t
)arg
)
if (where
!= NULL
&& 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
;
ep
->e_vm
= *p
->p_vmspace
;
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
, *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
;