Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: third_party/psutil/psutil/arch/osx/process_info.c

Issue 8919026: Remove psutil from tree, install via install-build-deps.sh (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Sort package list. Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/psutil/psutil/arch/osx/process_info.h ('k') | third_party/psutil/psutil/error.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * $Id: process_info.c 1142 2011-10-05 18:45:49Z g.rodola $
3 *
4 * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 *
8 * Helper functions related to fetching process information. Used by _psutil_osx
9 * module methods.
10 */
11
12 #include <Python.h>
13 #include <assert.h>
14 #include <errno.h>
15 #include <limits.h> /* for INT_MAX */
16 #include <stdbool.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <signal.h>
20 #include <sys/sysctl.h>
21
22 #include "process_info.h"
23 #include "../../_psutil_common.h"
24
25
26 /*
27 * Return 1 if PID exists in the current process list, else 0.
28 */
29 int
30 pid_exists(long pid)
31 {
32 int kill_ret;
33
34 // save some time if it's an invalid PID
35 if (pid < 0) {
36 return 0;
37 }
38
39 // if kill returns success of permission denied we know it's a valid PID
40 kill_ret = kill(pid , 0);
41 if ( (0 == kill_ret) || (EPERM == errno) ) {
42 return 1;
43 }
44
45 // otherwise return 0 for PID not found
46 return 0;
47 }
48
49
50
51 /*
52 * Returns a list of all BSD processes on the system. This routine
53 * allocates the list and puts it in *procList and a count of the
54 * number of entries in *procCount. You are responsible for freeing
55 * this list (use "free" from System framework).
56 * On success, the function returns 0.
57 * On error, the function returns a BSD errno value.
58 */
59 int
60 get_proc_list(kinfo_proc **procList, size_t *procCount)
61 {
62 /* Declaring mib as const requires use of a cast since the
63 * sysctl prototype doesn't include the const modifier. */
64 static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
65 size_t size, size2;
66 void *ptr;
67 int err, lim = 8; /* some limit */
68
69 assert( procList != NULL);
70 assert(*procList == NULL);
71 assert(procCount != NULL);
72
73 *procCount = 0;
74
75 /* We start by calling sysctl with ptr == NULL and size == 0.
76 * That will succeed, and set size to the appropriate length.
77 * We then allocate a buffer of at least that size and call
78 * sysctl with that buffer. If that succeeds, we're done.
79 * If that call fails with ENOMEM, we throw the buffer away
80 * and try again.
81 * Note that the loop calls sysctl with NULL again. This is
82 * is necessary because the ENOMEM failure case sets size to
83 * the amount of data returned, not the amount of data that
84 * could have been returned.
85 */
86 while (lim-- > 0) {
87 size = 0;
88 if (sysctl((int *)mib3, 3, NULL, &size, NULL, 0) == -1) {
89 return errno;
90 }
91
92 size2 = size + (size >> 3); /* add some */
93 if (size2 > size) {
94 ptr = malloc(size2);
95 if (ptr == NULL) {
96 ptr = malloc(size);
97 } else {
98 size = size2;
99 }
100 }
101 else {
102 ptr = malloc(size);
103 }
104 if (ptr == NULL) {
105 return ENOMEM;
106 }
107
108 if (sysctl((int *)mib3, 3, ptr, &size, NULL, 0) == -1) {
109 err = errno;
110 free(ptr);
111 if (err != ENOMEM) {
112 return err;
113 }
114
115 } else {
116 *procList = (kinfo_proc *)ptr;
117 *procCount = size / sizeof(kinfo_proc);
118 return 0;
119 }
120 }
121 return ENOMEM;
122 }
123
124
125 /* Read the maximum argument size for processes */
126 int
127 get_argmax()
128 {
129 int argmax;
130 int mib[] = { CTL_KERN, KERN_ARGMAX };
131 size_t size = sizeof(argmax);
132
133 if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0) {
134 return argmax;
135 }
136 return 0;
137 }
138
139
140 /* return process args as a python list */
141 PyObject*
142 get_arg_list(long pid)
143 {
144 int mib[3];
145 int nargs;
146 int len;
147 char *procargs;
148 char *arg_ptr;
149 char *arg_end;
150 char *curr_arg;
151 size_t argmax;
152 PyObject *arg = NULL;
153 PyObject *arglist = NULL;
154
155 //special case for PID 0 (kernel_task) where cmdline cannot be fetched
156 if (pid == 0) {
157 return Py_BuildValue("[]");
158 }
159
160 /* read argmax and allocate memory for argument space. */
161 argmax = get_argmax();
162 if (! argmax) { return PyErr_SetFromErrno(PyExc_OSError); }
163
164 procargs = (char *)malloc(argmax);
165 if (NULL == procargs) {
166 return PyErr_SetFromErrno(PyExc_OSError);
167 }
168
169 /* read argument space */
170 mib[0] = CTL_KERN;
171 mib[1] = KERN_PROCARGS2;
172 mib[2] = pid;
173 if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
174 if (EINVAL == errno) { // invalid == access denied OR nonexistent PID
175 if ( pid_exists(pid) ) {
176 AccessDenied();
177 } else {
178 NoSuchProcess();
179 }
180 }
181 free(procargs);
182 return NULL;
183 }
184
185 arg_end = &procargs[argmax];
186 /* copy the number of arguments to nargs */
187 memcpy(&nargs, procargs, sizeof(nargs));
188
189 arg_ptr = procargs + sizeof(nargs);
190 len = strlen(arg_ptr);
191 arg_ptr += len + 1;
192
193 if (arg_ptr == arg_end) {
194 free(procargs);
195 return Py_BuildValue("[]");
196 }
197
198 // skip ahead to the first argument
199 for (; arg_ptr < arg_end; arg_ptr++) {
200 if (*arg_ptr != '\0') {
201 break;
202 }
203 }
204
205 /* iterate through arguments */
206 curr_arg = arg_ptr;
207 arglist = Py_BuildValue("[]");
208 while (arg_ptr < arg_end && nargs > 0) {
209 if (*arg_ptr++ == '\0') {
210 arg = Py_BuildValue("s", curr_arg);
211 if (NULL == arg) {
212 return NULL;
213 }
214 PyList_Append(arglist, arg);
215 Py_DECREF(arg);
216 // iterate to next arg and decrement # of args
217 curr_arg = arg_ptr;
218 nargs--;
219 }
220 }
221
222 free(procargs);
223 return arglist;
224 }
225
226
227 int
228 get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
229 {
230 int mib[4];
231 size_t len;
232 mib[0] = CTL_KERN;
233 mib[1] = KERN_PROC;
234 mib[2] = KERN_PROC_PID;
235 mib[3] = pid;
236
237 // fetch the info with sysctl()
238 len = sizeof(struct kinfo_proc);
239
240 // now read the data from sysctl
241 if (sysctl(mib, 4, kp, &len, NULL, 0) == -1) {
242 // raise an exception and throw errno as the error
243 PyErr_SetFromErrno(PyExc_OSError);
244 }
245
246 /*
247 * sysctl succeeds but len is zero, happens when process has gone away
248 */
249 if (len == 0) {
250 NoSuchProcess();
251 return -1;
252 }
253 return 0;
254 }
OLDNEW
« no previous file with comments | « third_party/psutil/psutil/arch/osx/process_info.h ('k') | third_party/psutil/psutil/error.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698