]> git.saurik.com Git - apple/xnu.git/blame - libsyscall/wrappers/libproc/libproc.c
xnu-2422.1.72.tar.gz
[apple/xnu.git] / libsyscall / wrappers / libproc / libproc.c
CommitLineData
39236c6e
A
1/*
2 * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#include <sys/cdefs.h>
25#include <unistd.h>
26#include <errno.h>
27#include <string.h>
28#include <strings.h>
29#include <sys/errno.h>
30#include <sys/msgbuf.h>
31#include <sys/resource.h>
32#define BUILD_LIBSYSCALL 1
33#include <sys/process_policy.h>
34#include <mach/message.h>
35
36#include "libproc_internal.h"
37
38int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize);
39__private_extern__ int proc_setthreadname(void * buffer, int buffersize);
40int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid);
41int proc_rlimit_control(pid_t pid, int flavor, void *arg);
42
43int
44proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize)
45{
46 int retval;
47
48 if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) {
49 if ((retval = __proc_info(PROC_INFO_CALL_LISTPIDS, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1)
50 return(0);
51 } else {
52 errno = EINVAL;
53 retval = 0;
54 }
55 return(retval);
56}
57
58
59int
60proc_listallpids(void * buffer, int buffersize)
61{
62 int numpids;
63 numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize);
64
65 if (numpids == -1)
66 return(-1);
67 else
68 return(numpids/sizeof(int));
69}
70
71int
72proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize)
73{
74 int numpids;
75 numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize);
76 if (numpids == -1)
77 return(-1);
78 else
79 return(numpids/sizeof(int));
80}
81
82int
83proc_listchildpids(pid_t ppid, void * buffer, int buffersize)
84{
85 int numpids;
86 numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize);
87 if (numpids == -1)
88 return(-1);
89 else
90 return(numpids/sizeof(int));
91}
92
93
94int
95proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize)
96{
97 int retval;
98
99 if ((retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, flavor, arg, buffer, buffersize)) == -1)
100 return(0);
101
102 return(retval);
103}
104
105int
106proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer)
107{
108 return (__proc_info(PROC_INFO_CALL_PIDRUSAGE, pid, flavor, 0, buffer, 0));
109}
110
111int
112proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize)
113{
114 int retval;
115
116 if ((retval = __proc_info(PROC_INFO_CALL_PIDFDINFO, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1)
117 return(0);
118
119 return (retval);
120}
121
122
123int
124proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize)
125{
126 int retval;
127
128 if ((retval = __proc_info(PROC_INFO_CALL_PIDFILEPORTINFO, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1)
129 return (0);
130 return (retval);
131}
132
133
134int
135proc_name(int pid, void * buffer, uint32_t buffersize)
136{
137 int retval = 0, len;
138 struct proc_bsdinfo pbsd;
139
140
141 if (buffersize < sizeof(pbsd.pbi_name)) {
142 errno = ENOMEM;
143 return(0);
144 }
145
146 retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo));
147 if (retval != 0) {
148 if (pbsd.pbi_name[0]) {
149 bcopy(&pbsd.pbi_name, buffer, sizeof(pbsd.pbi_name));
150 } else {
151 bcopy(&pbsd.pbi_comm, buffer, sizeof(pbsd.pbi_comm));
152 }
153 len = strlen(buffer);
154 return(len);
155 }
156 return(0);
157}
158
159int
160proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize)
161{
162 int retval = 0, len;
163 struct proc_regionwithpathinfo reginfo;
164
165 if (buffersize < MAXPATHLEN) {
166 errno = ENOMEM;
167 return(0);
168 }
169
170 retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, &reginfo, sizeof(struct proc_regionwithpathinfo));
171 if (retval != -1) {
172 len = strlen(&reginfo.prp_vip.vip_path[0]);
173 if (len != 0) {
174 if (len > MAXPATHLEN)
175 len = MAXPATHLEN;
176 bcopy(&reginfo.prp_vip.vip_path[0], buffer, len);
177 return(len);
178 }
179 return(0);
180 }
181 return(0);
182
183}
184
185int
186proc_kmsgbuf(void * buffer, uint32_t buffersize)
187{
188 int retval;
189
190 if ((retval = __proc_info(PROC_INFO_CALL_KERNMSGBUF, 0, 0, (uint64_t)0, buffer, buffersize)) == -1)
191 return(0);
192 return (retval);
193}
194
195int
196proc_pidpath(int pid, void * buffer, uint32_t buffersize)
197{
198 int retval, len;
199
200 if (buffersize < PROC_PIDPATHINFO_SIZE) {
201 errno = ENOMEM;
202 return(0);
203 }
204 if (buffersize > PROC_PIDPATHINFO_MAXSIZE) {
205 errno = EOVERFLOW;
206 return(0);
207 }
208
209 retval = __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize);
210 if (retval != -1) {
211 len = strlen(buffer);
212 return(len);
213 }
214 return (0);
215}
216
217
218int
219proc_libversion(int *major, int * minor)
220{
221
222 if (major != NULL)
223 *major = 1;
224 if (minor != NULL)
225 *minor = 1;
226 return(0);
227}
228
229int
230proc_setpcontrol(const int control)
231{
232 int retval ;
233
234 if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE)
235 return(EINVAL);
236
237 if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1)
238 return(errno);
239
240 return(0);
241}
242
243
244__private_extern__ int
245proc_setthreadname(void * buffer, int buffersize)
246{
247 int retval;
248
249 retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize);
250
251 if (retval == -1)
252 return(errno);
253 else
254 return(0);
255}
256
257int
258proc_track_dirty(pid_t pid, uint32_t flags)
259{
260 if (__proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_TRACK, flags, NULL, 0) == -1) {
261 return errno;
262 }
263
264 return 0;
265}
266
267int
268proc_set_dirty(pid_t pid, bool dirty)
269{
270 if (__proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_SET, dirty, NULL, 0) == -1) {
271 return errno;
272 }
273
274 return 0;
275}
276
277int
278proc_get_dirty(pid_t pid, uint32_t *flags)
279{
280 int retval;
281
282 if (!flags) {
283 return EINVAL;
284 }
285
286 retval = __proc_info(PROC_INFO_CALL_DIRTYCONTROL, pid, PROC_DIRTYCONTROL_GET, 0, NULL, 0);
287 if (retval == -1) {
288 return errno;
289 }
290
291 *flags = retval;
292
293 return 0;
294}
295
296int
297proc_terminate(pid_t pid, int *sig)
298{
299 int retval;
300
301 if (!sig) {
302 return EINVAL;
303 }
304
305 retval = __proc_info(PROC_INFO_CALL_TERMINATE, pid, 0, 0, NULL, 0);
306 if (retval == -1) {
307 return errno;
308 }
309
310 *sig = retval;
311
312 return 0;
313}
314
315int
316proc_set_cpumon_params(pid_t pid, int percentage, int interval)
317{
318 proc_policy_cpuusage_attr_t attr;
319
320 attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
321 attr.ppattr_cpu_percentage = percentage;
322 attr.ppattr_cpu_attr_interval = (uint64_t)interval;
323 attr.ppattr_cpu_attr_deadline = 0;
324
325 return(__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
326 PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0));
327}
328
329int
330proc_get_cpumon_params(pid_t pid, int *percentage, int *interval)
331{
332 proc_policy_cpuusage_attr_t attr;
333 int ret;
334
335 ret = __process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_RESOURCE_USAGE,
336 PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0);
337
338 if ((ret == 0) && (attr.ppattr_cpu_attr == PROC_POLICY_RSRCACT_NOTIFY_EXC)) {
339 *percentage = attr.ppattr_cpu_percentage;
340 *interval = attr.ppattr_cpu_attr_interval;
341 } else {
342 *percentage = 0;
343 *interval = 0;
344 }
345
346 return (ret);
347}
348
349int
350proc_set_cpumon_defaults(pid_t pid)
351{
352 proc_policy_cpuusage_attr_t attr;
353
354 attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
355 attr.ppattr_cpu_percentage = PROC_POLICY_CPUMON_DEFAULTS;
356 attr.ppattr_cpu_attr_interval = 0;
357 attr.ppattr_cpu_attr_deadline = 0;
358
359 return(__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
360 PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0));
361}
362
363int
364proc_disable_cpumon(pid_t pid)
365{
366 proc_policy_cpuusage_attr_t attr;
367
368 attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
369 attr.ppattr_cpu_percentage = PROC_POLICY_CPUMON_DISABLE;
370 attr.ppattr_cpu_attr_interval = 0;
371 attr.ppattr_cpu_attr_deadline = 0;
372
373 return(__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_SET, PROC_POLICY_RESOURCE_USAGE,
374 PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0));
375}
376
377int
378proc_set_wakemon_params(pid_t pid, int rate_hz, int flags __unused)
379{
380 struct proc_rlimit_control_wakeupmon params;
381
382 params.wm_flags = WAKEMON_ENABLE;
383 params.wm_rate = rate_hz;
384
385 return (proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, &params));
386}
387
388#ifndef WAKEMON_GET_PARAMS
389#define WAKEMON_GET_PARAMS 0x4
390#define WAKEMON_SET_DEFAULTS 0x8
391#endif
392
393int
394proc_get_wakemon_params(pid_t pid, int *rate_hz, int *flags)
395{
396 struct proc_rlimit_control_wakeupmon params;
397 int error;
398
399 params.wm_flags = WAKEMON_GET_PARAMS;
400
401 if ((error = proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, &params)) != 0) {
402 return (error);
403 }
404
405 *rate_hz = params.wm_rate;
406 *flags = params.wm_flags;
407
408 return (0);
409}
410
411int
412proc_set_wakemon_defaults(pid_t pid)
413{
414 struct proc_rlimit_control_wakeupmon params;
415
416 params.wm_flags = WAKEMON_ENABLE | WAKEMON_SET_DEFAULTS;
417 params.wm_rate = -1;
418
419 return (proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, &params));
420}
421
422int
423proc_disable_wakemon(pid_t pid)
424{
425 struct proc_rlimit_control_wakeupmon params;
426
427 params.wm_flags = WAKEMON_DISABLE;
428 params.wm_rate = -1;
429
430 return (proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, &params));
431}
432
433
434#if TARGET_OS_EMBEDDED
435
436int
437proc_setcpu_percentage(pid_t pid, int action, int percentage)
438{
439 proc_policy_cpuusage_attr_t attr;
440
441 bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
442 attr.ppattr_cpu_attr = action;
443 attr.ppattr_cpu_percentage = percentage;
444 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1)
445 return(0);
446 else
447 return(errno);
448}
449
450int
451proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline)
452{
453 proc_policy_cpuusage_attr_t attr;
454
455 bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
456 attr.ppattr_cpu_attr = action;
457 attr.ppattr_cpu_attr_deadline = deadline;
458 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1)
459 return(0);
460 else
461 return(errno);
462
463}
464
465
466int
467proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline)
468{
469 proc_policy_cpuusage_attr_t attr;
470
471 bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
472 attr.ppattr_cpu_attr = action;
473 attr.ppattr_cpu_percentage = percentage;
474 attr.ppattr_cpu_attr_deadline = deadline;
475 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, (uint64_t)0) != -1)
476 return(0);
477 else
478 return(errno);
479}
480
481int
482proc_clear_cpulimits(pid_t pid)
483{
484 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)
485 return(0);
486 else
487 return(errno);
488
489
490}
491
492int
493proc_appstate(int pid, int * appstatep)
494{
495 int state;
496
497 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (proc_policy_attribute_t*)&state, pid, (uint64_t)0) != -1) {
498 if (appstatep != NULL)
499 *appstatep = state;
500 return(0);
501 } else
502 return(errno);
503
504}
505
506
507int
508proc_setappstate(int pid, int appstate)
509{
510 int state = appstate;
511
512 switch (state) {
513 case PROC_APPSTATE_NONE:
514 case PROC_APPSTATE_ACTIVE:
515 case PROC_APPSTATE_INACTIVE:
516 case PROC_APPSTATE_BACKGROUND:
517 case PROC_APPSTATE_NONUI:
518 break;
519 default:
520 return(EINVAL);
521 }
522 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (proc_policy_attribute_t*)&state, pid, (uint64_t)0) != -1)
523 return(0);
524 else
525 return(errno);
526}
527
528int
529proc_devstatusnotify(int devicestatus)
530{
531 int state = devicestatus;
532
533 switch (devicestatus) {
534 case PROC_DEVSTATUS_SHORTTERM:
535 case PROC_DEVSTATUS_LONGTERM:
536 break;
537 default:
538 return(EINVAL);
539 }
540
541 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_DEVSTATUS, (proc_policy_attribute_t*)&state, getpid(), (uint64_t)0) != -1) {
542 return(0);
543 } else
544 return(errno);
545
546}
547
548int
549proc_pidbind(int pid, uint64_t threadid, int bind)
550{
551 int state = bind;
552 pid_t passpid = pid;
553
554 switch (bind) {
555 case PROC_PIDBIND_CLEAR:
556 passpid = getpid(); /* ignore pid on clear */
557 break;
558 case PROC_PIDBIND_SET:
559 break;
560 default:
561 return(EINVAL);
562 }
563 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_PIDBIND, (proc_policy_attribute_t*)&state, passpid, threadid) != -1)
564 return(0);
565 else
566 return(errno);
567}
568#endif /* TARGET_OS_EMBEDDED */
569
570
571/* Donate importance to adaptive processes from this process */
572int
573proc_donate_importance_boost()
574{
575 int rval;
576
577#if TARGET_OS_EMBEDDED
578 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
579 PROC_POLICY_ACTION_ENABLE,
580 PROC_POLICY_APPTYPE,
581 PROC_POLICY_IOS_DONATEIMP,
582 NULL, getpid(), (uint64_t)0);
583#else /* TARGET_OS_EMBEDDED */
584 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
585 PROC_POLICY_ACTION_SET,
586 PROC_POLICY_BOOST,
587 PROC_POLICY_IMP_DONATION,
588 NULL, getpid(), 0);
589#endif /* TARGET_OS_EMBEDDED */
590
591 if (rval == 0)
592 return (0);
593 else
594 return (errno);
595}
596
597static __attribute__((noinline)) void
598proc_importance_bad_assertion(char *reason) {
599 (void)reason;
600}
601
602/*
603 * Use the address of these variables as the token. This way, they can be
604 * printed in the debugger as useful names.
605 */
606uint64_t important_boost_assertion_token = 0xfafafafafafafafa;
607uint64_t normal_boost_assertion_token = 0xfbfbfbfbfbfbfbfb;
608uint64_t non_boost_assertion_token = 0xfcfcfcfcfcfcfcfc;
609
610/*
611 * Accept the boost on a message, or request another boost assertion
612 * if we have already accepted the implicit boost for this message.
613 *
614 * Returns EOVERFLOW if an attempt is made to take an extra assertion when not boosted.
615 *
616 * Returns EIO if the message was not a boosting message.
617 * TODO: Return a 'non-boost' token instead.
618 */
619int
620proc_importance_assertion_begin_with_msg(mach_msg_header_t *msg,
621 __unused mach_msg_trailer_t *trailer,
622 uint64_t *assertion_token)
623{
624 int rval = 0;
625
626 if (assertion_token == NULL)
627 return (EINVAL);
628
629 /* Is this a boosting message? */
630 if ((msg->msgh_bits & MACH_MSGH_BITS_RAISEIMP) != 0) {
631
632 /*
633 * Have we accepted the implicit boost for this message yet?
634 * If we haven't accepted it yet, no need to call into kernel.
635 */
636 if ((msg->msgh_bits & MACH_MSGH_BITS_IMPHOLDASRT) == 0) {
637 msg->msgh_bits |= MACH_MSGH_BITS_IMPHOLDASRT;
638 *assertion_token = (uint64_t) &important_boost_assertion_token;
639 return (0);
640 }
641
642 /* Request an additional boost count */
643
644#if TARGET_OS_EMBEDDED
645 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
646 PROC_POLICY_ACTION_ENABLE,
647 PROC_POLICY_APPTYPE,
648 PROC_POLICY_IOS_HOLDIMP,
649 NULL, getpid(), 0);
650#else /* TARGET_OS_EMBEDDED */
651 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
652 PROC_POLICY_ACTION_HOLD,
653 PROC_POLICY_BOOST,
654 PROC_POLICY_IMP_IMPORTANT,
655 NULL, getpid(), 0);
656#endif /* TARGET_OS_EMBEDDED */
657
658 if (rval == 0) {
659 *assertion_token = (uint64_t) &important_boost_assertion_token;
660 return (0);
661 } else if (errno == EOVERFLOW) {
662 proc_importance_bad_assertion("Attempted to take assertion while not boosted");
663 return (errno);
664 } else {
665 return (errno);
666 }
667 }
668
669 return (EIO);
670}
671
672
673/*
674 * Drop a boost assertion.
675 * Returns EOVERFLOW on boost assertion underflow.
676 */
677int
678proc_importance_assertion_complete(uint64_t assertion_token)
679{
680 int rval = 0;
681
682 if (assertion_token == 0)
683 return (0);
684
685 if (assertion_token == (uint64_t) &important_boost_assertion_token) {
686
687#if TARGET_OS_EMBEDDED
688 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
689 PROC_POLICY_ACTION_ENABLE,
690 PROC_POLICY_APPTYPE,
691 PROC_POLICY_IOS_DROPIMP,
692 NULL, getpid(), 0);
693#else /* TARGET_OS_EMBEDDED */
694 rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
695 PROC_POLICY_ACTION_DROP,
696 PROC_POLICY_BOOST,
697 PROC_POLICY_IMP_IMPORTANT,
698 NULL, getpid(), 0);
699#endif /* TARGET_OS_EMBEDDED */
700
701 if (rval == 0) {
702 return (0);
703 } else if (errno == EOVERFLOW) {
704 proc_importance_bad_assertion("Attempted to drop too many assertions");
705 return (errno);
706 } else {
707 return (errno);
708 }
709 } else {
710 proc_importance_bad_assertion("Attempted to drop assertion with invalid token");
711 return (EIO);
712 }
713}
714
715#if !TARGET_OS_EMBEDDED
716
717int
718proc_clear_vmpressure(pid_t pid)
719{
720 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)
721 return(0);
722 else
723 return(errno);
724}
725
726/* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */
727int
728proc_set_owner_vmpressure(void)
729{
730 int retval;
731
732 if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1)
733 return(errno);
734
735 return(0);
736}
737
738/* mark yourself to delay idle sleep on disk IO */
739int
740proc_set_delayidlesleep(void)
741{
742 int retval;
743
744 if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)1, NULL, 0)) == -1)
745 return(errno);
746
747 return(0);
748}
749
750/* Reset yourself to delay idle sleep on disk IO, if already set */
751int
752proc_clear_delayidlesleep(void)
753{
754 int retval;
755
756 if ((retval = __proc_info(PROC_INFO_CALL_SETCONTROL, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)0, NULL, 0)) == -1)
757 return(errno);
758
759 return(0);
760}
761
762/* disable the launch time backgroudn policy and restore the process to default group */
763int
764proc_disable_apptype(pid_t pid, int apptype)
765{
766 switch (apptype) {
767 case PROC_POLICY_OSX_APPTYPE_TAL:
768 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
769 break;
770 default:
771 return(EINVAL);
772 }
773
774 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
775 return(0);
776 else
777 return(errno);
778
779}
780
781/* re-enable the launch time background policy if it had been disabled. */
782int
783proc_enable_apptype(pid_t pid, int apptype)
784{
785 switch (apptype) {
786 case PROC_POLICY_OSX_APPTYPE_TAL:
787 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
788 break;
789 default:
790 return(EINVAL);
791
792 }
793
794 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
795 return(0);
796 else
797 return(errno);
798
799}
800
801#if !TARGET_IPHONE_SIMULATOR
802
803int
804proc_suppress(__unused pid_t pid, __unused uint64_t *generation)
805{
806 return 0;
807}
808
809#endif /* !TARGET_IPHONE_SIMULATOR */
810
811#endif /* !TARGET_OS_EMBEDDED */
812
813
814