]> git.saurik.com Git - apple/libc.git/blame - darwin/libproc.c
Libc-825.24.tar.gz
[apple/libc.git] / darwin / libproc.c
CommitLineData
224c7076 1/*
1f2f436a 2 * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
224c7076
A
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>
1f2f436a
A
31#define CONFIG_EMBEDDED 1
32#include <sys/process_policy.h>
224c7076 33
1f2f436a 34#include "libproc_internal.h"
224c7076
A
35
36int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize);
1f2f436a
A
37__private_extern__ int proc_setthreadname(void * buffer, int buffersize);
38int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid);
224c7076
A
39
40
41
42int
43proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize)
44{
45 int retval;
46
1f2f436a 47 if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) {
224c7076
A
48 if ((retval = __proc_info(1, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1)
49 return(0);
50 } else {
51 errno = EINVAL;
52 retval = 0;
53 }
54 return(retval);
55}
56
57
1f2f436a
A
58int
59proc_listallpids(void * buffer, int buffersize)
60{
61 int numpids;
62 numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize);
63
64 if (numpids == -1)
65 return(-1);
66 else
67 return(numpids/sizeof(int));
68}
69
70int
71proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize)
72{
73 int numpids;
74 numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize);
75 if (numpids == -1)
76 return(-1);
77 else
78 return(numpids/sizeof(int));
79}
80
81int
82proc_listchildpids(pid_t ppid, void * buffer, int buffersize)
83{
84 int numpids;
85 numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize);
86 if (numpids == -1)
87 return(-1);
88 else
89 return(numpids/sizeof(int));
90}
91
92
224c7076
A
93int
94proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize)
95{
96 int retval;
97
98 if ((retval = __proc_info(2, pid, flavor, arg, buffer, buffersize)) == -1)
99 return(0);
100
101 return(retval);
102}
103
104
105int
106proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize)
107{
108 int retval;
109
110 if ((retval = __proc_info(3, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1)
111 return(0);
112
113 return (retval);
114}
115
116
1f2f436a
A
117int
118proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize)
119{
120 int retval;
121
122 if ((retval = __proc_info(6, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1)
123 return (0);
124 return (retval);
125}
126
224c7076
A
127
128int
129proc_name(int pid, void * buffer, uint32_t buffersize)
130{
131 int retval = 0, len;
132 struct proc_bsdinfo pbsd;
133
134
34e8f829 135 if (buffersize < sizeof(pbsd.pbi_name)) {
224c7076
A
136 errno = ENOMEM;
137 return(0);
138 }
139
140 retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo));
34e8f829
A
141 if (retval != 0) {
142 if (pbsd.pbi_name[0]) {
143 bcopy(&pbsd.pbi_name, buffer, sizeof(pbsd.pbi_name));
144 } else {
145 bcopy(&pbsd.pbi_comm, buffer, sizeof(pbsd.pbi_comm));
146 }
147 len = strlen(buffer);
224c7076
A
148 return(len);
149 }
150 return(0);
151}
152
153int
154proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize)
155{
156 int retval = 0, len;
157 struct proc_regionwithpathinfo reginfo;
158
159 if (buffersize < MAXPATHLEN) {
160 errno = ENOMEM;
161 return(0);
162 }
163
164 retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, &reginfo, sizeof(struct proc_regionwithpathinfo));
165 if (retval != -1) {
166 len = strlen(&reginfo.prp_vip.vip_path[0]);
167 if (len != 0) {
168 if (len > MAXPATHLEN)
169 len = MAXPATHLEN;
170 bcopy(&reginfo.prp_vip.vip_path[0], buffer, len);
171 return(len);
172 }
173 return(0);
174 }
175 return(0);
176
177}
178
179int
180proc_kmsgbuf(void * buffer, uint32_t buffersize)
181{
182 int retval;
183
184 if ((retval = __proc_info(4, 0, 0, (uint64_t)0, buffer, buffersize)) == -1)
185 return(0);
186 return (retval);
187}
188
189int
190proc_pidpath(int pid, void * buffer, uint32_t buffersize)
191{
192 int retval, len;
193
194 if (buffersize < PROC_PIDPATHINFO_SIZE) {
195 errno = ENOMEM;
196 return(0);
197 }
198 if (buffersize > PROC_PIDPATHINFO_MAXSIZE) {
199 errno = EOVERFLOW;
200 return(0);
201 }
202
203 retval = __proc_info(2, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize);
204 if (retval != -1) {
205 len = strlen(buffer);
206 return(len);
207 }
208 return (0);
209}
210
211
34e8f829
A
212int
213proc_libversion(int *major, int * minor)
224c7076
A
214{
215
216 if (major != NULL)
217 *major = 1;
218 if (minor != NULL)
219 *minor = 1;
220 return(0);
221}
222
34e8f829
A
223int
224proc_setpcontrol(const int control)
225{
226 int retval ;
227
228 if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE)
229 return(EINVAL);
230
1f2f436a 231 if ((retval = __proc_info(5, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1)
34e8f829
A
232 return(errno);
233
234 return(0);
235}
236
237
1f2f436a
A
238__private_extern__ int
239proc_setthreadname(void * buffer, int buffersize)
240{
241 int retval;
242
243 retval = __proc_info(5, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize);
244
245 if (retval == -1)
246 return(errno);
247 else
248 return(0);
249}
250
ad3c9f2a
A
251int
252proc_track_dirty(pid_t pid, uint32_t flags)
253{
254 if (__proc_info(8, pid, PROC_DIRTYCONTROL_TRACK, flags, NULL, 0) == -1) {
255 return errno;
256 }
257
258 return 0;
259}
260
261int
262proc_set_dirty(pid_t pid, bool dirty)
263{
264 if (__proc_info(8, pid, PROC_DIRTYCONTROL_SET, dirty, NULL, 0) == -1) {
265 return errno;
266 }
267
268 return 0;
269}
270
271int
272proc_get_dirty(pid_t pid, uint32_t *flags)
273{
274 int retval;
275
276 if (!flags) {
277 return EINVAL;
278 }
279
280 retval = __proc_info(8, pid, PROC_DIRTYCONTROL_GET, 0, NULL, 0);
281 if (retval == -1) {
282 return errno;
283 }
284
285 *flags = retval;
286
287 return 0;
288}
289
290int
291proc_terminate(pid_t pid, int *sig)
292{
293 int retval;
294
295 if (!sig) {
296 return EINVAL;
297 }
298
299 retval = __proc_info(7, pid, 0, 0, NULL, 0);
300 if (retval == -1) {
301 return errno;
302 }
303
304 *sig = retval;
305
306 return 0;
307}
308
1f2f436a
A
309#if TARGET_OS_EMBEDDED
310
311int
312proc_setcpu_percentage(pid_t pid, int action, int percentage)
313{
314 proc_policy_cpuusage_attr_t attr;
315
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)
320 return(0);
321 else
322 return(errno);
323}
324
325int
326proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline)
327{
328 proc_policy_cpuusage_attr_t attr;
329
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)
334 return(0);
335 else
336 return(errno);
337
338}
339
340
341int
342proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline)
343{
344 proc_policy_cpuusage_attr_t attr;
345
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)
351 return(0);
352 else
353 return(errno);
354}
355
356int
357proc_clear_cpulimits(pid_t pid)
358{
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)
360 return(0);
361 else
362 return(errno);
363
364
365}
366
367int
368proc_appstate(int pid, int * appstatep)
369{
370 int state;
371
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)
374 *appstatep = state;
375 return(0);
376 } else
377 return(errno);
378
379}
380
381
382int
383proc_setappstate(int pid, int appstate)
384{
385 int state = appstate;
386
387 switch (state) {
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:
393 break;
394 default:
395 return(EINVAL);
396 }
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)
398 return(0);
399 else
400 return(errno);
401}
402
403int
404proc_devstatusnotify(int devicestatus)
405{
406 int state = devicestatus;
407
408 switch (devicestatus) {
409 case PROC_DEVSTATUS_SHORTTERM:
410 case PROC_DEVSTATUS_LONGTERM:
411 break;
412 default:
413 return(EINVAL);
414 }
415
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) {
417 return(0);
418 } else
419 return(errno);
420
421}
422
423int
424proc_pidbind(int pid, uint64_t threadid, int bind)
425{
426 int state = bind;
427 pid_t passpid = pid;
428
429 switch (bind) {
430 case PROC_PIDBIND_CLEAR:
431 passpid = getpid(); /* ignore pid on clear */
432 break;
433 case PROC_PIDBIND_SET:
434 break;
435 default:
436 return(EINVAL);
437 }
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)
439 return(0);
440 else
441 return(errno);
442}
443
444#else /* TARGET_OS_EMBEDDED */
445
446int
447proc_clear_vmpressure(pid_t pid)
448{
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)
450 return(0);
451 else
452 return(errno);
453}
454
455/* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */
456int
457proc_set_owner_vmpressure(void)
458{
459 int retval;
460
461 if ((retval = __proc_info(5, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1)
462 return(errno);
463
464 return(0);
465}
466
ad3c9f2a
A
467/* mark yourself to delay idle sleep on disk IO */
468int
469proc_set_delayidlesleep(void)
470{
471 int retval;
472
473 if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)1, NULL, 0)) == -1)
474 return(errno);
475
476 return(0);
477}
478
479/* Reset yourself to delay idle sleep on disk IO, if already set */
480int
481proc_clear_delayidlesleep(void)
482{
483 int retval;
484
485 if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)0, NULL, 0)) == -1)
486 return(errno);
487
488 return(0);
489}
490
1f2f436a
A
491/* disable the launch time backgroudn policy and restore the process to default group */
492int
493proc_disable_apptype(pid_t pid, int apptype)
494{
495 switch (apptype) {
496 case PROC_POLICY_OSX_APPTYPE_TAL:
497 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
498 break;
499 default:
500 return(EINVAL);
501
502 }
503
504 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
505 return(0);
506 else
507 return(errno);
508
509}
510
511/* re-enable the launch time background policy if it had been disabled. */
512int
513proc_enable_apptype(pid_t pid, int apptype)
514{
515 switch (apptype) {
516 case PROC_POLICY_OSX_APPTYPE_TAL:
517 case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
518 break;
519 default:
520 return(EINVAL);
521
522 }
523
524 if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
525 return(0);
526 else
527 return(errno);
528
529}
530
531#endif /* TARGET_OS_EMBEDDED */
532