2 * Copyright (c) 2000-2002 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>
80 #include <mach/machine.h>
81 #include <mach/mach_types.h>
82 #include <mach/vm_param.h>
83 #include <kern/task.h>
84 #include <vm/vm_kern.h>
85 #include <mach/host_info.h>
87 extern vm_map_t bsd_pageable_map
;
89 #include <sys/mount.h>
90 #include <sys/kdebug.h>
92 #include <IOKit/IOPlatformExpert.h>
93 #include <pexpert/pexpert.h>
96 #include <ppc/machine_routines.h>
102 sysctlfn debug_sysctl
;
104 extern sysctlfn vm_sysctl
;
105 extern sysctlfn vfs_sysctl
;
106 extern sysctlfn net_sysctl
;
107 extern sysctlfn cpu_sysctl
;
111 userland_sysctl(struct proc
*p
, int *name
, u_int namelen
, void *old
, size_t
112 *oldlenp
, int inkernel
, void *new, size_t newlen
, size_t *retval
);
115 fill_proc(struct proc
*p
,struct kinfo_proc
*kp
, int doingzomb
);
118 fill_externproc(struct proc
*p
, struct extern_proc
*exp
);
123 * temporary location for vm_sysctl. This should be machine independant
126 vm_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
135 extern uint32_t mach_factor
[3];
136 struct loadavg loadinfo
;
140 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
141 &averunnable
, sizeof(struct loadavg
)));
143 loadinfo
.ldavg
[0] = mach_factor
[0];
144 loadinfo
.ldavg
[1] = mach_factor
[1];
145 loadinfo
.ldavg
[2] = mach_factor
[2];
146 loadinfo
.fscale
= LSCALE
;
147 return (sysctl_struct(oldp
, oldlenp
, newp
, newlen
,
148 &loadinfo
, sizeof(struct loadavg
)));
163 static struct sysctl_lock
{
169 struct __sysctl_args
{
178 __sysctl(p
, uap
, retval
)
180 register struct __sysctl_args
*uap
;
183 int error
, dolock
= 1;
184 size_t savelen
, oldlen
= 0;
186 int name
[CTL_MAXNAME
];
191 * all top-level sysctl names are non-terminal
193 if (uap
->namelen
> CTL_MAXNAME
|| uap
->namelen
< 2)
196 copyin(uap
->name
, &name
, uap
->namelen
* sizeof(int)))
199 /* CTL_UNSPEC is used to get oid to AUTO_OID */
201 && ((name
[0] == CTL_KERN
202 && !(name
[1] == KERN_IPC
|| name
[1] == KERN_PANICINFO
))
203 || (name
[0] == CTL_HW
)
204 || (name
[0] == CTL_VM
)
205 || (name
[0] == CTL_VFS
))
206 && (error
= suser(p
->p_ucred
, &p
->p_acflag
)))
212 if ((name
[1] != KERN_VNODE
) && (name
[1] != KERN_FILE
)
213 && (name
[1] != KERN_PROC
))
236 (error
= copyin(uap
->oldlenp
, &oldlen
, sizeof(oldlen
))))
239 if (uap
->old
!= NULL
) {
240 if (!useracc(uap
->old
, oldlen
, B_WRITE
))
243 /* The pc sampling mechanism does not need to take this lock */
244 if ((name
[1] != KERN_PCSAMPLES
) &&
245 (!((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
246 while (memlock
.sl_lock
) {
248 sleep((caddr_t
)&memlock
, PRIBIO
+1);
254 if (dolock
&& oldlen
&& (error
= vslock(uap
->old
, oldlen
))) {
255 if ((name
[1] != KERN_PCSAMPLES
) &&
256 (! ((name
[1] == KERN_KDEBUG
) && (name
[2] == KERN_KDGETENTROPY
)))) {
258 if (memlock
.sl_want
) {
260 wakeup((caddr_t
)&memlock
);
269 error
= (*fn
)(name
+ 1, uap
->namelen
- 1, uap
->old
,
270 &oldlen
, uap
->new, uap
->newlen
, p
);
274 if ( (name
[0] != CTL_VFS
) && (error
== EOPNOTSUPP
))
275 error
= userland_sysctl(p
, name
, uap
->namelen
,
276 uap
->old
, uap
->oldlenp
, 0,
277 uap
->new, uap
->newlen
, &oldlen
);
279 if (uap
->old
!= NULL
) {
280 if (dolock
&& savelen
) {
281 error1
= vsunlock(uap
->old
, savelen
, B_WRITE
);
282 if (!error
&& error1
)
285 if (name
[1] != KERN_PCSAMPLES
) {
287 if (memlock
.sl_want
) {
289 wakeup((caddr_t
)&memlock
);
293 if ((error
) && (error
!= ENOMEM
))
297 i
= copyout(&oldlen
, uap
->oldlenp
, sizeof(oldlen
));
306 * Attributes stored in the kernel.
308 extern char hostname
[MAXHOSTNAMELEN
]; /* defined in bsd/kern/init_main.c */
309 extern int hostnamelen
;
310 extern char domainname
[MAXHOSTNAMELEN
];
311 extern int domainnamelen
;
314 int securelevel
= -1;
319 extern int get_kernel_symfile( struct proc
*, char **);
320 extern int sysctl_dopanicinfo(int *, u_int
, void *, size_t *,
321 void *, size_t, struct proc
*);
324 * kernel related system variables.
327 kern_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
336 int error
, level
, inthostid
;
337 unsigned int oldval
=0;
339 extern char ostype
[], osrelease
[], version
[];
340 extern int netboot_root();
342 /* all sysctl names not listed below are terminal at this level */
344 && !(name
[0] == KERN_PROC
345 || name
[0] == KERN_PROF
346 || name
[0] == KERN_KDEBUG
347 || name
[0] == KERN_PROCARGS
348 || name
[0] == KERN_PCSAMPLES
349 || name
[0] == KERN_IPC
350 || name
[0] == KERN_SYSV
351 || name
[0] == KERN_PANICINFO
)
353 return (ENOTDIR
); /* overloaded */
357 return (sysctl_rdstring(oldp
, oldlenp
, newp
, ostype
));
359 return (sysctl_rdstring(oldp
, oldlenp
, newp
, osrelease
));
361 return (sysctl_rdint(oldp
, oldlenp
, newp
, BSD
));
363 return (sysctl_rdstring(oldp
, oldlenp
, newp
, version
));
365 oldval
= desiredvnodes
;
366 error
= sysctl_int(oldp
, oldlenp
, newp
,
367 newlen
, &desiredvnodes
);
368 reset_vmobjectcache(oldval
, desiredvnodes
);
371 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxproc
));
373 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, &maxfiles
));
375 return (sysctl_rdint(oldp
, oldlenp
, newp
, ARG_MAX
));
378 if ((error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &level
)) ||
381 if (level
< securelevel
&& p
->p_pid
!= 1)
386 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
387 hostname
, sizeof(hostname
));
389 hostnamelen
= newlen
;
391 case KERN_DOMAINNAME
:
392 error
= sysctl_string(oldp
, oldlenp
, newp
, newlen
,
393 domainname
, sizeof(domainname
));
395 domainnamelen
= newlen
;
398 inthostid
= hostid
; /* XXX assumes sizeof long <= sizeof int */
399 error
= sysctl_int(oldp
, oldlenp
, newp
, newlen
, &inthostid
);
403 return (sysctl_clockrate(oldp
, oldlenp
));
405 return (sysctl_rdstruct(oldp
, oldlenp
, newp
, &boottime
,
406 sizeof(struct timeval
)));
408 return (sysctl_vnode(oldp
, oldlenp
));
410 return (sysctl_doproc(name
+ 1, namelen
- 1, oldp
, oldlenp
));
412 return (sysctl_file(oldp
, oldlenp
));
415 return (sysctl_doprof(name
+ 1, namelen
- 1, oldp
, oldlenp
,
419 return (sysctl_rdint(oldp
, oldlenp
, newp
, _POSIX_VERSION
));
421 return (sysctl_rdint(oldp
, oldlenp
, newp
, NGROUPS_MAX
));
422 case KERN_JOB_CONTROL
:
423 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
425 #ifdef _POSIX_SAVED_IDS
426 return (sysctl_rdint(oldp
, oldlenp
, newp
, 1));
428 return (sysctl_rdint(oldp
, oldlenp
, newp
, 0));
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
, p
));
438 error
= get_kernel_symfile( p
, &str
);
441 return (sysctl_rdstring(oldp
, oldlenp
, newp
, str
));
443 return (sysctl_rdint(oldp
, oldlenp
, newp
, netboot_root()));
445 return(sysctl_dopanicinfo(name
+ 1, namelen
- 1, oldp
, oldlenp
,
454 * hardware related system variables.
456 hw_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
467 extern int vm_page_wire_count
;
469 ml_ppc_cpu_info_t cpu_info
;
471 ml_ppc_get_info(&cpu_info
);
474 /* all sysctl names at this level are terminal */
476 return (ENOTDIR
); /* overloaded */
480 if(!PEGetMachineName(dummy
,64))
482 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
484 if(!PEGetModelName(dummy
,64))
486 return (sysctl_rdstring(oldp
, oldlenp
, newp
, dummy
));
490 host_basic_info_data_t hinfo
;
492 int count
= HOST_BASIC_INFO_COUNT
;
495 kret
= host_info(BSD_HOST
, HOST_BASIC_INFO
, &hinfo
, &count
);
496 if (kret
== KERN_SUCCESS
) {
497 numcpus
= hinfo
.avail_cpus
;
498 return (sysctl_rdint(oldp
, oldlenp
, newp
, numcpus
));
504 return (sysctl_rdint(oldp
, oldlenp
, newp
, BYTE_ORDER
));
506 return (sysctl_rdint(oldp
, oldlenp
, newp
, mem_size
));
508 return (sysctl_rdint(oldp
, oldlenp
, newp
,
509 (mem_size
- vm_page_wire_count
* page_size
)));
511 return (sysctl_rdint(oldp
, oldlenp
, newp
, page_size
));
513 epochTemp
= PEGetPlatformEpoch();
514 if (epochTemp
== -1) return(EINVAL
);
515 return (sysctl_rdint(oldp
, oldlenp
, newp
, epochTemp
));
517 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.bus_clock_rate_hz
));
519 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.cpu_clock_rate_hz
));
521 return (sysctl_rdint(oldp
, oldlenp
, newp
, gPEClockFrequencyInfo
.timebase_frequency_hz
));
524 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.vector_unit
));
526 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.cache_line_size
));
527 case HW_L1ICACHESIZE
:
528 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_icache_size
));
529 case HW_L1DCACHESIZE
:
530 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l1_dcache_size
));
532 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
533 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_settings
));
535 if (cpu_info
.l2_cache_size
== 0xFFFFFFFF) return(EINVAL
);
536 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l2_cache_size
));
538 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
539 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_settings
));
541 if (cpu_info
.l3_cache_size
== 0xFFFFFFFF) return(EINVAL
);
542 return (sysctl_rdint(oldp
, oldlenp
, newp
, cpu_info
.l3_cache_size
));
551 * Debugging related system variables.
555 #endif /* DIAGNOSTIC */
556 struct ctldebug debug0
, debug1
;
557 struct ctldebug debug2
, debug3
, debug4
;
558 struct ctldebug debug5
, debug6
, debug7
, debug8
, debug9
;
559 struct ctldebug debug10
, debug11
, debug12
, debug13
, debug14
;
560 struct ctldebug debug15
, debug16
, debug17
, debug18
, debug19
;
561 static struct ctldebug
*debugvars
[CTL_DEBUG_MAXID
] = {
562 &debug0
, &debug1
, &debug2
, &debug3
, &debug4
,
563 &debug5
, &debug6
, &debug7
, &debug8
, &debug9
,
564 &debug10
, &debug11
, &debug12
, &debug13
, &debug14
,
565 &debug15
, &debug16
, &debug17
, &debug18
, &debug19
,
568 debug_sysctl(name
, namelen
, oldp
, oldlenp
, newp
, newlen
, p
)
577 struct ctldebug
*cdp
;
579 /* all sysctl names at this level are name and field */
581 return (ENOTDIR
); /* overloaded */
582 cdp
= debugvars
[name
[0]];
583 if (cdp
->debugname
== 0)
587 return (sysctl_rdstring(oldp
, oldlenp
, newp
, cdp
->debugname
));
588 case CTL_DEBUG_VALUE
:
589 return (sysctl_int(oldp
, oldlenp
, newp
, newlen
, cdp
->debugvar
));
598 * Validate parameters and get old / set new parameters
599 * for an integer-valued sysctl function.
602 sysctl_int(oldp
, oldlenp
, newp
, newlen
, valp
)
611 if (oldp
&& *oldlenp
< sizeof(int))
613 if (newp
&& newlen
!= sizeof(int))
615 *oldlenp
= sizeof(int);
617 error
= copyout(valp
, oldp
, sizeof(int));
618 if (error
== 0 && newp
)
619 error
= copyin(newp
, valp
, sizeof(int));
624 * As above, but read-only.
627 sysctl_rdint(oldp
, oldlenp
, newp
, val
)
635 if (oldp
&& *oldlenp
< sizeof(int))
639 *oldlenp
= sizeof(int);
641 error
= copyout((caddr_t
)&val
, oldp
, sizeof(int));
646 * Validate parameters and get old / set new parameters
647 * for an quad(64bit)-valued sysctl function.
650 sysctl_quad(oldp
, oldlenp
, newp
, newlen
, valp
)
659 if (oldp
&& *oldlenp
< sizeof(quad_t
))
661 if (newp
&& newlen
!= sizeof(quad_t
))
663 *oldlenp
= sizeof(quad_t
);
665 error
= copyout(valp
, oldp
, sizeof(quad_t
));
666 if (error
== 0 && newp
)
667 error
= copyin(newp
, valp
, sizeof(quad_t
));
672 * As above, but read-only.
675 sysctl_rdquad(oldp
, oldlenp
, newp
, val
)
683 if (oldp
&& *oldlenp
< sizeof(quad_t
))
687 *oldlenp
= sizeof(quad_t
);
689 error
= copyout((caddr_t
)&val
, oldp
, sizeof(quad_t
));
694 * Validate parameters and get old / set new parameters
695 * for a string-valued sysctl function.
698 sysctl_string(oldp
, oldlenp
, newp
, newlen
, str
, maxlen
)
708 len
= strlen(str
) + 1;
709 if (oldp
&& *oldlenp
< len
)
711 if (newp
&& newlen
>= maxlen
)
713 *oldlenp
= len
-1; /* deal with NULL strings correctly */
715 error
= copyout(str
, oldp
, len
);
717 if (error
== 0 && newp
) {
718 error
= copyin(newp
, str
, newlen
);
725 * As above, but read-only.
728 sysctl_rdstring(oldp
, oldlenp
, newp
, str
)
736 len
= strlen(str
) + 1;
737 if (oldp
&& *oldlenp
< len
)
743 error
= copyout(str
, oldp
, len
);
748 * Validate parameters and get old / set new parameters
749 * for a structure oriented sysctl function.
752 sysctl_struct(oldp
, oldlenp
, newp
, newlen
, sp
, len
)
762 if (oldp
&& *oldlenp
< len
)
764 if (newp
&& newlen
> len
)
768 error
= copyout(sp
, oldp
, len
);
770 if (error
== 0 && newp
)
771 error
= copyin(newp
, sp
, len
);
776 * Validate parameters and get old parameters
777 * for a structure oriented sysctl function.
780 sysctl_rdstruct(oldp
, oldlenp
, newp
, sp
, len
)
788 if (oldp
&& *oldlenp
< len
)
794 error
= copyout(sp
, oldp
, len
);
799 * Get file structures.
802 sysctl_file(where
, sizep
)
813 * overestimate by 10 files
815 *sizep
= sizeof(filehead
) + (nfiles
+ 10) * sizeof(struct file
);
820 * first copyout filehead
822 if (buflen
< sizeof(filehead
)) {
826 if (error
= copyout((caddr_t
)&filehead
, where
, sizeof(filehead
)))
828 buflen
-= sizeof(filehead
);
829 where
+= sizeof(filehead
);
832 * followed by an array of file structures
834 for (fp
= filehead
.lh_first
; fp
!= 0; fp
= fp
->f_list
.le_next
) {
835 if (buflen
< sizeof(struct file
)) {
836 *sizep
= where
- start
;
839 if (error
= copyout((caddr_t
)fp
, where
, sizeof (struct file
)))
841 buflen
-= sizeof(struct file
);
842 where
+= sizeof(struct file
);
844 *sizep
= where
- start
;
849 * try over estimating by 5 procs
851 #define KERN_PROCSLOP (5 * sizeof (struct kinfo_proc))
854 sysctl_doproc(name
, namelen
, where
, sizep
)
860 register struct proc
*p
;
861 register struct kinfo_proc
*dp
= (struct kinfo_proc
*)where
;
862 register int needed
= 0;
863 int buflen
= where
!= NULL
? *sizep
: 0;
865 struct kinfo_proc kproc
;
868 if (namelen
!= 2 && !(namelen
== 1 && name
[0] == KERN_PROC_ALL
))
870 p
= allproc
.lh_first
;
873 for (; p
!= 0; p
= p
->p_list
.le_next
) {
875 * Skip embryonic processes.
877 if (p
->p_stat
== SIDL
)
880 * TODO - make more efficient (see notes below).
886 /* could do this with just a lookup */
887 if (p
->p_pid
!= (pid_t
)name
[1])
892 /* could do this by traversing pgrp */
893 if (p
->p_pgrp
->pg_id
!= (pid_t
)name
[1])
898 if ( doingzomb
|| (p
->p_flag
& P_CONTROLT
) == 0 ||
899 p
->p_session
->s_ttyp
== NULL
||
900 p
->p_session
->s_ttyp
->t_dev
!= (dev_t
)name
[1])
905 if (doingzomb
|| (p
->p_ucred
->cr_uid
!= (uid_t
)name
[1]))
910 if ( doingzomb
|| (p
->p_cred
->p_ruid
!= (uid_t
)name
[1]))
914 if (buflen
>= sizeof(struct kinfo_proc
)) {
915 bzero(&kproc
, sizeof(struct kinfo_proc
));
916 fill_proc(p
, &kproc
, doingzomb
);
917 if (error
= copyout((caddr_t
)&kproc
, &dp
->kp_proc
,
918 sizeof(struct kinfo_proc
)))
921 buflen
-= sizeof(struct kinfo_proc
);
923 needed
+= sizeof(struct kinfo_proc
);
925 if (doingzomb
== 0) {
926 p
= zombproc
.lh_first
;
931 *sizep
= (caddr_t
)dp
- where
;
935 needed
+= KERN_PROCSLOP
;
942 fill_proc(p
,kp
, doingzomb
)
943 register struct proc
*p
;
944 register struct kinfo_proc
*kp
;
947 fill_externproc(p
, &kp
->kp_proc
);
949 fill_eproc(p
, &kp
->kp_eproc
);
952 * Fill in an eproc structure for the specified process.
956 register struct proc
*p
;
957 register struct eproc
*ep
;
959 register struct tty
*tp
;
962 * Skip zombie processes.
964 if (p
->p_stat
== SZOMB
)
968 ep
->e_sess
= p
->p_pgrp
->pg_session
;
969 ep
->e_pcred
= *p
->p_cred
;
970 ep
->e_ucred
= *p
->p_ucred
;
971 if (p
->p_stat
== SIDL
|| p
->p_stat
== SZOMB
) {
972 ep
->e_vm
.vm_tsize
= 0;
973 ep
->e_vm
.vm_dsize
= 0;
974 ep
->e_vm
.vm_ssize
= 0;
976 ep
->e_vm
.vm_rssize
= 0;
978 ep
->e_ppid
= p
->p_pptr
->p_pid
;
981 ep
->e_pgid
= p
->p_pgrp
->pg_id
;
982 ep
->e_jobc
= p
->p_pgrp
->pg_jobc
;
983 if ((p
->p_flag
& P_CONTROLT
) &&
984 (tp
= ep
->e_sess
->s_ttyp
)) {
985 ep
->e_tdev
= tp
->t_dev
;
986 ep
->e_tpgid
= tp
->t_pgrp
? tp
->t_pgrp
->pg_id
: NO_PID
;
987 ep
->e_tsess
= tp
->t_session
;
990 ep
->e_flag
= ep
->e_sess
->s_ttyvp
? EPROC_CTTY
: 0;
992 ep
->e_flag
|= EPROC_SLEADER
;
994 strncpy(ep
->e_wmesg
, p
->p_wmesg
, WMESGLEN
);
995 ep
->e_xsize
= ep
->e_xrssize
= 0;
996 ep
->e_xccount
= ep
->e_xswrss
= 0;
999 * Fill in an eproc structure for the specified process.
1002 fill_externproc(p
, exp
)
1003 register struct proc
*p
;
1004 register struct extern_proc
*exp
;
1006 exp
->p_forw
= exp
->p_back
= NULL
;
1008 exp
->p_starttime
= p
->p_stats
->p_start
;
1009 exp
->p_vmspace
= NULL
;
1010 exp
->p_sigacts
= p
->p_sigacts
;
1011 exp
->p_flag
= p
->p_flag
;
1012 exp
->p_stat
= p
->p_stat
;
1013 exp
->p_pid
= p
->p_pid
;
1014 exp
->p_oppid
= p
->p_oppid
;
1015 exp
->p_dupfd
= p
->p_dupfd
;
1017 exp
->user_stack
= p
->user_stack
;
1018 exp
->exit_thread
= p
->exit_thread
;
1019 exp
->p_debugger
= p
->p_debugger
;
1020 exp
->sigwait
= p
->sigwait
;
1022 exp
->p_estcpu
= p
->p_estcpu
;
1023 exp
->p_cpticks
= p
->p_cpticks
;
1024 exp
->p_pctcpu
= p
->p_pctcpu
;
1025 exp
->p_wchan
= p
->p_wchan
;
1026 exp
->p_wmesg
= p
->p_wmesg
;
1027 exp
->p_swtime
= p
->p_swtime
;
1028 exp
->p_slptime
= p
->p_slptime
;
1029 bcopy(&p
->p_realtimer
, &exp
->p_realtimer
,sizeof(struct itimerval
));
1030 bcopy(&p
->p_rtime
, &exp
->p_rtime
,sizeof(struct timeval
));
1031 exp
->p_uticks
= p
->p_uticks
;
1032 exp
->p_sticks
= p
->p_sticks
;
1033 exp
->p_iticks
= p
->p_iticks
;
1034 exp
->p_traceflag
= p
->p_traceflag
;
1035 exp
->p_tracep
= p
->p_tracep
;
1036 exp
->p_siglist
= 0 ; /* No longer relevant */
1037 exp
->p_textvp
= p
->p_textvp
;
1038 exp
->p_holdcnt
= 0 ;
1039 exp
->p_sigmask
= 0 ; /* no longer avaialable */
1040 exp
->p_sigignore
= p
->p_sigignore
;
1041 exp
->p_sigcatch
= p
->p_sigcatch
;
1042 exp
->p_priority
= p
->p_priority
;
1043 exp
->p_usrpri
= p
->p_usrpri
;
1044 exp
->p_nice
= p
->p_nice
;
1045 bcopy(&p
->p_comm
, &exp
->p_comm
,MAXCOMLEN
);
1046 exp
->p_comm
[MAXCOMLEN
] = '\0';
1047 exp
->p_pgrp
= p
->p_pgrp
;
1049 exp
->p_xstat
= p
->p_xstat
;
1050 exp
->p_acflag
= p
->p_acflag
;
1051 exp
->p_ru
= p
->p_ru
;
1055 kdebug_ops(name
, namelen
, where
, sizep
, p
)
1064 extern int kdbg_control(int *name
, u_int namelen
,
1065 char * where
,size_t * sizep
);
1067 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1083 case KERN_KDSETRTCDEC
:
1085 case KERN_KDGETENTROPY
:
1086 ret
= kdbg_control(name
, namelen
, where
, sizep
);
1096 pcsamples_ops(name
, namelen
, where
, sizep
, p
)
1104 extern int pcsamples_control(int *name
, u_int namelen
,
1105 char * where
,size_t * sizep
);
1107 if (ret
= suser(p
->p_ucred
, &p
->p_acflag
))
1111 case KERN_PCDISABLE
:
1115 case KERN_PCREADBUF
:
1119 ret
= pcsamples_control(name
, namelen
, where
, sizep
);
1129 * Returns the top N bytes of the user stack, with
1130 * everything below the first argument character
1131 * zeroed for security reasons.
1132 * Odd data structure is for compatibility.
1135 sysctl_procargs(name
, namelen
, where
, sizep
, cur_proc
)
1140 struct proc
*cur_proc
;
1142 register struct proc
*p
;
1143 register int needed
= 0;
1144 int buflen
= where
!= NULL
? *sizep
: 0;
1146 struct vm_map
*proc_map
;
1149 vm_offset_t arg_addr
;
1153 vm_offset_t copy_start
, copy_end
;
1154 vm_offset_t dealloc_start
; /* area to remove from kernel map */
1155 vm_offset_t dealloc_end
;
1161 if ((buflen
<= 0) || (buflen
> (PAGE_SIZE
<< 1))) {
1167 * Lookup process by pid
1178 * Copy the top N bytes of the stack.
1179 * On all machines we have so far, the stack grows
1182 * If the user expects no more than N bytes of
1183 * argument list, use that as a guess for the
1190 if ((p
->p_ucred
->cr_uid
!= cur_proc
->p_ucred
->cr_uid
)
1191 && suser(cur_proc
->p_ucred
, &cur_proc
->p_acflag
))
1193 arg_addr
= (vm_offset_t
)(p
->user_stack
- arg_size
);
1197 * Before we can block (any VM code), make another
1198 * reference to the map to keep it alive. We do
1199 * that by getting a reference on the task itself.
1206 * A regular task_reference call can block, causing the funnel
1207 * to be dropped and allowing the proc/task to get freed.
1208 * Instead, we issue a non-blocking attempt at the task reference,
1209 * and look up the proc/task all over again if that fails.
1211 if (!task_reference_try(task
)) {
1216 ret
= kmem_alloc(kernel_map
, ©_start
, round_page(arg_size
));
1217 if (ret
!= KERN_SUCCESS
) {
1218 task_deallocate(task
);
1222 proc_map
= get_task_map(task
);
1223 copy_end
= round_page(copy_start
+ arg_size
);
1225 if( vm_map_copyin(proc_map
, trunc_page(arg_addr
), round_page(arg_size
),
1226 FALSE
, &tmp
) != KERN_SUCCESS
) {
1227 task_deallocate(task
);
1228 kmem_free(kernel_map
, copy_start
,
1229 round_page(arg_size
));
1234 * Now that we've done the copyin from the process'
1235 * map, we can release the reference to it.
1237 task_deallocate(task
);
1239 if( vm_map_copy_overwrite(kernel_map
, copy_start
,
1240 tmp
, FALSE
) != KERN_SUCCESS
) {
1241 kmem_free(kernel_map
, copy_start
,
1242 round_page(arg_size
));
1246 data
= (caddr_t
) (copy_end
- arg_size
);
1247 ip
= (int *) copy_end
;
1251 * Now look down the stack for the bottom of the
1252 * argument list. Since this call is otherwise
1253 * unprotected, we can't let the nosy user see
1254 * anything else on the stack.
1256 * The arguments are pushed on the stack by
1260 * arg 0 (null-terminated)
1268 ip
-= 2; /*skip trailing 0 word and assume at least one
1269 argument. The last word of argN may be just
1270 the trailing 0, in which case we'd stop
1273 if (ip
== (int *)data
)
1276 * To account for saved path name and not having a null after that
1277 * Run the sweep again. If we have already sweeped entire range skip this
1279 if (ip
!= (int *)data
) {
1281 if (ip
== (int *)data
)
1285 bzero(data
, (unsigned) ((int)ip
- (int)data
));
1287 dealloc_start
= copy_start
;
1288 dealloc_end
= copy_end
;
1291 size
= MIN(size
, buflen
);
1292 error
= copyout(data
, where
, size
);
1294 if (dealloc_start
!= (vm_offset_t
) 0) {
1295 kmem_free(kernel_map
, dealloc_start
,
1296 dealloc_end
- dealloc_start
);