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
];
194 * all top-level sysctl names are non-terminal
196 if (uap
->namelen
> CTL_MAXNAME
|| uap
->namelen
< 2)
199 copyin(uap
->name
, &name
, uap
->namelen
* sizeof(int)))
202 /* CTL_UNSPEC is used to get oid to AUTO_OID */
203 if (uap
->new != NULL
&&
204 (((name
[0] == CTL_KERN
) && (name
[1] != KERN_IPC
)) ||
205 (name
[0] == CTL_HW
) || (name
[0] == CTL_VM
) ||
206 (name
[0] == CTL_VFS
)) &&
207 (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
213 if (name
[1] != KERN_VNODE
) /* XXX */
241 (error
= copyin(uap
->oldlenp
, &oldlen
, sizeof(oldlen
))))
244 if (uap
->old
!= NULL
) {
245 if (!useracc(uap
->old
, oldlen
, B_WRITE
))
248 /* The pc sampling mechanism does not need to take this lock */
249 if (name
[1] != KERN_PCSAMPLES
) {
250 while (memlock
.sl_lock
) {
252 sleep((caddr_t
)&memlock
, PRIBIO
+1);
259 vslock(uap
->old
, oldlen
);
264 error
= (*fn
)(name
+ 1, uap
->namelen
- 1, uap
->old
,
265 &oldlen
, uap
->new, uap
->newlen
, p
);
269 if ( (name
[0] != CTL_VFS
) && (error
== EOPNOTSUPP
))
270 error
= userland_sysctl(p
, name
, uap
->namelen
,
271 uap
->old
, uap
->oldlenp
, 0,
272 uap
->new, uap
->newlen
, &oldlen
);
274 if (uap
->old
!= NULL
) {
276 vsunlock(uap
->old
, savelen
, B_WRITE
);
277 if (name
[1] != KERN_PCSAMPLES
) {
279 if (memlock
.sl_want
) {
281 wakeup((caddr_t
)&memlock
);
285 if ((error
) && (error
!= ENOMEM
))
289 i
= copyout(&oldlen
, uap
->oldlenp
, sizeof(oldlen
));
298 * Attributes stored in the kernel.
300 extern char hostname
[MAXHOSTNAMELEN
]; /* defined in bsd/kern/init_main.c */
301 extern int hostnamelen
;
302 extern char domainname
[MAXHOSTNAMELEN
];
303 extern int domainnamelen
;
306 int securelevel
= -1;
311 int get_kernel_symfile( struct proc
*p
, char **symfile
);
314 * kernel related system variables.
316 kern_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
325 int error
, level
, inthostid
;
326 unsigned int oldval
=0;
327 extern char ostype
[], osrelease
[], version
[];
329 /* all sysctl names at this level are terminal */
330 if (namelen
!= 1 && !(name
[0] == KERN_PROC
|| name
[0] == KERN_PROF
331 || name
[0] == KERN_KDEBUG
332 || name
[0] == KERN_PROCARGS
333 || name
[0] == KERN_PCSAMPLES
334 || name
[0] == KERN_IPC
336 return (ENOTDIR
); /* overloaded */
340 return (sysctl_rdstring(oldp
, oldlenp
, newp
, ostype
));
342 return (sysctl_rdstring(oldp
, oldlenp
, newp
, osrelease
));
344 return (sysctl_rdint(oldp
, oldlenp
, newp
, BSD
));
346 return (sysctl_rdstring(oldp
, oldlenp
, newp
, version
));
348 oldval
= desiredvnodes
;
349 error
= sysctl_int(oldp
, oldlenp
, newp
,
350 newlen
, &desiredvnodes
);
351 reset_vmobjectcache(oldval
, desiredvnodes
);
354 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxproc
));
356 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxfiles
));
358 return (sysctl_rdint(oldp
, oldlenp
, newp
, ARG_MAX
));
361 if ((error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &level
)) ||
364 if (level
< securelevel
&& p
->p_pid
!= 1)
369 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
370 hostname
, sizeof(hostname
));
372 hostnamelen
= newlen
;
374 case KERN_DOMAINNAME
:
375 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
376 domainname
, sizeof(domainname
));
378 domainnamelen
= newlen
;
381 inthostid
= hostid
; /* XXX assumes sizeof long <= sizeof int */
382 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &inthostid
);
386 return (sysctl_clockrate(oldp
, oldlenp
));
388 return (sysctl_rdstruct(oldp
, oldlenp
, newp
, &boottime
,
389 sizeof(struct timeval
)));
391 return (sysctl_vnode(oldp
, oldlenp
));
393 return (sysctl_doproc(name
+ 1, namelen
- 1, oldp
, oldlenp
));
395 return (sysctl_file(oldp
, oldlenp
));
398 return (sysctl_doprof(name
+ 1, namelen
- 1, oldp
, oldlenp
,
402 return (sysctl_rdint(oldp
, oldlenp
, newp
, _POSIX_VERSION
));
404 return (sysctl_rdint(oldp
, oldlenp
, newp
, NGROUPS_MAX
));
405 case KERN_JOB_CONTROL
:
406 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
408 #ifdef _POSIX_SAVED_IDS
409 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
411 return (sysctl_rdint(oldp
, oldlenp
, newp
, 0));
414 case KERN_MAXPARTITIONS
:
415 return (sysctl_rdint(oldp
, oldlenp
, newp
, MAXPARTITIONS
));
418 return (kdebug_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
420 return (pcsamples_ops(name
+ 1, namelen
- 1, oldp
, oldlenp
, p
));
422 /* new one as it does not use kinfo_proc */
423 return (sysctl_procargs(name
+ 1, namelen
- 1, oldp
, oldlenp
));
427 error
= get_kernel_symfile( p
, &str
);
428 if ( error
) return error
;
429 return (sysctl_rdstring(oldp
, oldlenp
, newp
, str
));
438 * hardware related system variables.
440 hw_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
451 extern int vm_page_wire_count
;
453 ml_ppc_cpu_info_t cpu_info
;
455 ml_ppc_get_info(&cpu_info
);
458 /* all sysctl names at this level are terminal */
460 return (ENOTDIR
); /* overloaded */
464 if(!PEGetMachineName(dummy
,64))
466 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
468 if(!PEGetModelName(dummy
,64))
470 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
473 host_basic_info_data_t hinfo
;
475 int count
= HOST_BASIC_INFO_COUNT
;
478 kret
= host_info(BSD_HOST
, HOST_BASIC_INFO
, &hinfo
, &count
);
479 if (kret
== KERN_SUCCESS
) {
480 numcpus
= hinfo
.avail_cpus
;
481 return (sysctl_rdint(oldp
, oldlenp
, newp
, numcpus
));
487 return (sysctl_rdint(oldp
, oldlenp
, newp
, BYTE_ORDER
));
489 return (sysctl_rdint(oldp
, oldlenp
, newp
, mem_size
));
491 return (sysctl_rdint(oldp
, oldlenp
, newp
,
492 (mem_size
- vm_page_wire_count
* page_size
)));
494 return (sysctl_rdint(oldp
, oldlenp
, newp
, page_size
));
496 epochTemp
= PEGetPlatformEpoch();
497 if (epochTemp
== -1) return(EINVAL
);
498 return (sysctl_rdint(oldp
, oldlenp
, newp
, epochTemp
));
500 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.bus_clock_rate_hz
));
502 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.cpu_clock_rate_hz
));
505 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.vector_unit
));
507 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.cache_line_size
));
508 case HW_L1ICACHESIZE
:
509 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_icache_size
));
510 case HW_L1DCACHESIZE
:
511 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_dcache_size
));
513 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
514 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_settings
));
516 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
517 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_cache_size
));
519 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
520 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_settings
));
522 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
523 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_cache_size
));
532 * Debugging related system variables.
536 #endif /* DIAGNOSTIC */
537 struct ctldebug debug0
, debug1
;
538 struct ctldebug debug2
, debug3
, debug4
;
539 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
540 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
541 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
542 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
543 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
544 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
545 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
546 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
549 debug_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
558 struct ctldebug
*cdp
;
560 /* all sysctl names at this level are name and field */
562 return (ENOTDIR
); /* overloaded */
563 cdp
= debugvars
[name
[0]];
564 if (cdp
->debugname
== 0)
568 return (sysctl_rdstring(oldp
, oldlenp
, newp
, cdp
->debugname
));
569 case CTL_DEBUG_VALUE
:
570 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, cdp
->debugvar
));
579 * Validate parameters and get old / set new parameters
580 * for an integer-valued sysctl function.
582 sysctl_int(oldp
, oldlenp
, newp
, newlen
, valp
)
591 if (oldp
&& *oldlenp
< sizeof(int))
593 if (newp
&& newlen
!= sizeof(int))
595 *oldlenp
= sizeof(int);
597 error
= copyout(valp
, oldp
, sizeof(int));
598 if (error
== 0 && newp
)
599 error
= copyin(newp
, valp
, sizeof(int));
604 * As above, but read-only.
606 sysctl_rdint(oldp
, oldlenp
, newp
, val
)
614 if (oldp
&& *oldlenp
< sizeof(int))
618 *oldlenp
= sizeof(int);
620 error
= copyout((caddr_t
)&val
, oldp
, sizeof(int));
625 * Validate parameters and get old / set new parameters
626 * for a string-valued sysctl function.
628 sysctl_string(oldp
, oldlenp
, newp
, newlen
, str
, maxlen
)
638 len
= strlen(str
) + 1;
639 if (oldp
&& *oldlenp
< len
)
641 if (newp
&& newlen
>= maxlen
)
645 error
= copyout(str
, oldp
, len
);
647 if (error
== 0 && newp
) {
648 error
= copyin(newp
, str
, newlen
);
655 * As above, but read-only.
657 sysctl_rdstring(oldp
, oldlenp
, newp
, str
)
665 len
= strlen(str
) + 1;
666 if (oldp
&& *oldlenp
< len
)
672 error
= copyout(str
, oldp
, len
);
677 * Validate parameters and get old / set new parameters
678 * for a structure oriented sysctl function.
680 sysctl_struct(oldp
, oldlenp
, newp
, newlen
, sp
, len
)
690 if (oldp
&& *oldlenp
< len
)
692 if (newp
&& newlen
> len
)
696 error
= copyout(sp
, oldp
, len
);
698 if (error
== 0 && newp
)
699 error
= copyin(newp
, sp
, len
);
704 * Validate parameters and get old parameters
705 * for a structure oriented sysctl function.
707 sysctl_rdstruct(oldp
, oldlenp
, newp
, sp
, len
)
715 if (oldp
&& *oldlenp
< len
)
721 error
= copyout(sp
, oldp
, len
);
726 * Get file structures.
728 sysctl_file(where
, sizep
)
739 * overestimate by 10 files
741 *sizep
= sizeof(filehead
) + (nfiles
+ 10) * sizeof(struct file
);
746 * first copyout filehead
748 if (buflen
< sizeof(filehead
)) {
752 if (error
= copyout((caddr_t
)&filehead
, where
, sizeof(filehead
)))
754 buflen
-= sizeof(filehead
);
755 where
+= sizeof(filehead
);
758 * followed by an array of file structures
760 for (fp
= filehead
.lh_first
; fp
!= 0; fp
= fp
->f_list
.le_next
) {
761 if (buflen
< sizeof(struct file
)) {
762 *sizep
= where
- start
;
765 if (error
= copyout((caddr_t
)fp
, where
, sizeof (struct file
)))
767 buflen
-= sizeof(struct file
);
768 where
+= sizeof(struct file
);
770 *sizep
= where
- start
;
775 * try over estimating by 5 procs
777 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
779 sysctl_doproc(name
, namelen
, where
, sizep
)
785 register struct proc
*p
;
786 register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
787 register int needed
= 0;
788 int buflen
= where
!= NULL
? *sizep
: 0;
790 struct kinfo_proc kproc
;
793 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
795 p
= allproc
.lh_first
;
798 for (; p
!= 0; p
= p
->p_list
.le_next
) {
800 * Skip embryonic processes.
802 if (p
->p_stat
== SIDL
)
805 * TODO - make more efficient (see notes below).
811 /* could do this with just a lookup */
812 if (p
->p_pid
!= (pid_t
)name
[1])
817 /* could do this by traversing pgrp */
818 if (p
->p_pgrp
->pg_id
!= (pid_t
)name
[1])
823 if ( doingzomb
|| (p
->p_flag
& P_CONTROLT
) == 0 ||
824 p
->p_session
->s_ttyp
== NULL
||
825 p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)name
[1])
830 if (doingzomb
|| (p
->p_ucred
->cr_uid
!= (uid_t
)name
[1]))
835 if ( doingzomb
|| (p
->p_cred
->p_ruid
!= (uid_t
)name
[1]))
839 if (buflen
>= sizeof(struct kinfo_proc
)) {
840 fill_proc(p
, &kproc
, doingzomb
);
841 if (error
= copyout((caddr_t
)&kproc
, &dp
->kp_proc
,
842 sizeof(struct kinfo_proc
)))
845 buflen
-= sizeof(struct kinfo_proc
);
847 needed
+= sizeof(struct kinfo_proc
);
849 if (doingzomb
== 0) {
850 p
= zombproc
.lh_first
;
855 *sizep
= (caddr_t
)dp
- where
;
859 needed
+= KERN_PROCSLOP
;
866 fill_proc(p
,kp
, doingzomb
)
867 register struct proc
*p
;
868 register struct kinfo_proc
*kp
;
871 fill_externproc(p
, &kp
->kp_proc
);
873 fill_eproc(p
, &kp
->kp_eproc
);
876 * Fill in an eproc structure for the specified process.
880 register struct proc
*p
;
881 register struct eproc
*ep
;
883 register struct tty
*tp
;
886 ep
->e_sess
= p
->p_pgrp
->pg_session
;
887 ep
->e_pcred
= *p
->p_cred
;
888 ep
->e_ucred
= *p
->p_ucred
;
889 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
890 ep
->e_vm
.vm_rssize
= 0;
891 ep
->e_vm
.vm_tsize
= 0;
892 ep
->e_vm
.vm_dsize
= 0;
893 ep
->e_vm
.vm_ssize
= 0;
894 /* ep->e_vm.vm_pmap = XXX; */
897 register vm_map_t vm
= ((task_t
)p
->task
)->map
;
899 ep
->e_vm
.vm_rssize
= pmap_resident_count(vm
->pmap
); /*XXX*/
900 // ep->e_vm.vm_tsize = vm->vm_tsize;
901 // ep->e_vm.vm_dsize = vm->vm_dsize;
902 // ep->e_vm.vm_ssize = vm->vm_ssize;
904 ep
->e_vm
.vm_rssize
= 0; /*XXX*/
908 ep
->e_ppid
= p
->p_pptr
->p_pid
;
911 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
912 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
913 if ((p
->p_flag
& P_CONTROLT
) &&
914 (tp
= ep
->e_sess
->s_ttyp
)) {
915 ep
->e_tdev
= tp
->t_dev
;
916 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
917 ep
->e_tsess
= tp
->t_session
;
920 ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
922 ep
->e_flag
|= EPROC_SLEADER
;
924 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
925 ep
->e_xsize
= ep
->e_xrssize
= 0;
926 ep
->e_xccount
= ep
->e_xswrss
= 0;
929 * Fill in an eproc structure for the specified process.
932 fill_externproc(p
, exp
)
933 register struct proc
*p
;
934 register struct extern_proc
*exp
;
936 exp
->p_forw
= exp
->p_back
= NULL
;
937 exp
->p_vmspace
= NULL
;
938 exp
->p_sigacts
= p
->p_sigacts
;
939 exp
->p_flag
= p
->p_flag
;
940 exp
->p_stat
= p
->p_stat
;
941 exp
->p_pid
= p
->p_pid
;
942 exp
->p_oppid
= p
->p_oppid
;
943 exp
->p_dupfd
= p
->p_dupfd
;
945 exp
->user_stack
= p
->user_stack
;
946 exp
->exit_thread
= p
->exit_thread
;
947 exp
->p_debugger
= p
->p_debugger
;
948 exp
->sigwait
= p
->sigwait
;
950 exp
->p_estcpu
= p
->p_estcpu
;
951 exp
->p_cpticks
= p
->p_cpticks
;
952 exp
->p_pctcpu
= p
->p_pctcpu
;
953 exp
->p_wchan
= p
->p_wchan
;
954 exp
->p_wmesg
= p
->p_wmesg
;
955 exp
->p_swtime
= p
->p_swtime
;
956 exp
->p_slptime
= p
->p_slptime
;
957 bcopy(&p
->p_realtimer
, &exp
->p_realtimer
,sizeof(struct itimerval
));
958 bcopy(&p
->p_rtime
, &exp
->p_rtime
,sizeof(struct timeval
));
959 exp
->p_uticks
= p
->p_uticks
;
960 exp
->p_sticks
= p
->p_sticks
;
961 exp
->p_iticks
= p
->p_iticks
;
962 exp
->p_traceflag
= p
->p_traceflag
;
963 exp
->p_tracep
= p
->p_tracep
;
964 exp
->p_siglist
= p
->p_siglist
;
965 exp
->p_textvp
= p
->p_textvp
;
967 exp
->p_sigmask
= p
->p_sigmask
;
968 exp
->p_sigignore
= p
->p_sigignore
;
969 exp
->p_sigcatch
= p
->p_sigcatch
;
970 exp
->p_priority
= p
->p_priority
;
971 exp
->p_usrpri
= p
->p_usrpri
;
972 exp
->p_nice
= p
->p_nice
;
973 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
974 exp
->p_comm
[MAXCOMLEN
] = '\0';
975 exp
->p_pgrp
= p
->p_pgrp
;
977 exp
->p_xstat
= p
->p_xstat
;
978 exp
->p_acflag
= p
->p_acflag
;
979 exp
->p_ru
= p
->p_ru
;
982 kdebug_ops(name
, namelen
, where
, sizep
, p
)
991 extern int kdbg_control(int *name
, u_int namelen
, char * where
,size_t * sizep
);
993 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1009 case KERN_KDSETRTCDEC
:
1011 ret
= kdbg_control(name
, namelen
, where
, sizep
);
1020 pcsamples_ops(name
, namelen
, where
, sizep
, p
)
1028 extern int pcsamples_control(int *name
, u_int namelen
, char * where
,size_t * sizep
);
1030 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1034 case KERN_PCDISABLE
:
1038 case KERN_PCREADBUF
:
1042 ret
= pcsamples_control(name
, namelen
, where
, sizep
);
1052 * Returns the top N bytes of the user stack, with
1053 * everything below the first argument character
1054 * zeroed for security reasons.
1055 * Odd data structure is for compatibility.
1057 sysctl_procargs(name
, namelen
, where
, sizep
)
1063 register struct proc
*p
;
1064 register int needed
= 0;
1065 int buflen
= where
!= NULL
? *sizep
: 0;
1067 struct vm_map
*proc_map
;
1070 vm_offset_t arg_addr
;
1074 vm_offset_t copy_start
, copy_end
;
1075 vm_offset_t dealloc_start
; /* area to remove from kernel map */
1076 vm_offset_t dealloc_end
;
1082 if ((buflen
<= 0) || (buflen
> (PAGE_SIZE
<< 1))) {
1088 * Lookup process by pid
1098 * Copy the top N bytes of the stack.
1099 * On all machines we have so far, the stack grows
1102 * If the user expects no more than N bytes of
1103 * argument list, use that as a guess for the
1110 arg_addr
= (vm_offset_t
)(p
->user_stack
- arg_size
);
1114 * Before we can block (any VM code), make another
1115 * reference to the map to keep it alive. We do
1116 * that by getting a reference on the task itself.
1122 task_reference(task
);
1124 ret
= kmem_alloc(kernel_map
, ©_start
, round_page(arg_size
));
1125 if (ret
!= KERN_SUCCESS
) {
1126 task_deallocate(task
);
1130 proc_map
= get_task_map(task
);
1131 copy_end
= round_page(copy_start
+ arg_size
);
1133 if( vm_map_copyin(proc_map
, trunc_page(arg_addr
), round_page(arg_size
),
1134 FALSE
, &tmp
) != KERN_SUCCESS
) {
1135 task_deallocate(task
);
1136 kmem_free(kernel_map
, copy_start
,
1137 round_page(arg_size
));
1142 * Now that we've done the copyin from the process'
1143 * map, we can release the reference to it.
1145 task_deallocate(task
);
1147 if( vm_map_copy_overwrite(kernel_map
, copy_start
,
1148 tmp
, FALSE
) != KERN_SUCCESS
) {
1149 kmem_free(kernel_map
, copy_start
,
1150 round_page(arg_size
));
1154 data
= (caddr_t
) (copy_end
- arg_size
);
1155 ip
= (int *) copy_end
;
1159 * Now look down the stack for the bottom of the
1160 * argument list. Since this call is otherwise
1161 * unprotected, we can't let the nosy user see
1162 * anything else on the stack.
1164 * The arguments are pushed on the stack by
1168 * arg 0 (null-terminated)
1176 ip
-= 2; /*skip trailing 0 word and assume at least one
1177 argument. The last word of argN may be just
1178 the trailing 0, in which case we'd stop
1181 if (ip
== (int *)data
)
1184 * To account for saved path name and not having a null after that
1185 * Run the sweep again. If we have already sweeped entire range skip this
1187 if (ip
!= (int *)data
) {
1189 if (ip
== (int *)data
)
1193 bzero(data
, (unsigned) ((int)ip
- (int)data
));
1195 dealloc_start
= copy_start
;
1196 dealloc_end
= copy_end
;
1199 size
= MIN(size
, buflen
);
1200 error
= copyout(data
, where
, size
);
1202 if (dealloc_start
!= (vm_offset_t
) 0) {
1203 kmem_free(kernel_map
, dealloc_start
,
1204 dealloc_end
- dealloc_start
);