Index: third_party/psutil/psutil/_psutil_bsd.c |
diff --git a/third_party/psutil/psutil/_psutil_bsd.c b/third_party/psutil/psutil/_psutil_bsd.c |
index d937cbf4c1efcc47bbca100c344f3f89497a7747..2e7e1c614a02f7d9ba4732a2d73659f14d3f72ce 100644 |
--- a/third_party/psutil/psutil/_psutil_bsd.c |
+++ b/third_party/psutil/psutil/_psutil_bsd.c |
@@ -1,5 +1,5 @@ |
/* |
- * $Id: _psutil_bsd.c 1142 2011-10-05 18:45:49Z g.rodola $ |
+ * $Id: _psutil_bsd.c 1206 2011-10-26 21:13:51Z g.rodola $ |
* |
* Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved. |
* Use of this source code is governed by a BSD-style license that can be |
@@ -19,13 +19,19 @@ |
#include <sys/param.h> |
#include <sys/user.h> |
#include <sys/proc.h> |
+#include <sys/socket.h> |
+#include <devstat.h> /* get io counters */ |
#include <sys/vmmeter.h> /* needed for vmtotal struct */ |
+#include <libutil.h> /* process open files */ |
#include <sys/mount.h> |
-// network-related stuff |
-#include <net/if.h> |
+ |
+#include <net/if.h> /* net io counters */ |
#include <net/if_dl.h> |
#include <net/route.h> |
+#include <netinet/in.h> /* process open files/connections */ |
+#include <sys/un.h> |
+ |
#include "_psutil_bsd.h" |
#include "_psutil_common.h" |
#include "arch/bsd/process_info.h" |
@@ -357,7 +363,7 @@ get_process_threads(PyObject* self, PyObject* args) |
if (error == -1) { |
PyErr_SetFromErrno(PyExc_OSError); |
return NULL; |
- } |
+ } |
if (size == 0) { |
return NoSuchProcess(); |
} |
@@ -643,6 +649,101 @@ get_system_cpu_times(PyObject* self, PyObject* args) |
); |
} |
+/* |
+ * XXX |
+ * These functions are available on FreeBSD 8 only. |
+ * In the upper python layer we do various tricks to avoid crashing |
+ * and/or to provide alternatives where possible. |
+ */ |
+ |
+ |
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 |
+/* |
+ * Return files opened by process as a list of (path, fd) tuples |
+ */ |
+static PyObject* |
+get_process_open_files(PyObject* self, PyObject* args) |
+{ |
+ long pid; |
+ PyObject *retList = PyList_New(0); |
+ PyObject *tuple = NULL; |
+ |
+ struct kinfo_file *freep, *kif; |
+ struct kinfo_proc kipp; |
+ |
+ |
+ int i, cnt; |
+ |
+ if (! PyArg_ParseTuple(args, "l", &pid)) |
+ return NULL; |
+ if (get_kinfo_proc(pid, &kipp) == -1) |
+ return NULL; |
+ |
+ freep = kinfo_getfile(pid, &cnt); |
+ if (freep == NULL) { |
+ PyErr_SetFromErrno(0); |
+ return NULL; |
+ } |
+ |
+ for (i = 0; i < cnt; i++) { |
+ kif = &freep[i]; |
+ if ((kif->kf_type == KF_TYPE_VNODE) && |
+ (kif->kf_vnode_type == KF_VTYPE_VREG)) |
+ { |
+ tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd); |
+ PyList_Append(retList, tuple); |
+ Py_DECREF(tuple); |
+ } |
+ } |
+ free(freep); |
+ |
+ return retList; |
+} |
+ |
+ |
+/* |
+ * Return process current working directory. |
+ */ |
+static PyObject* |
+get_process_cwd(PyObject* self, PyObject* args) |
+{ |
+ long pid; |
+ PyObject *path = NULL; |
+ struct kinfo_file *freep, *kif; |
+ struct kinfo_proc kipp; |
+ |
+ int i, cnt; |
+ |
+ if (! PyArg_ParseTuple(args, "l", &pid)) |
+ return NULL; |
+ if (get_kinfo_proc(pid, &kipp) == -1) |
+ return NULL; |
+ |
+ freep = kinfo_getfile(pid, &cnt); |
+ if (freep == NULL) { |
+ PyErr_SetFromErrno(0); |
+ return NULL; |
+ } |
+ |
+ for (i = 0; i < cnt; i++) { |
+ kif = &freep[i]; |
+ if (kif->kf_fd == KF_FD_TYPE_CWD) { |
+ path = Py_BuildValue("s", kif->kf_path); |
+ break; |
+ } |
+ } |
+ /* |
+ * For lower pids it seems we can't retrieve any information |
+ * (lsof can't do that it either). Since this happens even |
+ * as root we return an empty string instead of AccessDenied. |
+ */ |
+ if (path == NULL) { |
+ path = Py_BuildValue("s", ""); |
+ } |
+ free(freep); |
+ return path; |
+} |
+ |
/* |
* Return a Python list of tuple representing per-cpu times |
@@ -697,6 +798,7 @@ get_system_per_cpu_times(PyObject* self, PyObject* args) |
return py_retlist; |
} |
+#endif |
/* |
@@ -813,10 +915,68 @@ get_network_io_counters(PyObject* self, PyObject* args) |
} |
} |
+ free(buf); |
return py_retdict; |
} |
+/* |
+ * Return a Python dict of tuples for disk I/O information |
+ */ |
+static PyObject* |
+get_disk_io_counters(PyObject* self, PyObject* args) |
+{ |
+ PyObject* py_retdict = PyDict_New(); |
+ PyObject* py_disk_info; |
+ |
+ int i; |
+ struct statinfo stats; |
+ |
+ if (devstat_checkversion(NULL) < 0) { |
+ Py_DECREF(py_retdict); |
+ return PyErr_Format(PyExc_RuntimeError, |
+ "devstat_checkversion() failed"); |
+ } |
+ |
+ stats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); |
+ bzero(stats.dinfo, sizeof(struct devinfo)); |
+ |
+ if (devstat_getdevs(NULL, &stats) == -1) { |
+ Py_DECREF(py_retdict); |
+ return PyErr_Format(PyExc_RuntimeError, |
+ "devstat_getdevs() failed"); |
+ } |
+ |
+ for (i = 0; i < stats.dinfo->numdevs; i++) { |
+ struct devstat current; |
+ char disk_name[128]; |
+ current = stats.dinfo->devices[i]; |
+ snprintf(disk_name, sizeof(disk_name), "%s%d", |
+ current.device_name, |
+ current.unit_number); |
+ |
+ |
+ py_disk_info = Py_BuildValue("(KKKKLL)", |
+ current.operations[DEVSTAT_READ], // no reads |
+ current.operations[DEVSTAT_WRITE], // no writes |
+ current.bytes[DEVSTAT_READ], // bytes read |
+ current.bytes[DEVSTAT_WRITE], // bytes written |
+ (long long)devstat_compute_etime( |
+ ¤t.duration[DEVSTAT_READ], NULL), // r time |
+ (long long)devstat_compute_etime( |
+ ¤t.duration[DEVSTAT_WRITE], NULL) // w time |
+ ); |
+ PyDict_SetItemString(py_retdict, disk_name, py_disk_info); |
+ Py_XDECREF(py_disk_info); |
+ } |
+ |
+ if (stats.dinfo->mem_ptr) { |
+ free(stats.dinfo->mem_ptr); |
+ } |
+ free(stats.dinfo); |
+ |
+ return py_retdict; |
+} |
/* |
@@ -856,7 +1016,12 @@ PsutilMethods[] = |
"Return process IO counters"}, |
{"get_process_tty_nr", get_process_tty_nr, METH_VARARGS, |
"Return process tty (terminal) number"}, |
- |
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 |
+ {"get_process_open_files", get_process_open_files, METH_VARARGS, |
+ "Return files opened by process as a list of (path, fd) tuples"}, |
+ {"get_process_cwd", get_process_cwd, METH_VARARGS, |
+ "Return process current working directory."}, |
+#endif |
// --- system-related functions |
@@ -874,8 +1039,10 @@ PsutilMethods[] = |
"Return the amount of available virtual memory, in bytes"}, |
{"get_system_cpu_times", get_system_cpu_times, METH_VARARGS, |
"Return system cpu times as a tuple (user, system, nice, idle, irc)"}, |
+#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 |
{"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS, |
"Return system per-cpu times as a list of tuples"}, |
+#endif |
{"get_system_boot_time", get_system_boot_time, METH_VARARGS, |
"Return a float indicating the system boot time expressed in " |
"seconds since the epoch"}, |
@@ -884,6 +1051,8 @@ PsutilMethods[] = |
"fs type for all partitions mounted on the system."}, |
{"get_network_io_counters", get_network_io_counters, METH_VARARGS, |
"Return dict of tuples of networks I/O information."}, |
+ {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS, |
+ "Return a Python dict of tuples for disk I/O information"}, |
{NULL, NULL, 0, NULL} |
}; |