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

Side by Side Diff: third_party/psutil/psutil/_psutil_bsd.c

Issue 8159001: Update third_party/psutil and fix the licence issue with it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove the suppression and unnecessary files. Created 9 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « third_party/psutil/psutil/_psutil_bsd.h ('k') | third_party/psutil/psutil/_psutil_common.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * $Id: _psutil_bsd.c 780 2010-11-10 18:42:47Z jloden $ 2 * $Id: _psutil_bsd.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.
3 * 7 *
4 * FreeBSD platform-specific module methods for _psutil_bsd 8 * FreeBSD platform-specific module methods for _psutil_bsd
5 */ 9 */
6 10
7 #include <Python.h> 11 #include <Python.h>
8 #include <assert.h> 12 #include <assert.h>
9 #include <errno.h> 13 #include <errno.h>
10 #include <stdlib.h> 14 #include <stdlib.h>
11 #include <stdio.h> 15 #include <stdio.h>
12 #include <signal.h> 16 #include <signal.h>
13 #include <sys/types.h> 17 #include <sys/types.h>
14 #include <sys/sysctl.h> 18 #include <sys/sysctl.h>
15 #include <sys/param.h> 19 #include <sys/param.h>
16 #include <sys/user.h> 20 #include <sys/user.h>
17 #include <sys/proc.h> 21 #include <sys/proc.h>
18 #include <sys/vmmeter.h> /* needed for vmtotal struct */ 22 #include <sys/vmmeter.h> /* needed for vmtotal struct */
23 #include <sys/mount.h>
24 // network-related stuff
25 #include <net/if.h>
26 #include <net/if_dl.h>
27 #include <net/route.h>
19 28
20 #include "_psutil_bsd.h" 29 #include "_psutil_bsd.h"
30 #include "_psutil_common.h"
21 #include "arch/bsd/process_info.h" 31 #include "arch/bsd/process_info.h"
22 32
23 /*
24 * define the psutil C module methods and initialize the module.
25 */
26 static PyMethodDef
27 PsutilMethods[] =
28 {
29 // --- per-process functions
30 33
31 {"get_process_name", get_process_name, METH_VARARGS, 34 // convert a timeval struct to a double
32 "Return process name"}, 35 #define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
33 {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
34 "Return process cmdline as a list of cmdline arguments"},
35 {"get_process_ppid", get_process_ppid, METH_VARARGS,
36 "Return process ppid as an integer"},
37 {"get_process_uid", get_process_uid, METH_VARARGS,
38 "Return process real user id as an integer"},
39 {"get_process_gid", get_process_gid, METH_VARARGS,
40 "Return process real group id as an integer"},
41 {"get_cpu_times", get_cpu_times, METH_VARARGS,
42 "Return tuple of user/kern time for the given PID"},
43 {"get_process_create_time", get_process_create_time, METH_VARARGS,
44 "Return a float indicating the process create time expressed in "
45 "seconds since the epoch"},
46 {"get_memory_info", get_memory_info, METH_VARARGS,
47 "Return a tuple of RSS/VMS memory information"},
48 {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
49 "Return number of threads used by process"},
50
51
52 // --- system-related functions
53
54 {"get_pid_list", get_pid_list, METH_VARARGS,
55 "Returns a list of PIDs currently running on the system"},
56 {"get_num_cpus", get_num_cpus, METH_VARARGS,
57 "Return number of CPUs on the system"},
58 {"get_total_phymem", get_total_phymem, METH_VARARGS,
59 "Return the total amount of physical memory, in bytes"},
60 {"get_avail_phymem", get_avail_phymem, METH_VARARGS,
61 "Return the amount of available physical memory, in bytes"},
62 {"get_total_virtmem", get_total_virtmem, METH_VARARGS,
63 "Return the total amount of virtual memory, in bytes"},
64 {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS,
65 "Return the amount of available virtual memory, in bytes"},
66 {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
67 "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
68
69 {NULL, NULL, 0, NULL}
70 };
71
72 struct module_state {
73 PyObject *error;
74 };
75
76 #if PY_MAJOR_VERSION >= 3
77 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
78 #else
79 #define GETSTATE(m) (&_state)
80 static struct module_state _state;
81 #endif
82
83 #if PY_MAJOR_VERSION >= 3
84
85 static int
86 psutil_bsd_traverse(PyObject *m, visitproc visit, void *arg) {
87 Py_VISIT(GETSTATE(m)->error);
88 return 0;
89 }
90
91 static int
92 psutil_bsd_clear(PyObject *m) {
93 Py_CLEAR(GETSTATE(m)->error);
94 return 0;
95 }
96
97 static struct PyModuleDef
98 moduledef = {
99 PyModuleDef_HEAD_INIT,
100 "psutil_bsd",
101 NULL,
102 sizeof(struct module_state),
103 PsutilMethods,
104 NULL,
105 psutil_bsd_traverse,
106 psutil_bsd_clear,
107 NULL
108 };
109
110 #define INITERROR return NULL
111
112 PyObject *
113 PyInit__psutil_bsd(void)
114
115 #else
116 #define INITERROR return
117
118 void init_psutil_bsd(void)
119 #endif
120 {
121 #if PY_MAJOR_VERSION >= 3
122 PyObject *module = PyModule_Create(&moduledef);
123 #else
124 PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods);
125 #endif
126 if (module == NULL) {
127 INITERROR;
128 }
129 struct module_state *st = GETSTATE(module);
130
131 st->error = PyErr_NewException("_psutil_bsd.Error", NULL, NULL);
132 if (st->error == NULL) {
133 Py_DECREF(module);
134 INITERROR;
135 }
136 #if PY_MAJOR_VERSION >= 3
137 return module;
138 #endif
139 }
140 36
141 37
142 /* 38 /*
143 * Utility function which fills a kinfo_proc struct based on process pid 39 * Utility function which fills a kinfo_proc struct based on process pid
144 */ 40 */
145 static int 41 static int
146 get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc) 42 get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
147 { 43 {
148 int mib[4]; 44 int mib[4];
149 size_t size; 45 size_t size;
150 mib[0] = CTL_KERN; 46 mib[0] = CTL_KERN;
151 mib[1] = KERN_PROC; 47 mib[1] = KERN_PROC;
152 mib[2] = KERN_PROC_PID; 48 mib[2] = KERN_PROC_PID;
153 mib[3] = pid; 49 mib[3] = pid;
154 50
155 size = sizeof(struct kinfo_proc); 51 size = sizeof(struct kinfo_proc);
156 52
157 if (sysctl((int*)mib, 4, proc, &size, NULL, 0) == -1) { 53 if (sysctl((int*)mib, 4, proc, &size, NULL, 0) == -1) {
158 PyErr_SetFromErrno(PyExc_OSError); 54 PyErr_SetFromErrno(PyExc_OSError);
159 return -1; 55 return -1;
160 } 56 }
161 57
162 /* 58 /*
163 * sysctl stores 0 in the size if we can't find the process information. 59 * sysctl stores 0 in the size if we can't find the process information.
164 * Set errno to ESRCH which will be translated in NoSuchProcess later on.
165 */ 60 */
166 if (size == 0) { 61 if (size == 0) {
167 errno = ESRCH; 62 NoSuchProcess();
168 PyErr_SetFromErrno(PyExc_OSError);
169 return -1; 63 return -1;
170 } 64 }
171 return 0; 65 return 0;
172 } 66 }
173 67
174 68
175 /* 69 /*
176 * Return a Python list of all the PIDs running on the system. 70 * Return a Python list of all the PIDs running on the system.
177 */ 71 */
178 static PyObject* 72 static PyObject*
(...skipping 21 matching lines...) Expand all
200 proclist++; 94 proclist++;
201 } 95 }
202 free(orig_address); 96 free(orig_address);
203 } 97 }
204 98
205 return retlist; 99 return retlist;
206 } 100 }
207 101
208 102
209 /* 103 /*
104 * Return a Python float indicating the system boot time expressed in
105 * seconds since the epoch.
106 */
107 static PyObject*
108 get_system_boot_time(PyObject* self, PyObject* args)
109 {
110 /* fetch sysctl "kern.boottime" */
111 static int request[2] = { CTL_KERN, KERN_BOOTTIME };
112 struct timeval result;
113 size_t result_len = sizeof result;
114 time_t boot_time = 0;
115
116 if (sysctl(request, 2, &result, &result_len, NULL, 0) == -1) {
117 PyErr_SetFromErrno(0);
118 return NULL;
119 }
120 boot_time = result.tv_sec;
121 return Py_BuildValue("f", (float)boot_time);
122 }
123
124
125 /*
210 * Return process name from kinfo_proc as a Python string. 126 * Return process name from kinfo_proc as a Python string.
211 */ 127 */
212 static PyObject* 128 static PyObject*
213 get_process_name(PyObject* self, PyObject* args) 129 get_process_name(PyObject* self, PyObject* args)
214 { 130 {
215 long pid; 131 long pid;
216 struct kinfo_proc kp; 132 struct kinfo_proc kp;
217 if (! PyArg_ParseTuple(args, "l", &pid)) { 133 if (! PyArg_ParseTuple(args, "l", &pid)) {
218 return NULL; 134 return NULL;
219 } 135 }
220 if (get_kinfo_proc(pid, &kp) == -1) { 136 if (get_kinfo_proc(pid, &kp) == -1) {
221 return NULL; 137 return NULL;
222 } 138 }
223 return Py_BuildValue("s", kp.ki_comm); 139 return Py_BuildValue("s", kp.ki_comm);
224 } 140 }
225 141
226 142
227 /* 143 /*
144 * Return process pathname executable.
145 * Thanks to Robert N. M. Watson:
146 * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_bin.c?v=8-CURRENT
147 */
148 static PyObject*
149 get_process_exe(PyObject* self, PyObject* args)
150 {
151 long pid;
152 char pathname[PATH_MAX];
153 int error;
154 int mib[4];
155 size_t size;
156
157 if (! PyArg_ParseTuple(args, "l", &pid)) {
158 return NULL;
159 }
160
161 mib[0] = CTL_KERN;
162 mib[1] = KERN_PROC;
163 mib[2] = KERN_PROC_PATHNAME;
164 mib[3] = pid;
165
166 size = sizeof(pathname);
167 error = sysctl(mib, 4, pathname, &size, NULL, 0);
168 if (error == -1) {
169 PyErr_SetFromErrno(PyExc_OSError);
170 return NULL;
171 }
172 if (size == 0 || strlen(pathname) == 0) {
173 if (pid_exists(pid) == 0) {
174 return NoSuchProcess();
175 }
176 else {
177 strcpy(pathname, "");
178 }
179 }
180 return Py_BuildValue("s", pathname);
181 }
182
183
184 /*
228 * Return process cmdline as a Python list of cmdline arguments. 185 * Return process cmdline as a Python list of cmdline arguments.
229 */ 186 */
230 static PyObject* 187 static PyObject*
231 get_process_cmdline(PyObject* self, PyObject* args) 188 get_process_cmdline(PyObject* self, PyObject* args)
232 { 189 {
233 long pid; 190 long pid;
234 PyObject* arglist = NULL; 191 PyObject* arglist = NULL;
235 192
236 if (! PyArg_ParseTuple(args, "l", &pid)) { 193 if (! PyArg_ParseTuple(args, "l", &pid)) {
237 return NULL; 194 return NULL;
(...skipping 23 matching lines...) Expand all
261 return NULL; 218 return NULL;
262 } 219 }
263 if (get_kinfo_proc(pid, &kp) == -1) { 220 if (get_kinfo_proc(pid, &kp) == -1) {
264 return NULL; 221 return NULL;
265 } 222 }
266 return Py_BuildValue("l", (long)kp.ki_ppid); 223 return Py_BuildValue("l", (long)kp.ki_ppid);
267 } 224 }
268 225
269 226
270 /* 227 /*
271 * Return process real uid from kinfo_proc as a Python integer. 228 * Return process status as a Python integer.
272 */ 229 */
273 static PyObject* 230 static PyObject*
274 get_process_uid(PyObject* self, PyObject* args) 231 get_process_status(PyObject* self, PyObject* args)
275 { 232 {
276 long pid; 233 long pid;
277 struct kinfo_proc kp; 234 struct kinfo_proc kp;
235 if (! PyArg_ParseTuple(args, "l", &pid)) {
236 return NULL;
237 }
238 if (get_kinfo_proc(pid, &kp) == -1) {
239 return NULL;
240 }
241 return Py_BuildValue("i", (int)kp.ki_stat);
242 }
243
244
245 /*
246 * Return process real, effective and saved user ids from kinfo_proc
247 * as a Python tuple.
248 */
249 static PyObject*
250 get_process_uids(PyObject* self, PyObject* args)
251 {
252 long pid;
253 struct kinfo_proc kp;
278 if (! PyArg_ParseTuple(args, "l", &pid)) { 254 if (! PyArg_ParseTuple(args, "l", &pid)) {
279 return NULL; 255 return NULL;
280 } 256 }
281 if (get_kinfo_proc(pid, &kp) == -1) { 257 if (get_kinfo_proc(pid, &kp) == -1) {
282 return NULL; 258 return NULL;
283 } 259 }
284 return Py_BuildValue("l", (long)kp.ki_ruid); 260 return Py_BuildValue("lll", (long)kp.ki_ruid,
261 (long)kp.ki_uid,
262 (long)kp.ki_svuid);
285 } 263 }
286 264
287 265
288 /* 266 /*
289 * Return process real group id from ki_comm as a Python integer. 267 * Return process real, effective and saved group ids from kinfo_proc
268 * as a Python tuple.
290 */ 269 */
291 static PyObject* 270 static PyObject*
292 get_process_gid(PyObject* self, PyObject* args) 271 get_process_gids(PyObject* self, PyObject* args)
293 { 272 {
294 long pid; 273 long pid;
295 struct kinfo_proc kp; 274 struct kinfo_proc kp;
296 if (! PyArg_ParseTuple(args, "l", &pid)) { 275 if (! PyArg_ParseTuple(args, "l", &pid)) {
297 return NULL; 276 return NULL;
298 } 277 }
299 if (get_kinfo_proc(pid, &kp) == -1) { 278 if (get_kinfo_proc(pid, &kp) == -1) {
300 return NULL; 279 return NULL;
301 } 280 }
302 return Py_BuildValue("l", (long)kp.ki_rgid); 281 return Py_BuildValue("lll", (long)kp.ki_rgid,
282 (long)kp.ki_groups[0],
283 (long)kp.ki_svuid);
303 } 284 }
304 285
305 286
287 /*
288 * Return process real, effective and saved group ids from kinfo_proc
289 * as a Python tuple.
290 */
291 static PyObject*
292 get_process_tty_nr(PyObject* self, PyObject* args)
293 {
294 long pid;
295 struct kinfo_proc kp;
296 if (! PyArg_ParseTuple(args, "l", &pid)) {
297 return NULL;
298 }
299 if (get_kinfo_proc(pid, &kp) == -1) {
300 return NULL;
301 }
302 return Py_BuildValue("i", kp.ki_tdev);
303 }
304
305
306 /* 306 /*
307 * Return number of threads used by process as a Python integer. 307 * Return number of threads used by process as a Python integer.
308 */ 308 */
309 static PyObject* 309 static PyObject*
310 get_process_num_threads(PyObject* self, PyObject* args) 310 get_process_num_threads(PyObject* self, PyObject* args)
311 { 311 {
312 long pid; 312 long pid;
313 struct kinfo_proc kp; 313 struct kinfo_proc kp;
314 if (! PyArg_ParseTuple(args, "l", &pid)) { 314 if (! PyArg_ParseTuple(args, "l", &pid)) {
315 return NULL; 315 return NULL;
316 } 316 }
317 if (get_kinfo_proc(pid, &kp) == -1) { 317 if (get_kinfo_proc(pid, &kp) == -1) {
318 return NULL; 318 return NULL;
319 } 319 }
320 return Py_BuildValue("l", (long)kp.ki_numthreads); 320 return Py_BuildValue("l", (long)kp.ki_numthreads);
321 } 321 }
322 322
323 323
324 /*
325 * Retrieves all threads used by process returning a list of tuples
326 * including thread id, user time and system time.
327 * Thanks to Robert N. M. Watson:
328 * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_threads.c?v=8-CURRE NT
329 */
330 static PyObject*
331 get_process_threads(PyObject* self, PyObject* args)
332 {
333 long pid;
334 int mib[4];
335 struct kinfo_proc *kip;
336 struct kinfo_proc *kipp;
337 int error;
338 unsigned int i;
339 size_t size;
340 PyObject* retList = PyList_New(0);
341 PyObject* pyTuple = NULL;
324 342
325 // convert a timeval struct to a double 343 if (! PyArg_ParseTuple(args, "l", &pid)) {
326 #define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) 344 return NULL;
345 }
346
347 /*
348 * We need to re-query for thread information, so don't use *kipp.
349 */
350 mib[0] = CTL_KERN;
351 mib[1] = KERN_PROC;
352 mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
353 mib[3] = pid;
354
355 size = 0;
356 error = sysctl(mib, 4, NULL, &size, NULL, 0);
357 if (error == -1) {
358 PyErr_SetFromErrno(PyExc_OSError);
359 return NULL;
360 » }
361 if (size == 0) {
362 return NoSuchProcess();
363 }
364
365 kip = malloc(size);
366 if (kip == NULL) {
367 PyErr_SetFromErrno(PyExc_OSError);
368 return NULL;
369 }
370
371 error = sysctl(mib, 4, kip, &size, NULL, 0);
372 if (error == -1) {
373 PyErr_SetFromErrno(PyExc_OSError);
374 return NULL;
375 }
376 if (size == 0) {
377 return NoSuchProcess();
378 }
379
380 for (i = 0; i < size / sizeof(*kipp); i++) {
381 kipp = &kip[i];
382 pyTuple = Py_BuildValue("Idd", kipp->ki_tid,
383 TV2DOUBLE(kipp->ki_rusage.ru_utime),
384 TV2DOUBLE(kipp->ki_rusage.ru_stime)
385 );
386 PyList_Append(retList, pyTuple);
387 Py_XDECREF(pyTuple);
388 }
389 free(kip);
390 return retList;
391 }
327 392
328 393
329 /* 394 /*
330 * Return a Python tuple (user_time, kernel_time) 395 * Return a Python tuple (user_time, kernel_time)
331 */ 396 */
332 static PyObject* 397 static PyObject*
333 get_cpu_times(PyObject* self, PyObject* args) 398 get_cpu_times(PyObject* self, PyObject* args)
334 { 399 {
335 long pid; 400 long pid;
336 double user_t, sys_t; 401 double user_t, sys_t;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 return NULL; 449 return NULL;
385 } 450 }
386 if (get_kinfo_proc(pid, &kp) == -1) { 451 if (get_kinfo_proc(pid, &kp) == -1) {
387 return NULL; 452 return NULL;
388 } 453 }
389 return Py_BuildValue("d", TV2DOUBLE(kp.ki_start)); 454 return Py_BuildValue("d", TV2DOUBLE(kp.ki_start));
390 } 455 }
391 456
392 457
393 /* 458 /*
459 * Return a Python float indicating the process create time expressed in
460 * seconds since the epoch.
461 */
462 static PyObject*
463 get_process_io_counters(PyObject* self, PyObject* args)
464 {
465 long pid;
466 struct kinfo_proc kp;
467 if (! PyArg_ParseTuple(args, "l", &pid)) {
468 return NULL;
469 }
470 if (get_kinfo_proc(pid, &kp) == -1) {
471 return NULL;
472 }
473 // there's apparently no way to determine bytes count, hence return -1.
474 return Py_BuildValue("(llll)", kp.ki_rusage.ru_inblock,
475 kp.ki_rusage.ru_oublock,
476 -1, -1);
477 }
478
479
480
481 /*
394 * Return the RSS and VMS as a Python tuple. 482 * Return the RSS and VMS as a Python tuple.
395 */ 483 */
396 static PyObject* 484 static PyObject*
397 get_memory_info(PyObject* self, PyObject* args) 485 get_memory_info(PyObject* self, PyObject* args)
398 { 486 {
399 long pid; 487 long pid;
400 struct kinfo_proc kp; 488 struct kinfo_proc kp;
401 if (! PyArg_ParseTuple(args, "l", &pid)) { 489 if (! PyArg_ParseTuple(args, "l", &pid)) {
402 return NULL; 490 return NULL;
403 } 491 }
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 long cpu_time[CPUSTATES]; 627 long cpu_time[CPUSTATES];
540 size_t size; 628 size_t size;
541 629
542 size = sizeof(cpu_time); 630 size = sizeof(cpu_time);
543 631
544 if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) { 632 if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) {
545 PyErr_SetFromErrno(0); 633 PyErr_SetFromErrno(0);
546 return NULL; 634 return NULL;
547 } 635 }
548 636
549 /*
550 #define CP_USER 0
551 #define CP_NICE 1
552 #define CP_SYS 2
553 #define CP_INTR 3
554 #define CP_IDLE 4
555 #define CPUSTATES 5
556 */
557 //user, nice, system, idle, iowait, irqm, softirq
558 return Py_BuildValue("(ddddd)", 637 return Py_BuildValue("(ddddd)",
559 (double)cpu_time[CP_USER] / CLOCKS_PER_SEC, 638 (double)cpu_time[CP_USER] / CLOCKS_PER_SEC,
560 (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC, 639 (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC,
561 (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC, 640 (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC,
562 (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC, 641 (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC,
563 (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC 642 (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC
564 ); 643 );
565 } 644 }
566 645
646
647 /*
648 * Return a Python list of tuple representing per-cpu times
649 */
650 static PyObject*
651 get_system_per_cpu_times(PyObject* self, PyObject* args)
652 {
653 static int maxcpus;
654 int mib[2];
655 int ncpu;
656 size_t len;
657 size_t size;
658 int i;
659 PyObject* py_retlist = PyList_New(0);
660 PyObject* py_cputime;
661
662 // retrieve maxcpus value
663 size = sizeof(maxcpus);
664 if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
665 PyErr_SetFromErrno(0);
666 return NULL;
667 }
668 long cpu_time[maxcpus][CPUSTATES];
669
670 // retrieve the number of cpus
671 mib[0] = CTL_HW;
672 mib[1] = HW_NCPU;
673 len = sizeof(ncpu);
674 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
675 PyErr_SetFromErrno(0);
676 return NULL;
677 }
678
679 // per-cpu info
680 size = sizeof(cpu_time);
681 if (sysctlbyname("kern.cp_times", &cpu_time, &size, NULL, 0) == -1) {
682 PyErr_SetFromErrno(0);
683 return NULL;
684 }
685
686 for (i = 0; i < ncpu; i++) {
687 py_cputime = Py_BuildValue("(ddddd)",
688 (double)cpu_time[i][CP_USER] / CLOCKS_PER_SEC,
689 (double)cpu_time[i][CP_NICE] / CLOCKS_PER_SEC,
690 (double)cpu_time[i][CP_SYS] / CLOCKS_PER_SEC,
691 (double)cpu_time[i][CP_IDLE] / CLOCKS_PER_SEC,
692 (double)cpu_time[i][CP_INTR] / CLOCKS_PER_SEC
693 );
694 PyList_Append(py_retlist, py_cputime);
695 Py_XDECREF(py_cputime);
696 }
697
698 return py_retlist;
699 }
700
701
702 /*
703 * Return a list of tuples including device, mount point and fs type
704 * for all partitions mounted on the system.
705 */
706 static PyObject*
707 get_disk_partitions(PyObject* self, PyObject* args)
708 {
709 int num;
710 int i;
711 long len;
712 struct statfs *fs;
713 PyObject* py_retlist = PyList_New(0);
714 PyObject* py_tuple;
715
716 // get the number of mount points
717 Py_BEGIN_ALLOW_THREADS
718 num = getfsstat(NULL, 0, MNT_NOWAIT);
719 Py_END_ALLOW_THREADS
720 if (num == -1) {
721 PyErr_SetFromErrno(0);
722 return NULL;
723 }
724
725 len = sizeof(*fs) * num;
726 fs = malloc(len);
727
728 Py_BEGIN_ALLOW_THREADS
729 num = getfsstat(fs, len, MNT_NOWAIT);
730 Py_END_ALLOW_THREADS
731 if (num == -1) {
732 free(fs);
733 PyErr_SetFromErrno(0);
734 return NULL;
735 }
736
737 for (i = 0; i < num; i++) {
738 py_tuple = Py_BuildValue("(sss)", fs[i].f_mntfromname, // device
739 fs[i].f_mntonname, // mount point
740 fs[i].f_fstypename); // fs type
741 PyList_Append(py_retlist, py_tuple);
742 Py_XDECREF(py_tuple);
743 }
744
745 free(fs);
746 return py_retlist;
747 }
748
749
750 /*
751 * Return a Python list of named tuples with overall network I/O information
752 */
753 static PyObject*
754 get_network_io_counters(PyObject* self, PyObject* args)
755 {
756 PyObject* py_retdict = PyDict_New();
757 PyObject* py_ifc_info;
758
759 char *buf = NULL, *lim, *next;
760 struct if_msghdr *ifm;
761 int mib[6];
762 size_t len;
763
764 mib[0] = CTL_NET; // networking subsystem
765 mib[1] = PF_ROUTE; // type of information
766 mib[2] = 0; // protocol (IPPROTO_xxx)
767 mib[3] = 0; // address family
768 mib[4] = NET_RT_IFLIST; // operation
769 mib[5] = 0;
770
771 if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
772 Py_DECREF(py_retdict);
773 PyErr_SetFromErrno(0);
774 return NULL;
775 }
776
777
778 buf = malloc(len);
779
780 if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
781 if (buf) {
782 free(buf);
783 }
784 Py_DECREF(py_retdict);
785 PyErr_SetFromErrno(0);
786 return NULL;
787 }
788
789 lim = buf + len;
790
791 for (next = buf; next < lim; ) {
792 ifm = (struct if_msghdr *)next;
793 next += ifm->ifm_msglen;
794
795 if (ifm->ifm_type == RTM_IFINFO) {
796 struct if_msghdr *if2m = (struct if_msghdr *)ifm;
797 struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
798 char ifc_name[32];
799
800 strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
801 ifc_name[sdl->sdl_nlen] = 0;
802
803 py_ifc_info = Py_BuildValue("(KKKK)",
804 if2m->ifm_data.ifi_obytes,
805 if2m->ifm_data.ifi_ibytes,
806 if2m->ifm_data.ifi_opackets,
807 if2m->ifm_data.ifi_ipackets);
808 PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info);
809 Py_XDECREF(py_ifc_info);
810 }
811 else {
812 continue;
813 }
814 }
815
816 return py_retdict;
817 }
818
819
820
821
822 /*
823 * define the psutil C module methods and initialize the module.
824 */
825 static PyMethodDef
826 PsutilMethods[] =
827 {
828 // --- per-process functions
829
830 {"get_process_name", get_process_name, METH_VARARGS,
831 "Return process name"},
832 {"get_process_exe", get_process_exe, METH_VARARGS,
833 "Return process pathname executable"},
834 {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
835 "Return process cmdline as a list of cmdline arguments"},
836 {"get_process_ppid", get_process_ppid, METH_VARARGS,
837 "Return process ppid as an integer"},
838 {"get_process_uids", get_process_uids, METH_VARARGS,
839 "Return process real effective and saved user ids as a Python tuple"},
840 {"get_process_gids", get_process_gids, METH_VARARGS,
841 "Return process real effective and saved group ids as a Python tuple"},
842 {"get_cpu_times", get_cpu_times, METH_VARARGS,
843 "Return tuple of user/kern time for the given PID"},
844 {"get_process_create_time", get_process_create_time, METH_VARARGS,
845 "Return a float indicating the process create time expressed in "
846 "seconds since the epoch"},
847 {"get_memory_info", get_memory_info, METH_VARARGS,
848 "Return a tuple of RSS/VMS memory information"},
849 {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
850 "Return number of threads used by process"},
851 {"get_process_threads", get_process_threads, METH_VARARGS,
852 "Return process threads"},
853 {"get_process_status", get_process_status, METH_VARARGS,
854 "Return process status as an integer"},
855 {"get_process_io_counters", get_process_io_counters, METH_VARARGS,
856 "Return process IO counters"},
857 {"get_process_tty_nr", get_process_tty_nr, METH_VARARGS,
858 "Return process tty (terminal) number"},
859
860
861 // --- system-related functions
862
863 {"get_pid_list", get_pid_list, METH_VARARGS,
864 "Returns a list of PIDs currently running on the system"},
865 {"get_num_cpus", get_num_cpus, METH_VARARGS,
866 "Return number of CPUs on the system"},
867 {"get_total_phymem", get_total_phymem, METH_VARARGS,
868 "Return the total amount of physical memory, in bytes"},
869 {"get_avail_phymem", get_avail_phymem, METH_VARARGS,
870 "Return the amount of available physical memory, in bytes"},
871 {"get_total_virtmem", get_total_virtmem, METH_VARARGS,
872 "Return the total amount of virtual memory, in bytes"},
873 {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS,
874 "Return the amount of available virtual memory, in bytes"},
875 {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
876 "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
877 {"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS,
878 "Return system per-cpu times as a list of tuples"},
879 {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
880 "Return a float indicating the system boot time expressed in "
881 "seconds since the epoch"},
882 {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
883 "Return a list of tuples including device, mount point and "
884 "fs type for all partitions mounted on the system."},
885 {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
886 "Return dict of tuples of networks I/O information."},
887
888 {NULL, NULL, 0, NULL}
889 };
890
891 struct module_state {
892 PyObject *error;
893 };
894
895 #if PY_MAJOR_VERSION >= 3
896 #define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
897 #else
898 #define GETSTATE(m) (&_state)
899 #endif
900
901 #if PY_MAJOR_VERSION >= 3
902
903 static int
904 psutil_bsd_traverse(PyObject *m, visitproc visit, void *arg) {
905 Py_VISIT(GETSTATE(m)->error);
906 return 0;
907 }
908
909 static int
910 psutil_bsd_clear(PyObject *m) {
911 Py_CLEAR(GETSTATE(m)->error);
912 return 0;
913 }
914
915 static struct PyModuleDef
916 moduledef = {
917 PyModuleDef_HEAD_INIT,
918 "psutil_bsd",
919 NULL,
920 sizeof(struct module_state),
921 PsutilMethods,
922 NULL,
923 psutil_bsd_traverse,
924 psutil_bsd_clear,
925 NULL
926 };
927
928 #define INITERROR return NULL
929
930 PyObject *
931 PyInit__psutil_bsd(void)
932
933 #else
934 #define INITERROR return
935
936 void init_psutil_bsd(void)
937 #endif
938 {
939 #if PY_MAJOR_VERSION >= 3
940 PyObject *module = PyModule_Create(&moduledef);
941 #else
942 PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods);
943 #endif
944 PyModule_AddIntConstant(module, "SSTOP", SSTOP);
945 PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
946 PyModule_AddIntConstant(module, "SRUN", SRUN);
947 PyModule_AddIntConstant(module, "SIDL", SIDL);
948 PyModule_AddIntConstant(module, "SWAIT", SWAIT);
949 PyModule_AddIntConstant(module, "SLOCK", SLOCK);
950 PyModule_AddIntConstant(module, "SZOMB", SZOMB);
951
952 if (module == NULL) {
953 INITERROR;
954 }
955 #if PY_MAJOR_VERSION >= 3
956 return module;
957 #endif
958 }
959
OLDNEW
« no previous file with comments | « third_party/psutil/psutil/_psutil_bsd.h ('k') | third_party/psutil/psutil/_psutil_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698