| 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}
|
| };
|
|
|