* 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.2 (Berkeley) %G%
/* TODO - gather stats on average and max time spent */
} *uap
= (struct a
*)u
.u_ap
;
switch (ki_type(uap
->op
)) {
u
.u_error
= kinfo_proc(uap
->op
, (char *)uap
->where
,
(int *)uap
->size
, uap
->arg
, &wanted
);
* try over estimating by 5 procs
#define KINFO_PROCSLOP (5 * sizeof (struct kinfo_proc))
int kinfo_proc_userfailed
;
kinfo_proc(op
, where
, asize
, arg
, awanted
)
int bufsize
, /* max size of users buffer */
copysize
, /* size copied */
if (error
= kinfo_doprocs(op
, NULL
, NULL
, arg
, &needed
))
if (where
== NULL
|| asize
== NULL
) {
if (error
= copyin((caddr_t
)asize
, (caddr_t
)&bufsize
, sizeof (bufsize
)))
needed
+= KINFO_PROCSLOP
;
locked
= copysize
= MIN(needed
, bufsize
);
if (!useracc(where
, copysize
, B_WRITE
))
* lock down target pages - NEED DEADLOCK AVOIDANCE
if (copysize
> ((int)ptob(freemem
) - (20 * 1024))) /* XXX */
error
= kinfo_doprocs(op
, where
, ©size
, arg
, &needed
);
vsunlock(where
, locked
, B_WRITE
);
if (error
= copyout((caddr_t
)©size
, (caddr_t
)asize
,
kinfo_doprocs(op
, where
, acopysize
, arg
, aneeded
)
int *acopysize
, *aneeded
;
register caddr_t dp
= (caddr_t
)where
;
struct session
*ttysession
;
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
)) {
if (error
= copyout((caddr_t
)p
, dp
,
dp
+= sizeof (struct proc
);
extra
.session
= p
->p_pgrp
->pg_session
;
extra
.pgid
= p
->p_pgrp
->pg_id
;
extra
.jobc
= p
->p_pgrp
->pg_jobc
;
tp
= p
->p_pgrp
->pg_session
->s_ttyp
;
if ((p
->p_flag
&SCTTY
) && tp
!= NULL
) {
extra
.ttydev
= tp
->t_dev
;
extra
.ttypgid
= tp
->t_pgrp
?
extra
.ttysession
= tp
->t_session
;
if (error
= copyout((caddr_t
)&extra
, dp
,
buflen
-= sizeof (struct kinfo_proc
);
needed
+= sizeof (struct kinfo_proc
);