2 * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
24 #include <sys/cdefs.h>
29 #include <sys/errno.h>
30 #include <sys/msgbuf.h>
31 #define CONFIG_EMBEDDED 1
32 #include <sys/process_policy.h>
34 #include "libproc_internal.h"
36 int __proc_info(int callnum
, int pid
, int flavor
, uint64_t arg
, void * buffer
, int buffersize
);
37 __private_extern__
int proc_setthreadname(void * buffer
, int buffersize
);
38 int __process_policy(int scope
, int action
, int policy
, int policy_subtype
, proc_policy_attribute_t
* attrp
, pid_t target_pid
, uint64_t target_threadid
);
43 proc_listpids(uint32_t type
, uint32_t typeinfo
, void *buffer
, int buffersize
)
47 if ((type
>= PROC_ALL_PIDS
) || (type
<= PROC_PPID_ONLY
)) {
48 if ((retval
= __proc_info(1, type
, typeinfo
,(uint64_t)0, buffer
, buffersize
)) == -1)
59 proc_listallpids(void * buffer
, int buffersize
)
62 numpids
= proc_listpids(PROC_ALL_PIDS
, (uint32_t)0, buffer
, buffersize
);
67 return(numpids
/sizeof(int));
71 proc_listpgrppids(pid_t pgrpid
, void * buffer
, int buffersize
)
74 numpids
= proc_listpids(PROC_PGRP_ONLY
, (uint32_t)pgrpid
, buffer
, buffersize
);
78 return(numpids
/sizeof(int));
82 proc_listchildpids(pid_t ppid
, void * buffer
, int buffersize
)
85 numpids
= proc_listpids(PROC_PPID_ONLY
, (uint32_t)ppid
, buffer
, buffersize
);
89 return(numpids
/sizeof(int));
94 proc_pidinfo(int pid
, int flavor
, uint64_t arg
, void *buffer
, int buffersize
)
98 if ((retval
= __proc_info(2, pid
, flavor
, arg
, buffer
, buffersize
)) == -1)
106 proc_pidfdinfo(int pid
, int fd
, int flavor
, void * buffer
, int buffersize
)
110 if ((retval
= __proc_info(3, pid
, flavor
, (uint64_t)fd
, buffer
, buffersize
)) == -1)
118 proc_pidfileportinfo(int pid
, uint32_t fileport
, int flavor
, void *buffer
, int buffersize
)
122 if ((retval
= __proc_info(6, pid
, flavor
, (uint64_t)fileport
, buffer
, buffersize
)) == -1)
129 proc_name(int pid
, void * buffer
, uint32_t buffersize
)
132 struct proc_bsdinfo pbsd
;
135 if (buffersize
< sizeof(pbsd
.pbi_name
)) {
140 retval
= proc_pidinfo(pid
, PROC_PIDTBSDINFO
, (uint64_t)0, &pbsd
, sizeof(struct proc_bsdinfo
));
142 if (pbsd
.pbi_name
[0]) {
143 bcopy(&pbsd
.pbi_name
, buffer
, sizeof(pbsd
.pbi_name
));
145 bcopy(&pbsd
.pbi_comm
, buffer
, sizeof(pbsd
.pbi_comm
));
147 len
= strlen(buffer
);
154 proc_regionfilename(int pid
, uint64_t address
, void * buffer
, uint32_t buffersize
)
157 struct proc_regionwithpathinfo reginfo
;
159 if (buffersize
< MAXPATHLEN
) {
164 retval
= proc_pidinfo(pid
, PROC_PIDREGIONPATHINFO
, (uint64_t)address
, ®info
, sizeof(struct proc_regionwithpathinfo
));
166 len
= strlen(®info
.prp_vip
.vip_path
[0]);
168 if (len
> MAXPATHLEN
)
170 bcopy(®info
.prp_vip
.vip_path
[0], buffer
, len
);
180 proc_kmsgbuf(void * buffer
, uint32_t buffersize
)
184 if ((retval
= __proc_info(4, 0, 0, (uint64_t)0, buffer
, buffersize
)) == -1)
190 proc_pidpath(int pid
, void * buffer
, uint32_t buffersize
)
194 if (buffersize
< PROC_PIDPATHINFO_SIZE
) {
198 if (buffersize
> PROC_PIDPATHINFO_MAXSIZE
) {
203 retval
= __proc_info(2, pid
, PROC_PIDPATHINFO
, (uint64_t)0, buffer
, buffersize
);
205 len
= strlen(buffer
);
213 proc_libversion(int *major
, int * minor
)
224 proc_setpcontrol(const int control
)
228 if (control
< PROC_SETPC_NONE
|| control
> PROC_SETPC_TERMINATE
)
231 if ((retval
= __proc_info(5, getpid(), PROC_SELFSET_PCONTROL
, (uint64_t)control
, NULL
, 0)) == -1)
238 __private_extern__
int
239 proc_setthreadname(void * buffer
, int buffersize
)
243 retval
= __proc_info(5, getpid(), PROC_SELFSET_THREADNAME
, (uint64_t)0, buffer
, buffersize
);
252 proc_track_dirty(pid_t pid
, uint32_t flags
)
254 if (__proc_info(8, pid
, PROC_DIRTYCONTROL_TRACK
, flags
, NULL
, 0) == -1) {
262 proc_set_dirty(pid_t pid
, bool dirty
)
264 if (__proc_info(8, pid
, PROC_DIRTYCONTROL_SET
, dirty
, NULL
, 0) == -1) {
272 proc_get_dirty(pid_t pid
, uint32_t *flags
)
280 retval
= __proc_info(8, pid
, PROC_DIRTYCONTROL_GET
, 0, NULL
, 0);
291 proc_terminate(pid_t pid
, int *sig
)
299 retval
= __proc_info(7, pid
, 0, 0, NULL
, 0);
309 #if TARGET_OS_EMBEDDED
312 proc_setcpu_percentage(pid_t pid
, int action
, int percentage
)
314 proc_policy_cpuusage_attr_t attr
;
316 bzero(&attr
, sizeof(proc_policy_cpuusage_attr_t
));
317 attr
.ppattr_cpu_attr
= action
;
318 attr
.ppattr_cpu_percentage
= percentage
;
319 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_RESOURCE_USAGE
, PROC_POLICY_RUSAGE_CPU
, &attr
, pid
, (uint64_t)0) != -1)
326 proc_setcpu_deadline(pid_t pid
, int action
, uint64_t deadline
)
328 proc_policy_cpuusage_attr_t attr
;
330 bzero(&attr
, sizeof(proc_policy_cpuusage_attr_t
));
331 attr
.ppattr_cpu_attr
= action
;
332 attr
.ppattr_cpu_attr_deadline
= deadline
;
333 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_RESOURCE_USAGE
, PROC_POLICY_RUSAGE_CPU
, &attr
, pid
, (uint64_t)0) != -1)
342 proc_setcpu_percentage_withdeadline(pid_t pid
, int action
, int percentage
, uint64_t deadline
)
344 proc_policy_cpuusage_attr_t attr
;
346 bzero(&attr
, sizeof(proc_policy_cpuusage_attr_t
));
347 attr
.ppattr_cpu_attr
= action
;
348 attr
.ppattr_cpu_percentage
= percentage
;
349 attr
.ppattr_cpu_attr_deadline
= deadline
;
350 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_RESOURCE_USAGE
, PROC_POLICY_RUSAGE_CPU
, &attr
, pid
, (uint64_t)0) != -1)
357 proc_clear_cpulimits(pid_t pid
)
359 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_RESTORE
, PROC_POLICY_RESOURCE_USAGE
, PROC_POLICY_RUSAGE_CPU
, NULL
, pid
, (uint64_t)0) != -1)
368 proc_appstate(int pid
, int * appstatep
)
372 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_GET
, PROC_POLICY_APP_LIFECYCLE
, PROC_POLICY_APPLIFE_STATE
, (int *)&state
, pid
, (uint64_t)0) != -1) {
373 if (appstatep
!= NULL
)
383 proc_setappstate(int pid
, int appstate
)
385 int state
= appstate
;
388 case PROC_APPSTATE_NONE
:
389 case PROC_APPSTATE_ACTIVE
:
390 case PROC_APPSTATE_INACTIVE
:
391 case PROC_APPSTATE_BACKGROUND
:
392 case PROC_APPSTATE_NONUI
:
397 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_APP_LIFECYCLE
, PROC_POLICY_APPLIFE_STATE
, (int *)&state
, pid
, (uint64_t)0) != -1)
404 proc_devstatusnotify(int devicestatus
)
406 int state
= devicestatus
;
408 switch (devicestatus
) {
409 case PROC_DEVSTATUS_SHORTTERM
:
410 case PROC_DEVSTATUS_LONGTERM
:
416 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_APP_LIFECYCLE
, PROC_POLICY_APPLIFE_DEVSTATUS
, (int *)&state
, getpid(), (uint64_t)0) != -1) {
424 proc_pidbind(int pid
, uint64_t threadid
, int bind
)
430 case PROC_PIDBIND_CLEAR
:
431 passpid
= getpid(); /* ignore pid on clear */
433 case PROC_PIDBIND_SET
:
438 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_APPLY
, PROC_POLICY_APP_LIFECYCLE
, PROC_POLICY_APPLIFE_PIDBIND
, (int *)&state
, passpid
, threadid
) != -1)
444 #else /* TARGET_OS_EMBEDDED */
447 proc_clear_vmpressure(pid_t pid
)
449 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_RESTORE
, PROC_POLICY_RESOURCE_STARVATION
, PROC_POLICY_RS_VIRTUALMEM
, NULL
, pid
, (uint64_t)0) != -1)
455 /* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */
457 proc_set_owner_vmpressure(void)
461 if ((retval
= __proc_info(5, getpid(), PROC_SELFSET_VMRSRCOWNER
, (uint64_t)0, NULL
, 0)) == -1)
467 /* mark yourself to delay idle sleep on disk IO */
469 proc_set_delayidlesleep(void)
473 if ((retval
= __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP
, (uint64_t)1, NULL
, 0)) == -1)
479 /* Reset yourself to delay idle sleep on disk IO, if already set */
481 proc_clear_delayidlesleep(void)
485 if ((retval
= __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP
, (uint64_t)0, NULL
, 0)) == -1)
491 /* disable the launch time backgroudn policy and restore the process to default group */
493 proc_disable_apptype(pid_t pid
, int apptype
)
496 case PROC_POLICY_OSX_APPTYPE_TAL
:
497 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT
:
504 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_DISABLE
, PROC_POLICY_APPTYPE
, apptype
, NULL
, pid
, (uint64_t)0) != -1)
511 /* re-enable the launch time background policy if it had been disabled. */
513 proc_enable_apptype(pid_t pid
, int apptype
)
516 case PROC_POLICY_OSX_APPTYPE_TAL
:
517 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT
:
524 if (__process_policy(PROC_POLICY_SCOPE_PROCESS
, PROC_POLICY_ACTION_ENABLE
, PROC_POLICY_APPTYPE
, apptype
, NULL
, pid
, (uint64_t)0) != -1)
531 #endif /* TARGET_OS_EMBEDDED */