]> git.saurik.com Git - apple/xnu.git/blob - libsyscall/wrappers/libproc/libproc.c
xnu-2422.1.72.tar.gz
[apple/xnu.git] / libsyscall / wrappers / libproc / libproc.c
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
38 int __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);
40 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);
41 int proc_rlimit_control(pid_t pid, int flavor, void *arg);
42
43 int
44 proc_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
59 int
60 proc_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
71 int
72 proc_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
82 int
83 proc_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
94 int
95 proc_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
105 int
106 proc_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
111 int
112 proc_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
123 int
124 proc_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
134 int
135 proc_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
159 int
160 proc_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
185 int
186 proc_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
195 int
196 proc_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
218 int
219 proc_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
229 int
230 proc_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
245 proc_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
257 int
258 proc_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
267 int
268 proc_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
277 int
278 proc_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
296 int
297 proc_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
315 int
316 proc_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
329 int
330 proc_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
349 int
350 proc_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
363 int
364 proc_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
377 int
378 proc_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
393 int
394 proc_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
411 int
412 proc_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
422 int
423 proc_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
436 int
437 proc_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
450 int
451 proc_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
466 int
467 proc_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
481 int
482 proc_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
492 int
493 proc_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
507 int
508 proc_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
528 int
529 proc_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
548 int
549 proc_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 */
572 int
573 proc_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
597 static __attribute__((noinline)) void
598 proc_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 */
606 uint64_t important_boost_assertion_token = 0xfafafafafafafafa;
607 uint64_t normal_boost_assertion_token = 0xfbfbfbfbfbfbfbfb;
608 uint64_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 */
619 int
620 proc_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 */
677 int
678 proc_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
717 int
718 proc_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 */
727 int
728 proc_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 */
739 int
740 proc_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 */
751 int
752 proc_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 */
763 int
764 proc_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. */
782 int
783 proc_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
803 int
804 proc_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