#include <errno.h>
#include <string.h>
#include <strings.h>
+#include <stdlib.h>
#include <sys/errno.h>
#include <sys/msgbuf.h>
#include <sys/resource.h>
#include <sys/process_policy.h>
+#include <sys/event.h>
#include <mach/message.h>
#include "libproc_internal.h"
return(retval);
}
+int
+proc_listcoalitions(int flavor, int coaltype, void *buffer, int buffersize)
+{
+ int retval;
+
+ if ((retval = __proc_info(PROC_INFO_CALL_LISTCOALITIONS, flavor, coaltype, 0, buffer, buffersize)) == -1)
+ return 0;
+
+ return retval;
+}
+
int
proc_pid_rusage(int pid, int flavor, rusage_info_t *buffer)
{
return (retval);
}
+int
+proc_piddynkqueueinfo(int pid, int flavor, kqueue_id_t kq_id, void *buffer, int buffersize)
+{
+ int ret;
+
+ if ((ret = __proc_info(PROC_INFO_CALL_PIDDYNKQUEUEINFO, pid, flavor, (uint64_t)kq_id, buffer, buffersize)) == -1) {
+ return 0;
+ }
+
+ return ret;
+}
+
+int
+proc_udata_info(int pid, int flavor, void *buffer, int buffersize)
+{
+ return (__proc_info(PROC_INFO_CALL_UDATA_INFO, pid, flavor, 0, buffer, buffersize));
+}
int
proc_name(int pid, void * buffer, uint32_t buffersize)
int
proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize)
{
- int retval = 0, len;
+ int retval;
struct proc_regionwithpathinfo reginfo;
if (buffersize < MAXPATHLEN) {
return(0);
}
- retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, ®info, sizeof(struct proc_regionwithpathinfo));
+ retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO2, (uint64_t)address, ®info, sizeof(struct proc_regionwithpathinfo));
if (retval != -1) {
- len = (int)strlen(®info.prp_vip.vip_path[0]);
- if (len != 0) {
- if (len > MAXPATHLEN)
- len = MAXPATHLEN;
- bcopy(®info.prp_vip.vip_path[0], buffer, len);
- return(len);
- }
- return(0);
+ return ((int)(strlcpy(buffer, reginfo.prp_vip.vip_path, MAXPATHLEN)));
}
- return(0);
-
+ return(0);
}
int
return 0;
}
+/*
+ * XXX the _fatal() variant both checks for an existing monitor
+ * (with important policy effects on first party background apps)
+ * and validates inputs.
+ */
int
proc_set_cpumon_params(pid_t pid, int percentage, int interval)
{
proc_policy_cpuusage_attr_t attr;
+ /* no argument validation ...
+ * task_set_cpuusage() ignores 0 values and squashes negative
+ * values into uint32_t.
+ */
+
attr.ppattr_cpu_attr = PROC_POLICY_RSRCACT_NOTIFY_EXC;
attr.ppattr_cpu_percentage = percentage;
attr.ppattr_cpu_attr_interval = (uint64_t)interval;
PROC_POLICY_RUSAGE_CPU, (proc_policy_attribute_t*)&attr, pid, 0));
}
+int
+proc_resume_cpumon(pid_t pid)
+{
+ return __process_policy(PROC_POLICY_SCOPE_PROCESS,
+ PROC_POLICY_ACTION_ENABLE,
+ PROC_POLICY_RESOURCE_USAGE,
+ PROC_POLICY_RUSAGE_CPU,
+ NULL, pid, 0);
+}
+
int
proc_disable_cpumon(pid_t pid)
{
* already active. If either the percentage or the
* interval is nonzero, then CPU monitoring is
* already in use for this process.
+ *
+ * XXX: need set...() and set..fatal() to behave similarly.
+ * Currently, this check prevents 1st party apps (which get a
+ * default non-fatal monitor) not to get a fatal monitor.
*/
(void)proc_get_cpumon_params(pid, ¤t_percentage, ¤t_interval);
if (current_percentage || current_interval)
return (proc_rlimit_control(pid, RLIMIT_WAKEUPS_MONITOR, ¶ms));
}
+int
+proc_list_uptrs(int pid, uint64_t *buf, uint32_t bufsz)
+{
+ return __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDLISTUPTRS, 0,
+ buf, bufsz);
+}
+
+int
+proc_list_dynkqueueids(int pid, kqueue_id_t *buf, uint32_t bufsz)
+{
+ return __proc_info(PROC_INFO_CALL_PIDINFO, pid, PROC_PIDLISTDYNKQUEUES, 0,
+ buf, bufsz);
+}
+
+
+int
+proc_setcpu_percentage(pid_t pid, int action, int percentage)
+{
+ proc_policy_cpuusage_attr_t attr;
+
+ bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
+ attr.ppattr_cpu_attr = action;
+ attr.ppattr_cpu_percentage = percentage;
+ 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)
+ return(0);
+ else
+ return(errno);
+}
+
+int
+proc_clear_cpulimits(pid_t pid)
+{
+ 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)
+ return(0);
+ else
+ return(errno);
+}
+
+#if TARGET_OS_EMBEDDED
+
+int
+proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline)
+{
+ proc_policy_cpuusage_attr_t attr;
+
+ bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
+ attr.ppattr_cpu_attr = action;
+ attr.ppattr_cpu_attr_deadline = deadline;
+ 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)
+ return(0);
+ else
+ return(errno);
+
+}
+
+int
+proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline)
+{
+ proc_policy_cpuusage_attr_t attr;
+
+ bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
+ attr.ppattr_cpu_attr = action;
+ attr.ppattr_cpu_percentage = percentage;
+ attr.ppattr_cpu_attr_deadline = deadline;
+ 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)
+ return(0);
+ else
+ return(errno);
+}
+
+int
+proc_appstate(int pid, int * appstatep)
+{
+ int state;
+
+ 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) {
+ if (appstatep != NULL)
+ *appstatep = state;
+ return(0);
+ } else
+ return(errno);
+
+}
+int
+proc_setappstate(int pid, int appstate)
+{
+ int state = appstate;
+
+ switch (state) {
+ case PROC_APPSTATE_NONE:
+ case PROC_APPSTATE_ACTIVE:
+ case PROC_APPSTATE_INACTIVE:
+ case PROC_APPSTATE_BACKGROUND:
+ case PROC_APPSTATE_NONUI:
+ break;
+ default:
+ return(EINVAL);
+ }
+ 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)
+ return(0);
+ else
+ return(errno);
+}
+
+int
+proc_devstatusnotify(int devicestatus)
+{
+ int state = devicestatus;
+
+ switch (devicestatus) {
+ case PROC_DEVSTATUS_SHORTTERM:
+ case PROC_DEVSTATUS_LONGTERM:
+ break;
+ default:
+ return(EINVAL);
+ }
+
+ 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) {
+ return(0);
+ } else
+ return(errno);
+
+}
+
+int
+proc_pidbind(int pid, uint64_t threadid, int bind)
+{
+ int state = bind;
+ pid_t passpid = pid;
+
+ switch (bind) {
+ case PROC_PIDBIND_CLEAR:
+ passpid = getpid(); /* ignore pid on clear */
+ break;
+ case PROC_PIDBIND_SET:
+ break;
+ default:
+ return(EINVAL);
+ }
+ 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)
+ return(0);
+ else
+ return(errno);
+}
+
+int
+proc_can_use_foreground_hw(int pid, uint32_t *reason)
+{
+ return __proc_info(PROC_INFO_CALL_CANUSEFGHW, pid, 0, NULL, reason, sizeof(*reason));
+}
+#endif /* TARGET_OS_EMBEDDED */
/* Donate importance to adaptive processes from this process */
{
int rval;
+#if TARGET_OS_EMBEDDED
+ rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
+ PROC_POLICY_ACTION_ENABLE,
+ PROC_POLICY_APPTYPE,
+ PROC_POLICY_IOS_DONATEIMP,
+ NULL, getpid(), (uint64_t)0);
+#else /* TARGET_OS_EMBEDDED */
rval = __process_policy(PROC_POLICY_SCOPE_PROCESS,
PROC_POLICY_ACTION_SET,
PROC_POLICY_BOOST,
PROC_POLICY_IMP_DONATION,
NULL, getpid(), 0);
+#endif /* TARGET_OS_EMBEDDED */
if (rval == 0)
return (0);
return proc_importance_assertion_complete(assertion_token);
}
+#if !TARGET_OS_EMBEDDED
int
proc_clear_vmpressure(pid_t pid)
#endif /* !TARGET_IPHONE_SIMULATOR */
+#endif /* !TARGET_OS_EMBEDDED */