2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
24 * Copyright (c) 1982, 1986, 1989, 1993
25 * The Regents of the University of California. All rights reserved.
27 * This code is derived from software contributed to Berkeley by
28 * Mike Karels at Berkeley Software Design, Inc.
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * @(#)kern_sysctl.c 8.4 (Berkeley) 4/14/94
65 #include <sys/param.h>
66 #include <sys/systm.h>
67 #include <sys/kernel.h>
68 #include <sys/malloc.h>
71 #include <sys/vnode.h>
72 #include <sys/unistd.h>
74 #include <sys/ioctl.h>
76 #include <sys/disklabel.h>
78 #include <sys/sysctl.h>
79 #include <mach/machine.h>
80 #include <mach/mach_types.h>
81 #include <mach/vm_param.h>
82 #include <kern/task.h>
83 #include <vm/vm_kern.h>
84 #include <mach/host_info.h>
86 extern vm_map_t bsd_pageable_map
;
88 #include <sys/mount.h>
89 #include <sys/kdebug.h>
91 #include <IOKit/IOPlatformExpert.h>
92 #include <pexpert/pexpert.h>
95 #include <osfmk/ppc/machine_routines.h>
101 sysctlfn debug_sysctl
;
103 extern sysctlfn vm_sysctl
;
104 extern sysctlfn vfs_sysctl
;
105 extern sysctlfn net_sysctl
;
106 extern sysctlfn cpu_sysctl
;
110 userland_sysctl(struct proc
*p
, int *name
, u_int namelen
, void *old
, size_t
111 *oldlenp
, int inkernel
, void *new, size_t newlen
, size_t *retval
);
114 fill_proc(struct proc
*p
,struct kinfo_proc
*kp
, int doingzomb
);
117 fill_externproc(struct proc
*p
, struct extern_proc
*exp
);
122 * temporary location for vm_sysctl. This should be machine independant
124 vm_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
133 int error
, level
, inthostid
;
134 extern long avenrun
[3], mach_factor
[3];
135 struct loadavg loadinfo
;
137 //if (namelen != 1 && !(name[0] == VM_LOADAVG))
138 //return (ENOTDIR); /* overloaded */
142 loadinfo
.ldavg
[0] = avenrun
[0];
143 loadinfo
.ldavg
[1] = avenrun
[1];
144 loadinfo
.ldavg
[2] = avenrun
[2];
145 loadinfo
.fscale
= LSCALE
;
146 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
, &loadinfo
, sizeof(struct loadavg
)));
148 loadinfo
.ldavg
[0] = mach_factor
[0];
149 loadinfo
.ldavg
[1] = mach_factor
[1];
150 loadinfo
.ldavg
[2] = mach_factor
[2];
151 loadinfo
.fscale
= LSCALE
;
152 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
, &loadinfo
, sizeof(struct loadavg
)));
167 static struct sysctl_lock
{
173 struct __sysctl_args
{
182 __sysctl(p
, uap
, retval
)
184 register struct __sysctl_args
*uap
;
187 int error
, dolock
= 1;
188 size_t savelen
, oldlen
= 0;
190 int name
[CTL_MAXNAME
];
195 * all top-level sysctl names are non-terminal
197 if (uap
->namelen
> CTL_MAXNAME
|| uap
->namelen
< 2)
200 copyin(uap
->name
, &name
, uap
->namelen
* sizeof(int)))
203 /* CTL_UNSPEC is used to get oid to AUTO_OID */
204 if (uap
->new != NULL
&&
205 (((name
[0] == CTL_KERN
) && (name
[1] != KERN_IPC
)) ||
206 (name
[0] == CTL_HW
) || (name
[0] == CTL_VM
) ||
207 (name
[0] == CTL_VFS
)) &&
208 (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
214 if ((name
[1] != KERN_VNODE
) && (name
[1] != KERN_FILE
)
215 && (name
[1] != KERN_PROC
))
243 (error
= copyin(uap
->oldlenp
, &oldlen
, sizeof(oldlen
))))
246 if (uap
->old
!= NULL
) {
247 if (!useracc(uap
->old
, oldlen
, B_WRITE
))
250 /* The pc sampling mechanism does not need to take this lock */
251 if (name
[1] != KERN_PCSAMPLES
) {
252 while (memlock
.sl_lock
) {
254 sleep((caddr_t
)&memlock
, PRIBIO
+1);
260 if (dolock
&& oldlen
&& (error
= vslock(uap
->old
, oldlen
))) {
261 if (name
[1] != KERN_PCSAMPLES
) {
263 if (memlock
.sl_want
) {
265 wakeup((caddr_t
)&memlock
);
274 error
= (*fn
)(name
+ 1, uap
->namelen
- 1, uap
->old
,
275 &oldlen
, uap
->new, uap
->newlen
, p
);
279 if ( (name
[0] != CTL_VFS
) && (error
== EOPNOTSUPP
))
280 error
= userland_sysctl(p
, name
, uap
->namelen
,
281 uap
->old
, uap
->oldlenp
, 0,
282 uap
->new, uap
->newlen
, &oldlen
);
284 if (uap
->old
!= NULL
) {
285 if (dolock
&& savelen
) {
286 error1
= vsunlock(uap
->old
, savelen
, B_WRITE
);
287 if (!error
&& error1
)
290 if (name
[1] != KERN_PCSAMPLES
) {
292 if (memlock
.sl_want
) {
294 wakeup((caddr_t
)&memlock
);
298 if ((error
) && (error
!= ENOMEM
))
302 i
= copyout(&oldlen
, uap
->oldlenp
, sizeof(oldlen
));
311 * Attributes stored in the kernel.
313 extern char hostname
[MAXHOSTNAMELEN
]; /* defined in bsd/kern/init_main.c */
314 extern int hostnamelen
;
315 extern char domainname
[MAXHOSTNAMELEN
];
316 extern int domainnamelen
;
319 int securelevel
= -1;
324 int get_kernel_symfile( struct proc
*p
, char **symfile
);
327 * kernel related system variables.
329 kern_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
338 int error
, level
, inthostid
;
339 unsigned int oldval
=0;
340 extern char ostype
[], osrelease
[], version
[];
342 /* all sysctl names at this level are terminal */
343 if (namelen
!= 1 && !(name
[0] == KERN_PROC
|| name
[0] == KERN_PROF
344 || name
[0] == KERN_KDEBUG
345 || name
[0] == KERN_PROCARGS
346 || name
[0] == KERN_PCSAMPLES
347 || name
[0] == KERN_IPC
349 return (ENOTDIR
); /* overloaded */
353 return (sysctl_rdstring(oldp
, oldlenp
, newp
, ostype
));
355 return (sysctl_rdstring(oldp
, oldlenp
, newp
, osrelease
));
357 return (sysctl_rdint(oldp
, oldlenp
, newp
, BSD
));
359 return (sysctl_rdstring(oldp
, oldlenp
, newp
, version
));
361 oldval
= desiredvnodes
;
362 error
= sysctl_int(oldp
, oldlenp
, newp
,
363 newlen
, &desiredvnodes
);
364 reset_vmobjectcache(oldval
, desiredvnodes
);
367 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxproc
));
369 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxfiles
));
371 return (sysctl_rdint(oldp
, oldlenp
, newp
, ARG_MAX
));
374 if ((error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &level
)) ||
377 if (level
< securelevel
&& p
->p_pid
!= 1)
382 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
383 hostname
, sizeof(hostname
));
385 hostnamelen
= newlen
;
387 case KERN_DOMAINNAME
:
388 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
389 domainname
, sizeof(domainname
));
391 domainnamelen
= newlen
;
394 inthostid
= hostid
; /* XXX assumes sizeof long <= sizeof int */
395 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &inthostid
);
399 return (sysctl_clockrate(oldp
, oldlenp
));
401 return (sysctl_rdstruct(oldp
, oldlenp
, newp
, &boottime
,
402 sizeof(struct timeval
)));
404 return (sysctl_vnode(oldp
, oldlenp
));
406 return (sysctl_doproc(name
+ 1, namelen
- 1, oldp
, oldlenp
));
408 return (sysctl_file(oldp
, oldlenp
));
411 return (sysctl_doprof(name
+ 1, namelen
- 1, oldp
, oldlenp
,
415 return (sysctl_rdint(oldp
, oldlenp
, newp
, _POSIX_VERSION
));
417 return (sysctl_rdint(oldp
, oldlenp
, newp
, NGROUPS_MAX
));
418 case KERN_JOB_CONTROL
:
419 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
421 #ifdef _POSIX_SAVED_IDS
422 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
424 return (sysctl_rdint(oldp
, oldlenp
, newp
, 0));
427 case KERN_MAXPARTITIONS
:
428 return (sysctl_rdint(oldp
, oldlenp
, newp
, MAXPARTITIONS
));
431 return (kdebug_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
433 return (pcsamples_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
435 /* new one as it does not use kinfo_proc */
436 return (sysctl_procargs(name
+ 1, namelen
- 1, oldp
, oldlenp
));
440 error
= get_kernel_symfile( p
, &str
);
441 if ( error
) return error
;
442 return (sysctl_rdstring(oldp
, oldlenp
, newp
, str
));
451 * hardware related system variables.
453 hw_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
464 extern int vm_page_wire_count
;
466 ml_ppc_cpu_info_t cpu_info
;
468 ml_ppc_get_info(&cpu_info
);
471 /* all sysctl names at this level are terminal */
473 return (ENOTDIR
); /* overloaded */
477 if(!PEGetMachineName(dummy
,64))
479 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
481 if(!PEGetModelName(dummy
,64))
483 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
486 host_basic_info_data_t hinfo
;
488 int count
= HOST_BASIC_INFO_COUNT
;
491 kret
= host_info(BSD_HOST
, HOST_BASIC_INFO
, &hinfo
, &count
);
492 if (kret
== KERN_SUCCESS
) {
493 numcpus
= hinfo
.avail_cpus
;
494 return (sysctl_rdint(oldp
, oldlenp
, newp
, numcpus
));
500 return (sysctl_rdint(oldp
, oldlenp
, newp
, BYTE_ORDER
));
502 return (sysctl_rdint(oldp
, oldlenp
, newp
, mem_size
));
504 return (sysctl_rdint(oldp
, oldlenp
, newp
,
505 (mem_size
- vm_page_wire_count
* page_size
)));
507 return (sysctl_rdint(oldp
, oldlenp
, newp
, page_size
));
509 epochTemp
= PEGetPlatformEpoch();
510 if (epochTemp
== -1) return(EINVAL
);
511 return (sysctl_rdint(oldp
, oldlenp
, newp
, epochTemp
));
513 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.bus_clock_rate_hz
));
515 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.cpu_clock_rate_hz
));
518 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.vector_unit
));
520 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.cache_line_size
));
521 case HW_L1ICACHESIZE
:
522 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_icache_size
));
523 case HW_L1DCACHESIZE
:
524 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_dcache_size
));
526 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
527 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_settings
));
529 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
530 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_cache_size
));
532 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
533 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_settings
));
535 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
536 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_cache_size
));
545 * Debugging related system variables.
549 #endif /* DIAGNOSTIC */
550 struct ctldebug debug0
, debug1
;
551 struct ctldebug debug2
, debug3
, debug4
;
552 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
553 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
554 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
555 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
556 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
557 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
558 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
559 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
562 debug_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
571 struct ctldebug
*cdp
;
573 /* all sysctl names at this level are name and field */
575 return (ENOTDIR
); /* overloaded */
576 cdp
= debugvars
[name
[0]];
577 if (cdp
->debugname
== 0)
581 return (sysctl_rdstring(oldp
, oldlenp
, newp
, cdp
->debugname
));
582 case CTL_DEBUG_VALUE
:
583 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, cdp
->debugvar
));
592 * Validate parameters and get old / set new parameters
593 * for an integer-valued sysctl function.
595 sysctl_int(oldp
, oldlenp
, newp
, newlen
, valp
)
604 if (oldp
&& *oldlenp
< sizeof(int))
606 if (newp
&& newlen
!= sizeof(int))
608 *oldlenp
= sizeof(int);
610 error
= copyout(valp
, oldp
, sizeof(int));
611 if (error
== 0 && newp
)
612 error
= copyin(newp
, valp
, sizeof(int));
617 * As above, but read-only.
619 sysctl_rdint(oldp
, oldlenp
, newp
, val
)
627 if (oldp
&& *oldlenp
< sizeof(int))
631 *oldlenp
= sizeof(int);
633 error
= copyout((caddr_t
)&val
, oldp
, sizeof(int));
638 * Validate parameters and get old / set new parameters
639 * for a string-valued sysctl function.
641 sysctl_string(oldp
, oldlenp
, newp
, newlen
, str
, maxlen
)
651 len
= strlen(str
) + 1;
652 if (oldp
&& *oldlenp
< len
)
654 if (newp
&& newlen
>= maxlen
)
658 error
= copyout(str
, oldp
, len
);
660 if (error
== 0 && newp
) {
661 error
= copyin(newp
, str
, newlen
);
668 * As above, but read-only.
670 sysctl_rdstring(oldp
, oldlenp
, newp
, str
)
678 len
= strlen(str
) + 1;
679 if (oldp
&& *oldlenp
< len
)
685 error
= copyout(str
, oldp
, len
);
690 * Validate parameters and get old / set new parameters
691 * for a structure oriented sysctl function.
693 sysctl_struct(oldp
, oldlenp
, newp
, newlen
, sp
, len
)
703 if (oldp
&& *oldlenp
< len
)
705 if (newp
&& newlen
> len
)
709 error
= copyout(sp
, oldp
, len
);
711 if (error
== 0 && newp
)
712 error
= copyin(newp
, sp
, len
);
717 * Validate parameters and get old parameters
718 * for a structure oriented sysctl function.
720 sysctl_rdstruct(oldp
, oldlenp
, newp
, sp
, len
)
728 if (oldp
&& *oldlenp
< len
)
734 error
= copyout(sp
, oldp
, len
);
739 * Get file structures.
741 sysctl_file(where
, sizep
)
752 * overestimate by 10 files
754 *sizep
= sizeof(filehead
) + (nfiles
+ 10) * sizeof(struct file
);
759 * first copyout filehead
761 if (buflen
< sizeof(filehead
)) {
765 if (error
= copyout((caddr_t
)&filehead
, where
, sizeof(filehead
)))
767 buflen
-= sizeof(filehead
);
768 where
+= sizeof(filehead
);
771 * followed by an array of file structures
773 for (fp
= filehead
.lh_first
; fp
!= 0; fp
= fp
->f_list
.le_next
) {
774 if (buflen
< sizeof(struct file
)) {
775 *sizep
= where
- start
;
778 if (error
= copyout((caddr_t
)fp
, where
, sizeof (struct file
)))
780 buflen
-= sizeof(struct file
);
781 where
+= sizeof(struct file
);
783 *sizep
= where
- start
;
788 * try over estimating by 5 procs
790 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
792 sysctl_doproc(name
, namelen
, where
, sizep
)
798 register struct proc
*p
;
799 register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
800 register int needed
= 0;
801 int buflen
= where
!= NULL
? *sizep
: 0;
803 struct kinfo_proc kproc
;
806 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
808 p
= allproc
.lh_first
;
811 for (; p
!= 0; p
= p
->p_list
.le_next
) {
813 * Skip embryonic processes.
815 if (p
->p_stat
== SIDL
)
818 * TODO - make more efficient (see notes below).
824 /* could do this with just a lookup */
825 if (p
->p_pid
!= (pid_t
)name
[1])
830 /* could do this by traversing pgrp */
831 if (p
->p_pgrp
->pg_id
!= (pid_t
)name
[1])
836 if ( doingzomb
|| (p
->p_flag
& P_CONTROLT
) == 0 ||
837 p
->p_session
->s_ttyp
== NULL
||
838 p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)name
[1])
843 if (doingzomb
|| (p
->p_ucred
->cr_uid
!= (uid_t
)name
[1]))
848 if ( doingzomb
|| (p
->p_cred
->p_ruid
!= (uid_t
)name
[1]))
852 if (buflen
>= sizeof(struct kinfo_proc
)) {
853 bzero(&kproc
, sizeof(struct kinfo_proc
));
854 fill_proc(p
, &kproc
, doingzomb
);
855 if (error
= copyout((caddr_t
)&kproc
, &dp
->kp_proc
,
856 sizeof(struct kinfo_proc
)))
859 buflen
-= sizeof(struct kinfo_proc
);
861 needed
+= sizeof(struct kinfo_proc
);
863 if (doingzomb
== 0) {
864 p
= zombproc
.lh_first
;
869 *sizep
= (caddr_t
)dp
- where
;
873 needed
+= KERN_PROCSLOP
;
880 fill_proc(p
,kp
, doingzomb
)
881 register struct proc
*p
;
882 register struct kinfo_proc
*kp
;
885 fill_externproc(p
, &kp
->kp_proc
);
887 fill_eproc(p
, &kp
->kp_eproc
);
890 * Fill in an eproc structure for the specified process.
894 register struct proc
*p
;
895 register struct eproc
*ep
;
897 register struct tty
*tp
;
900 * Skip zombie processes.
902 if (p
->p_stat
== SZOMB
)
906 ep
->e_sess
= p
->p_pgrp
->pg_session
;
907 ep
->e_pcred
= *p
->p_cred
;
908 ep
->e_ucred
= *p
->p_ucred
;
909 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
910 ep
->e_vm
.vm_rssize
= 0;
911 ep
->e_vm
.vm_tsize
= 0;
912 ep
->e_vm
.vm_dsize
= 0;
913 ep
->e_vm
.vm_ssize
= 0;
914 /* ep->e_vm.vm_pmap = XXX; */
917 register vm_map_t vm
= ((task_t
)p
->task
)->map
;
919 ep
->e_vm
.vm_rssize
= pmap_resident_count(vm
->pmap
); /*XXX*/
920 // ep->e_vm.vm_tsize = vm->vm_tsize;
921 // ep->e_vm.vm_dsize = vm->vm_dsize;
922 // ep->e_vm.vm_ssize = vm->vm_ssize;
924 ep
->e_vm
.vm_rssize
= 0; /*XXX*/
928 ep
->e_ppid
= p
->p_pptr
->p_pid
;
931 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
932 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
933 if ((p
->p_flag
& P_CONTROLT
) &&
934 (tp
= ep
->e_sess
->s_ttyp
)) {
935 ep
->e_tdev
= tp
->t_dev
;
936 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
937 ep
->e_tsess
= tp
->t_session
;
940 ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
942 ep
->e_flag
|= EPROC_SLEADER
;
944 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
945 ep
->e_xsize
= ep
->e_xrssize
= 0;
946 ep
->e_xccount
= ep
->e_xswrss
= 0;
949 * Fill in an eproc structure for the specified process.
952 fill_externproc(p
, exp
)
953 register struct proc
*p
;
954 register struct extern_proc
*exp
;
956 exp
->p_forw
= exp
->p_back
= NULL
;
957 exp
->p_vmspace
= NULL
;
958 exp
->p_sigacts
= p
->p_sigacts
;
959 exp
->p_flag
= p
->p_flag
;
960 exp
->p_stat
= p
->p_stat
;
961 exp
->p_pid
= p
->p_pid
;
962 exp
->p_oppid
= p
->p_oppid
;
963 exp
->p_dupfd
= p
->p_dupfd
;
965 exp
->user_stack
= p
->user_stack
;
966 exp
->exit_thread
= p
->exit_thread
;
967 exp
->p_debugger
= p
->p_debugger
;
968 exp
->sigwait
= p
->sigwait
;
970 exp
->p_estcpu
= p
->p_estcpu
;
971 exp
->p_cpticks
= p
->p_cpticks
;
972 exp
->p_pctcpu
= p
->p_pctcpu
;
973 exp
->p_wchan
= p
->p_wchan
;
974 exp
->p_wmesg
= p
->p_wmesg
;
975 exp
->p_swtime
= p
->p_swtime
;
976 exp
->p_slptime
= p
->p_slptime
;
977 bcopy(&p
->p_realtimer
, &exp
->p_realtimer
,sizeof(struct itimerval
));
978 bcopy(&p
->p_rtime
, &exp
->p_rtime
,sizeof(struct timeval
));
979 exp
->p_uticks
= p
->p_uticks
;
980 exp
->p_sticks
= p
->p_sticks
;
981 exp
->p_iticks
= p
->p_iticks
;
982 exp
->p_traceflag
= p
->p_traceflag
;
983 exp
->p_tracep
= p
->p_tracep
;
984 exp
->p_siglist
= p
->p_siglist
;
985 exp
->p_textvp
= p
->p_textvp
;
987 exp
->p_sigmask
= p
->p_sigmask
;
988 exp
->p_sigignore
= p
->p_sigignore
;
989 exp
->p_sigcatch
= p
->p_sigcatch
;
990 exp
->p_priority
= p
->p_priority
;
991 exp
->p_usrpri
= p
->p_usrpri
;
992 exp
->p_nice
= p
->p_nice
;
993 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
994 exp
->p_comm
[MAXCOMLEN
] = '\0';
995 exp
->p_pgrp
= p
->p_pgrp
;
997 exp
->p_xstat
= p
->p_xstat
;
998 exp
->p_acflag
= p
->p_acflag
;
999 exp
->p_ru
= p
->p_ru
;
1002 kdebug_ops(name
, namelen
, where
, sizep
, p
)
1011 extern int kdbg_control(int *name
, u_int namelen
, char * where
,size_t * sizep
);
1013 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1029 case KERN_KDSETRTCDEC
:
1031 ret
= kdbg_control(name
, namelen
, where
, sizep
);
1040 pcsamples_ops(name
, namelen
, where
, sizep
, p
)
1048 extern int pcsamples_control(int *name
, u_int namelen
, char * where
,size_t * sizep
);
1050 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1054 case KERN_PCDISABLE
:
1058 case KERN_PCREADBUF
:
1062 ret
= pcsamples_control(name
, namelen
, where
, sizep
);
1072 * Returns the top N bytes of the user stack, with
1073 * everything below the first argument character
1074 * zeroed for security reasons.
1075 * Odd data structure is for compatibility.
1077 sysctl_procargs(name
, namelen
, where
, sizep
)
1083 register struct proc
*p
;
1084 register int needed
= 0;
1085 int buflen
= where
!= NULL
? *sizep
: 0;
1087 struct vm_map
*proc_map
;
1090 vm_offset_t arg_addr
;
1094 vm_offset_t copy_start
, copy_end
;
1095 vm_offset_t dealloc_start
; /* area to remove from kernel map */
1096 vm_offset_t dealloc_end
;
1102 if ((buflen
<= 0) || (buflen
> (PAGE_SIZE
<< 1))) {
1108 * Lookup process by pid
1119 * Copy the top N bytes of the stack.
1120 * On all machines we have so far, the stack grows
1123 * If the user expects no more than N bytes of
1124 * argument list, use that as a guess for the
1131 arg_addr
= (vm_offset_t
)(p
->user_stack
- arg_size
);
1135 * Before we can block (any VM code), make another
1136 * reference to the map to keep it alive. We do
1137 * that by getting a reference on the task itself.
1144 * A regular task_reference call can block, causing the funnel
1145 * to be dropped and allowing the proc/task to get freed.
1146 * Instead, we issue a non-blocking attempt at the task reference,
1147 * and look up the proc/task all over again if that fails.
1149 if (!task_reference_try(task
)) {
1154 ret
= kmem_alloc(kernel_map
, ©_start
, round_page(arg_size
));
1155 if (ret
!= KERN_SUCCESS
) {
1156 task_deallocate(task
);
1160 proc_map
= get_task_map(task
);
1161 copy_end
= round_page(copy_start
+ arg_size
);
1163 if( vm_map_copyin(proc_map
, trunc_page(arg_addr
), round_page(arg_size
),
1164 FALSE
, &tmp
) != KERN_SUCCESS
) {
1165 task_deallocate(task
);
1166 kmem_free(kernel_map
, copy_start
,
1167 round_page(arg_size
));
1172 * Now that we've done the copyin from the process'
1173 * map, we can release the reference to it.
1175 task_deallocate(task
);
1177 if( vm_map_copy_overwrite(kernel_map
, copy_start
,
1178 tmp
, FALSE
) != KERN_SUCCESS
) {
1179 kmem_free(kernel_map
, copy_start
,
1180 round_page(arg_size
));
1184 data
= (caddr_t
) (copy_end
- arg_size
);
1185 ip
= (int *) copy_end
;
1189 * Now look down the stack for the bottom of the
1190 * argument list. Since this call is otherwise
1191 * unprotected, we can't let the nosy user see
1192 * anything else on the stack.
1194 * The arguments are pushed on the stack by
1198 * arg 0 (null-terminated)
1206 ip
-= 2; /*skip trailing 0 word and assume at least one
1207 argument. The last word of argN may be just
1208 the trailing 0, in which case we'd stop
1211 if (ip
== (int *)data
)
1214 * To account for saved path name and not having a null after that
1215 * Run the sweep again. If we have already sweeped entire range skip this
1217 if (ip
!= (int *)data
) {
1219 if (ip
== (int *)data
)
1223 bzero(data
, (unsigned) ((int)ip
- (int)data
));
1225 dealloc_start
= copy_start
;
1226 dealloc_end
= copy_end
;
1229 size
= MIN(size
, buflen
);
1230 error
= copyout(data
, where
, size
);
1232 if (dealloc_start
!= (vm_offset_t
) 0) {
1233 kmem_free(kernel_map
, dealloc_start
,
1234 dealloc_end
- dealloc_start
);