http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.c
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.c
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.c
new file mode 100644
index 0000000..0c83345
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.c
@@ -0,0 +1,1881 @@
+/*
+ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * OS X platform-specific module methods for _psutil_osx
+ */
+
+#include <Python.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <utmpx.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+#include <libproc.h>
+#include <sys/proc_info.h>
+#include <netinet/tcp_fsm.h>
+#include <arpa/inet.h>
+#include <net/if_dl.h>
+#include <pwd.h>
+
+#include <mach/mach.h>
+#include <mach/task.h>
+#include <mach/mach_init.h>
+#include <mach/host_info.h>
+#include <mach/mach_host.h>
+#include <mach/mach_traps.h>
+#include <mach/mach_vm.h>
+#include <mach/shared_region.h>
+
+#include <mach-o/loader.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <IOKit/IOKitLib.h>
+#include <IOKit/storage/IOBlockStorageDriver.h>
+#include <IOKit/storage/IOMedia.h>
+#include <IOKit/IOBSD.h>
+
+#include "_psutil_osx.h"
+#include "_psutil_common.h"
+#include "arch/osx/process_info.h"
+
+
+/*
+ * A wrapper around host_statistics() invoked with HOST_VM_INFO.
+ */
+int
+psutil_sys_vminfo(vm_statistics_data_t *vmstat)
+{
+    kern_return_t ret;
+    mach_msg_type_number_t count = sizeof(*vmstat) / sizeof(integer_t);
+    mach_port_t mport = mach_host_self();
+
+    ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)vmstat, &count);
+    if (ret != KERN_SUCCESS) {
+        PyErr_Format(PyExc_RuntimeError,
+                     "host_statistics() failed: %s", mach_error_string(ret));
+        return 0;
+    }
+    mach_port_deallocate(mach_task_self(), mport);
+    return 1;
+}
+
+
+/*
+ * Return a Python list of all the PIDs running on the system.
+ */
+static PyObject *
+psutil_pids(PyObject *self, PyObject *args)
+{
+    kinfo_proc *proclist = NULL;
+    kinfo_proc *orig_address = NULL;
+    size_t num_processes;
+    size_t idx;
+    PyObject *pid = NULL;
+    PyObject *retlist = PyList_New(0);
+
+    if (retlist == NULL)
+        return NULL;
+
+    if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "failed to retrieve process list.");
+        goto error;
+    }
+
+    if (num_processes > 0) {
+        // save the address of proclist so we can free it later
+        orig_address = proclist;
+        for (idx = 0; idx < num_processes; idx++) {
+            pid = Py_BuildValue("i", proclist->kp_proc.p_pid);
+            if (!pid)
+                goto error;
+            if (PyList_Append(retlist, pid))
+                goto error;
+            Py_DECREF(pid);
+            proclist++;
+        }
+        free(orig_address);
+    }
+    return retlist;
+
+error:
+    Py_XDECREF(pid);
+    Py_DECREF(retlist);
+    if (orig_address != NULL)
+        free(orig_address);
+    return NULL;
+}
+
+
+/*
+ * Return process name from kinfo_proc as a Python string.
+ */
+static PyObject *
+psutil_proc_name(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("s", kp.kp_proc.p_comm);
+}
+
+
+/*
+ * Return process current working directory.
+ */
+static PyObject *
+psutil_proc_cwd(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct proc_vnodepathinfo pathinfo;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+
+    if (! psutil_proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, &pathinfo,
+                              sizeof(pathinfo)))
+    {
+        return NULL;
+    }
+    return Py_BuildValue("s", pathinfo.pvi_cdir.vip_path);
+}
+
+
+/*
+ * Return path of the process executable.
+ */
+static PyObject *
+psutil_proc_exe(PyObject *self, PyObject *args)
+{
+    long pid;
+    char buf[PATH_MAX];
+    int ret;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    ret = proc_pidpath(pid, &buf, sizeof(buf));
+    if (ret == 0) {
+        if (! psutil_pid_exists(pid)) {
+            return NoSuchProcess();
+        }
+        else {
+            return AccessDenied();
+        }
+    }
+    return Py_BuildValue("s", buf);
+}
+
+
+/*
+ * Return process cmdline as a Python list of cmdline arguments.
+ */
+static PyObject *
+psutil_proc_cmdline(PyObject *self, PyObject *args)
+{
+    long pid;
+    PyObject *arglist = NULL;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+
+    // get the commandline, defined in arch/osx/process_info.c
+    arglist = psutil_get_arg_list(pid);
+    return arglist;
+}
+
+
+/*
+ * Return process parent pid from kinfo_proc as a Python integer.
+ */
+static PyObject *
+psutil_proc_ppid(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid);
+}
+
+
+/*
+ * Return process real uid from kinfo_proc as a Python integer.
+ */
+static PyObject *
+psutil_proc_uids(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("lll",
+                         (long)kp.kp_eproc.e_pcred.p_ruid,
+                         (long)kp.kp_eproc.e_ucred.cr_uid,
+                         (long)kp.kp_eproc.e_pcred.p_svuid);
+}
+
+
+/*
+ * Return process real group id from ki_comm as a Python integer.
+ */
+static PyObject *
+psutil_proc_gids(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("lll",
+                         (long)kp.kp_eproc.e_pcred.p_rgid,
+                         (long)kp.kp_eproc.e_ucred.cr_groups[0],
+                         (long)kp.kp_eproc.e_pcred.p_svgid);
+}
+
+
+/*
+ * Return process controlling terminal number as an integer.
+ */
+static PyObject *
+psutil_proc_tty_nr(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("i", kp.kp_eproc.e_tdev);
+}
+
+
+/*
+ * Return a list of tuples for every process memory maps.
+ * 'procstat' cmdline utility has been used as an example.
+ */
+static PyObject *
+psutil_proc_memory_maps(PyObject *self, PyObject *args)
+{
+    char buf[PATH_MAX];
+    char addr_str[34];
+    char perms[8];
+    int pagesize = getpagesize();
+    long pid;
+    kern_return_t err = KERN_SUCCESS;
+    mach_port_t task = MACH_PORT_NULL;
+    uint32_t depth = 1;
+    vm_address_t address = 0;
+    vm_size_t size = 0;
+
+    PyObject *py_tuple = NULL;
+    PyObject *py_list = PyList_New(0);
+
+    if (py_list == NULL)
+        return NULL;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        goto error;
+    }
+
+    err = task_for_pid(mach_task_self(), pid, &task);
+
+    if (err != KERN_SUCCESS) {
+        if (! psutil_pid_exists(pid)) {
+            NoSuchProcess();
+        }
+        else {
+            // pid exists, so return AccessDenied error since task_for_pid()
+            // failed
+            AccessDenied();
+        }
+        goto error;
+    }
+
+    while (1) {
+        py_tuple = NULL;
+        struct vm_region_submap_info_64 info;
+        mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64;
+
+        err = vm_region_recurse_64(task, &address, &size, &depth,
+                                   (vm_region_info_64_t)&info, &count);
+
+        if (err == KERN_INVALID_ADDRESS) {
+            break;
+        }
+
+        if (info.is_submap) {
+            depth++;
+        }
+        else {
+            // Free/Reset the char[]s to avoid weird paths
+            memset(buf, 0, sizeof(buf));
+            memset(addr_str, 0, sizeof(addr_str));
+            memset(perms, 0, sizeof(perms));
+
+            sprintf(addr_str, "%016lx-%016lx", address, address + size);
+            sprintf(perms, "%c%c%c/%c%c%c",
+                    (info.protection & VM_PROT_READ) ? 'r' : '-',
+                    (info.protection & VM_PROT_WRITE) ? 'w' : '-',
+                    (info.protection & VM_PROT_EXECUTE) ? 'x' : '-',
+                    (info.max_protection & VM_PROT_READ) ? 'r' : '-',
+                    (info.max_protection & VM_PROT_WRITE) ? 'w' : '-',
+                    (info.max_protection & VM_PROT_EXECUTE) ? 'x' : '-');
+
+            err = proc_regionfilename(pid, address, buf, sizeof(buf));
+
+            if (info.share_mode == SM_COW && info.ref_count == 1) {
+                // Treat single reference SM_COW as SM_PRIVATE
+                info.share_mode = SM_PRIVATE;
+            }
+
+            if (strlen(buf) == 0) {
+                switch (info.share_mode) {
+                /*
+                case SM_LARGE_PAGE:
+                    // Treat SM_LARGE_PAGE the same as SM_PRIVATE
+                    // since they are not shareable and are wired.
+                */
+                case SM_COW:
+                    strcpy(buf, "[cow]");
+                    break;
+                case SM_PRIVATE:
+                    strcpy(buf, "[prv]");
+                    break;
+                case SM_EMPTY:
+                    strcpy(buf, "[nul]");
+                    break;
+                case SM_SHARED:
+                case SM_TRUESHARED:
+                    strcpy(buf, "[shm]");
+                    break;
+                case SM_PRIVATE_ALIASED:
+                    strcpy(buf, "[ali]");
+                    break;
+                case SM_SHARED_ALIASED:
+                    strcpy(buf, "[s/a]");
+                    break;
+                default:
+                    strcpy(buf, "[???]");
+                }
+            }
+
+            py_tuple = Py_BuildValue(
+                "sssIIIIIH",
+                addr_str,                                 // "start-end"address
+                perms,                                    // "rwx" permissions
+                buf,                                      // path
+                info.pages_resident * pagesize,           // rss
+                info.pages_shared_now_private * pagesize, // private
+                info.pages_swapped_out * pagesize,        // swapped
+                info.pages_dirtied * pagesize,            // dirtied
+                info.ref_count,                           // ref count
+                info.shadow_depth                         // shadow depth
+            );
+            if (!py_tuple)
+                goto error;
+            if (PyList_Append(py_list, py_tuple))
+                goto error;
+            Py_DECREF(py_tuple);
+        }
+
+        // increment address for the next map/file
+        address += size;
+    }
+
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
+
+    return py_list;
+
+error:
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
+    Py_XDECREF(py_tuple);
+    Py_DECREF(py_list);
+    return NULL;
+}
+
+
+/*
+ * Return the number of logical CPUs in the system.
+ * XXX this could be shared with BSD.
+ */
+static PyObject *
+psutil_cpu_count_logical(PyObject *self, PyObject *args)
+{
+    int mib[2];
+    int ncpu;
+    size_t len;
+
+    mib[0] = CTL_HW;
+    mib[1] = HW_NCPU;
+    len = sizeof(ncpu);
+
+    if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) {
+        // mimic os.cpu_count()
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    else {
+        return Py_BuildValue("i", ncpu);
+    }
+}
+
+
+/*
+ * Return the number of physical CPUs in the system.
+ */
+static PyObject *
+psutil_cpu_count_phys(PyObject *self, PyObject *args)
+{
+    int num;
+    size_t size = sizeof(int);
+    if (sysctlbyname("hw.physicalcpu", &num, &size, NULL, 0)) {
+        // mimic os.cpu_count()
+        Py_INCREF(Py_None);
+        return Py_None;
+    }
+    return Py_BuildValue("i", num);
+}
+
+
+#define TV2DOUBLE(t)    ((t).tv_sec + (t).tv_usec / 1000000.0)
+
+/*
+ * Return a Python tuple (user_time, kernel_time)
+ */
+static PyObject *
+psutil_proc_cpu_times(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct proc_taskinfo pti;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
+        return NULL;
+    }
+    return Py_BuildValue("(dd)",
+                         (float)pti.pti_total_user / 1000000000.0,
+                         (float)pti.pti_total_system / 1000000000.0);
+}
+
+
+/*
+ * Return a Python float indicating the process create time expressed in
+ * seconds since the epoch.
+ */
+static PyObject *
+psutil_proc_create_time(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime));
+}
+
+
+/*
+ * Return extended memory info about a process.
+ */
+static PyObject *
+psutil_proc_memory_info(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct proc_taskinfo pti;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
+        return NULL;
+    }
+
+    // Note: determining other memory stats on OSX is a mess:
+    // http://www.opensource.apple.com/source/top/top-67/libtop.c?txt
+    // I just give up...
+    // struct proc_regioninfo pri;
+    // psutil_proc_pidinfo(pid, PROC_PIDREGIONINFO, &pri, sizeof(pri))
+    return Py_BuildValue(
+        "(KKkk)",
+        pti.pti_resident_size,  // resident memory size (rss)
+        pti.pti_virtual_size,   // virtual memory size (vms)
+        pti.pti_faults,         // number of page faults (pages)
+        pti.pti_pageins         // number of actual pageins (pages)
+    );
+}
+
+
+/*
+ * Return number of threads used by process as a Python integer.
+ */
+static PyObject *
+psutil_proc_num_threads(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct proc_taskinfo pti;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
+        return NULL;
+    }
+    return Py_BuildValue("k", pti.pti_threadnum);
+}
+
+
+/*
+ * Return the number of context switches performed by process.
+ */
+static PyObject *
+psutil_proc_num_ctx_switches(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct proc_taskinfo pti;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (! psutil_proc_pidinfo(pid, PROC_PIDTASKINFO, &pti, sizeof(pti))) {
+        return NULL;
+    }
+    // unvoluntary value seems not to be available;
+    // pti.pti_csw probably refers to the sum of the two (getrusage()
+    // numbers seems to confirm this theory).
+    return Py_BuildValue("ki", pti.pti_csw, 0);
+}
+
+
+/*
+ * Return system virtual memory stats
+ */
+static PyObject *
+psutil_virtual_mem(PyObject *self, PyObject *args)
+{
+
+    int      mib[2];
+    uint64_t total;
+    size_t   len = sizeof(total);
+    vm_statistics_data_t vm;
+    int pagesize = getpagesize();
+
+    // physical mem
+    mib[0] = CTL_HW;
+    mib[1] = HW_MEMSIZE;
+    if (sysctl(mib, 2, &total, &len, NULL, 0)) {
+        if (errno != 0)
+            PyErr_SetFromErrno(PyExc_OSError);
+        else
+            PyErr_Format(PyExc_RuntimeError, "sysctl(HW_MEMSIZE) failed");
+        return NULL;
+    }
+
+    // vm
+    if (!psutil_sys_vminfo(&vm)) {
+        return NULL;
+    }
+
+    return Py_BuildValue(
+        "KKKKK",
+        total,
+        (unsigned long long) vm.active_count * pagesize,
+        (unsigned long long) vm.inactive_count * pagesize,
+        (unsigned long long) vm.wire_count * pagesize,
+        (unsigned long long) vm.free_count * pagesize
+    );
+}
+
+
+/*
+ * Return stats about swap memory.
+ */
+static PyObject *
+psutil_swap_mem(PyObject *self, PyObject *args)
+{
+    int mib[2];
+    size_t size;
+    struct xsw_usage totals;
+    vm_statistics_data_t vmstat;
+    int pagesize = getpagesize();
+
+    mib[0] = CTL_VM;
+    mib[1] = VM_SWAPUSAGE;
+    size = sizeof(totals);
+    if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) {
+        if (errno != 0)
+            PyErr_SetFromErrno(PyExc_OSError);
+        else
+            PyErr_Format(PyExc_RuntimeError, "sysctl(VM_SWAPUSAGE) failed");
+        return NULL;
+    }
+    if (!psutil_sys_vminfo(&vmstat)) {
+        return NULL;
+    }
+
+    return Py_BuildValue(
+        "LLLKK",
+        totals.xsu_total,
+        totals.xsu_used,
+        totals.xsu_avail,
+        (unsigned long long)vmstat.pageins * pagesize,
+        (unsigned long long)vmstat.pageouts * pagesize);
+}
+
+
+/*
+ * Return a Python tuple representing user, kernel and idle CPU times
+ */
+static PyObject *
+psutil_cpu_times(PyObject *self, PyObject *args)
+{
+    mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+    kern_return_t error;
+    host_cpu_load_info_data_t r_load;
+
+    mach_port_t host_port = mach_host_self();
+    error = host_statistics(host_port, HOST_CPU_LOAD_INFO,
+                            (host_info_t)&r_load, &count);
+    if (error != KERN_SUCCESS) {
+        return PyErr_Format(PyExc_RuntimeError,
+                            "Error in host_statistics(): %s",
+                            mach_error_string(error));
+    }
+    mach_port_deallocate(mach_task_self(), host_port);
+
+    return Py_BuildValue(
+        "(dddd)",
+        (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
+        (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
+        (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
+        (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
+    );
+}
+
+
+/*
+ * Return a Python list of tuple representing per-cpu times
+ */
+static PyObject *
+psutil_per_cpu_times(PyObject *self, PyObject *args)
+{
+    natural_t cpu_count;
+    processor_info_array_t info_array;
+    mach_msg_type_number_t info_count;
+    kern_return_t error;
+    processor_cpu_load_info_data_t *cpu_load_info = NULL;
+    int i, ret;
+    PyObject *py_retlist = PyList_New(0);
+    PyObject *py_cputime = NULL;
+
+    if (py_retlist == NULL)
+        return NULL;
+
+    mach_port_t host_port = mach_host_self();
+    error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO,
+                                &cpu_count, &info_array, &info_count);
+    if (error != KERN_SUCCESS) {
+        PyErr_Format(PyExc_RuntimeError, "Error in host_processor_info(): %s",
+                     mach_error_string(error));
+        goto error;
+    }
+    mach_port_deallocate(mach_task_self(), host_port);
+
+    cpu_load_info = (processor_cpu_load_info_data_t *) info_array;
+
+    for (i = 0; i < cpu_count; i++) {
+        py_cputime = Py_BuildValue(
+            "(dddd)",
+            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK,
+            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
+            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
+            (double)cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
+        );
+        if (!py_cputime)
+            goto error;
+        if (PyList_Append(py_retlist, py_cputime))
+            goto error;
+        Py_DECREF(py_cputime);
+    }
+
+    ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
+                        info_count * sizeof(int));
+    if (ret != KERN_SUCCESS) {
+        PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+    }
+    return py_retlist;
+
+error:
+    Py_XDECREF(py_cputime);
+    Py_DECREF(py_retlist);
+    if (cpu_load_info != NULL) {
+        ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array,
+                            info_count * sizeof(int));
+        if (ret != KERN_SUCCESS) {
+            PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+        }
+    }
+    return NULL;
+}
+
+
+/*
+ * Return a Python float indicating the system boot time expressed in
+ * seconds since the epoch.
+ */
+static PyObject *
+psutil_boot_time(PyObject *self, PyObject *args)
+{
+    // fetch sysctl "kern.boottime"
+    static int request[2] = { CTL_KERN, KERN_BOOTTIME };
+    struct timeval result;
+    size_t result_len = sizeof result;
+    time_t boot_time = 0;
+
+    if (sysctl(request, 2, &result, &result_len, NULL, 0) == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        return NULL;
+    }
+    boot_time = result.tv_sec;
+    return Py_BuildValue("f", (float)boot_time);
+}
+
+
+/*
+ * Return a list of tuples including device, mount point and fs type
+ * for all partitions mounted on the system.
+ */
+static PyObject *
+psutil_disk_partitions(PyObject *self, PyObject *args)
+{
+    int num;
+    int i;
+    long len;
+    uint64_t flags;
+    char opts[400];
+    struct statfs *fs = NULL;
+    PyObject *py_retlist = PyList_New(0);
+    PyObject *py_tuple = NULL;
+
+    if (py_retlist == NULL)
+        return NULL;
+
+    // get the number of mount points
+    Py_BEGIN_ALLOW_THREADS
+    num = getfsstat(NULL, 0, MNT_NOWAIT);
+    Py_END_ALLOW_THREADS
+    if (num == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    len = sizeof(*fs) * num;
+    fs = malloc(len);
+    if (fs == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+
+    Py_BEGIN_ALLOW_THREADS
+    num = getfsstat(fs, len, MNT_NOWAIT);
+    Py_END_ALLOW_THREADS
+    if (num == -1) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    for (i = 0; i < num; i++) {
+        opts[0] = 0;
+        flags = fs[i].f_flags;
+
+        // see sys/mount.h
+        if (flags & MNT_RDONLY)
+            strlcat(opts, "ro", sizeof(opts));
+        else
+            strlcat(opts, "rw", sizeof(opts));
+        if (flags & MNT_SYNCHRONOUS)
+            strlcat(opts, ",sync", sizeof(opts));
+        if (flags & MNT_NOEXEC)
+            strlcat(opts, ",noexec", sizeof(opts));
+        if (flags & MNT_NOSUID)
+            strlcat(opts, ",nosuid", sizeof(opts));
+        if (flags & MNT_UNION)
+            strlcat(opts, ",union", sizeof(opts));
+        if (flags & MNT_ASYNC)
+            strlcat(opts, ",async", sizeof(opts));
+        if (flags & MNT_EXPORTED)
+            strlcat(opts, ",exported", sizeof(opts));
+        if (flags & MNT_QUARANTINE)
+            strlcat(opts, ",quarantine", sizeof(opts));
+        if (flags & MNT_LOCAL)
+            strlcat(opts, ",local", sizeof(opts));
+        if (flags & MNT_QUOTA)
+            strlcat(opts, ",quota", sizeof(opts));
+        if (flags & MNT_ROOTFS)
+            strlcat(opts, ",rootfs", sizeof(opts));
+        if (flags & MNT_DOVOLFS)
+            strlcat(opts, ",dovolfs", sizeof(opts));
+        if (flags & MNT_DONTBROWSE)
+            strlcat(opts, ",dontbrowse", sizeof(opts));
+        if (flags & MNT_IGNORE_OWNERSHIP)
+            strlcat(opts, ",ignore-ownership", sizeof(opts));
+        if (flags & MNT_AUTOMOUNTED)
+            strlcat(opts, ",automounted", sizeof(opts));
+        if (flags & MNT_JOURNALED)
+            strlcat(opts, ",journaled", sizeof(opts));
+        if (flags & MNT_NOUSERXATTR)
+            strlcat(opts, ",nouserxattr", sizeof(opts));
+        if (flags & MNT_DEFWRITE)
+            strlcat(opts, ",defwrite", sizeof(opts));
+        if (flags & MNT_MULTILABEL)
+            strlcat(opts, ",multilabel", sizeof(opts));
+        if (flags & MNT_NOATIME)
+            strlcat(opts, ",noatime", sizeof(opts));
+        if (flags & MNT_UPDATE)
+            strlcat(opts, ",update", sizeof(opts));
+        if (flags & MNT_RELOAD)
+            strlcat(opts, ",reload", sizeof(opts));
+        if (flags & MNT_FORCE)
+            strlcat(opts, ",force", sizeof(opts));
+        if (flags & MNT_CMDFLAGS)
+            strlcat(opts, ",cmdflags", sizeof(opts));
+
+        py_tuple = Py_BuildValue(
+            "(ssss)", fs[i].f_mntfromname,  // device
+            fs[i].f_mntonname,    // mount point
+            fs[i].f_fstypename,   // fs type
+            opts);                // options
+        if (!py_tuple)
+            goto error;
+        if (PyList_Append(py_retlist, py_tuple))
+            goto error;
+        Py_DECREF(py_tuple);
+    }
+
+    free(fs);
+    return py_retlist;
+
+error:
+    Py_XDECREF(py_tuple);
+    Py_DECREF(py_retlist);
+    if (fs != NULL)
+        free(fs);
+    return NULL;
+}
+
+
+/*
+ * Return process status as a Python integer.
+ */
+static PyObject *
+psutil_proc_status(PyObject *self, PyObject *args)
+{
+    long pid;
+    struct kinfo_proc kp;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
+        return NULL;
+    }
+    return Py_BuildValue("i", (int)kp.kp_proc.p_stat);
+}
+
+
+/*
+ * Return process threads
+ */
+static PyObject *
+psutil_proc_threads(PyObject *self, PyObject *args)
+{
+    long pid;
+    int err, j, ret;
+    kern_return_t kr;
+    unsigned int info_count = TASK_BASIC_INFO_COUNT;
+    mach_port_t task = MACH_PORT_NULL;
+    struct task_basic_info tasks_info;
+    thread_act_port_array_t thread_list = NULL;
+    thread_info_data_t thinfo_basic;
+    thread_basic_info_t basic_info_th;
+    mach_msg_type_number_t thread_count, thread_info_count;
+
+    PyObject *retList = PyList_New(0);
+    PyObject *pyTuple = NULL;
+
+    if (retList == NULL)
+        return NULL;
+
+    // the argument passed should be a process id
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        goto error;
+    }
+
+    // task_for_pid() requires special privileges
+    err = task_for_pid(mach_task_self(), pid, &task);
+    if (err != KERN_SUCCESS) {
+        if (! psutil_pid_exists(pid)) {
+            NoSuchProcess();
+        }
+        else {
+            AccessDenied();
+        }
+        goto error;
+    }
+
+    info_count = TASK_BASIC_INFO_COUNT;
+    err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info,
+                    &info_count);
+    if (err != KERN_SUCCESS) {
+        // errcode 4 is "invalid argument" (access denied)
+        if (err == 4) {
+            AccessDenied();
+        }
+        else {
+            // otherwise throw a runtime error with appropriate error code
+            PyErr_Format(PyExc_RuntimeError,
+                         "task_info(TASK_BASIC_INFO) failed");
+        }
+        goto error;
+    }
+
+    err = task_threads(task, &thread_list, &thread_count);
+    if (err != KERN_SUCCESS) {
+        PyErr_Format(PyExc_RuntimeError, "task_threads() failed");
+        goto error;
+    }
+
+    for (j = 0; j < thread_count; j++) {
+        pyTuple = NULL;
+        thread_info_count = THREAD_INFO_MAX;
+        kr = thread_info(thread_list[j], THREAD_BASIC_INFO,
+                         (thread_info_t)thinfo_basic, &thread_info_count);
+        if (kr != KERN_SUCCESS) {
+            PyErr_Format(PyExc_RuntimeError,
+                         "thread_info() with flag THREAD_BASIC_INFO failed");
+            goto error;
+        }
+
+        basic_info_th = (thread_basic_info_t)thinfo_basic;
+        pyTuple = Py_BuildValue(
+            "Iff",
+            j + 1,
+            (float)basic_info_th->user_time.microseconds / 1000000.0,
+            (float)basic_info_th->system_time.microseconds / 1000000.0
+        );
+        if (!pyTuple)
+            goto error;
+        if (PyList_Append(retList, pyTuple))
+            goto error;
+        Py_DECREF(pyTuple);
+    }
+
+    ret = vm_deallocate(task, (vm_address_t)thread_list,
+                        thread_count * sizeof(int));
+    if (ret != KERN_SUCCESS) {
+        PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+    }
+
+    mach_port_deallocate(mach_task_self(), task);
+
+    return retList;
+
+error:
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
+    Py_XDECREF(pyTuple);
+    Py_DECREF(retList);
+    if (thread_list != NULL) {
+        ret = vm_deallocate(task, (vm_address_t)thread_list,
+                            thread_count * sizeof(int));
+        if (ret != KERN_SUCCESS) {
+            PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
+        }
+    }
+    return NULL;
+}
+
+
+/*
+ * Return process open files as a Python tuple.
+ * References:
+ * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/m78fd
+ * - /usr/include/sys/proc_info.h
+ */
+static PyObject *
+psutil_proc_open_files(PyObject *self, PyObject *args)
+{
+    long pid;
+    int pidinfo_result;
+    int iterations;
+    int i;
+    int nb;
+
+    struct proc_fdinfo *fds_pointer = NULL;
+    struct proc_fdinfo *fdp_pointer;
+    struct vnode_fdinfowithpath vi;
+
+    PyObject *retList = PyList_New(0);
+    PyObject *tuple = NULL;
+
+    if (retList == NULL)
+        return NULL;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        goto error;
+    }
+
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+    if (pidinfo_result <= 0) {
+        // may be be ignored later if errno != 0
+        PyErr_Format(PyExc_RuntimeError,
+                     "proc_pidinfo(PROC_PIDLISTFDS) failed");
+        goto error;
+    }
+
+    fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
+                                  pidinfo_result);
+    if (pidinfo_result <= 0) {
+        // may be be ignored later if errno != 0
+        PyErr_Format(PyExc_RuntimeError,
+                     "proc_pidinfo(PROC_PIDLISTFDS) failed");
+        goto error;
+    }
+
+    iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
+
+    for (i = 0; i < iterations; i++) {
+        tuple = NULL;
+        fdp_pointer = &fds_pointer[i];
+
+        if (fdp_pointer->proc_fdtype == PROX_FDTYPE_VNODE)
+        {
+            nb = proc_pidfdinfo(pid,
+                                fdp_pointer->proc_fd,
+                                PROC_PIDFDVNODEPATHINFO,
+                                &vi,
+                                sizeof(vi));
+
+            // --- errors checking
+            if (nb <= 0) {
+                if ((errno == ENOENT) || (errno == EBADF)) {
+                    // no such file or directory or bad file descriptor;
+                    // let's assume the file has been closed or removed
+                    continue;
+                }
+                // may be be ignored later if errno != 0
+                PyErr_Format(PyExc_RuntimeError,
+                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
+                goto error;
+            }
+            if (nb < sizeof(vi)) {
+                PyErr_Format(PyExc_RuntimeError,
+                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
+                             "(buffer mismatch)");
+                goto error;
+            }
+            // --- /errors checking
+
+            // --- construct python list
+            tuple = Py_BuildValue("(si)",
+                                  vi.pvip.vip_path,
+                                  (int)fdp_pointer->proc_fd);
+            if (!tuple)
+                goto error;
+            if (PyList_Append(retList, tuple))
+                goto error;
+            Py_DECREF(tuple);
+            // --- /construct python list
+        }
+    }
+
+    free(fds_pointer);
+    return retList;
+
+error:
+    Py_XDECREF(tuple);
+    Py_DECREF(retList);
+    if (fds_pointer != NULL) {
+        free(fds_pointer);
+    }
+    if (errno != 0) {
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+    else if (! psutil_pid_exists(pid)) {
+        return NoSuchProcess();
+    }
+    else {
+        // exception has already been set earlier
+        return NULL;
+    }
+}
+
+
+// a signaler for connections without an actual status
+static int PSUTIL_CONN_NONE = 128;
+
+/*
+ * Return process TCP and UDP connections as a list of tuples.
+ * References:
+ * - lsof source code: http://goo.gl/SYW79 and http://goo.gl/wNrC0
+ * - /usr/include/sys/proc_info.h
+ */
+static PyObject *
+psutil_proc_connections(PyObject *self, PyObject *args)
+{
+    long pid;
+    int pidinfo_result;
+    int iterations;
+    int i;
+    int nb;
+
+    struct proc_fdinfo *fds_pointer = NULL;
+    struct proc_fdinfo *fdp_pointer;
+    struct socket_fdinfo si;
+
+    PyObject *retList = PyList_New(0);
+    PyObject *tuple = NULL;
+    PyObject *laddr = NULL;
+    PyObject *raddr = NULL;
+    PyObject *af_filter = NULL;
+    PyObject *type_filter = NULL;
+
+    if (retList == NULL)
+        return NULL;
+
+    if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
+        goto error;
+    }
+
+    if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
+        PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
+        goto error;
+    }
+
+    if (pid == 0) {
+        return retList;
+    }
+
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+    if (pidinfo_result <= 0) {
+        goto error;
+    }
+
+    fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
+                                  pidinfo_result);
+
+    if (pidinfo_result <= 0) {
+        goto error;
+    }
+
+    iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
+
+    for (i = 0; i < iterations; i++) {
+        tuple = NULL;
+        laddr = NULL;
+        raddr = NULL;
+        errno = 0;
+        fdp_pointer = &fds_pointer[i];
+
+        if (fdp_pointer->proc_fdtype == PROX_FDTYPE_SOCKET)
+        {
+            nb = proc_pidfdinfo(pid, fdp_pointer->proc_fd,
+                                PROC_PIDFDSOCKETINFO, &si, sizeof(si));
+
+            // --- errors checking
+            if (nb <= 0) {
+                if (errno == EBADF) {
+                    // let's assume socket has been closed
+                    continue;
+                }
+                if (errno != 0) {
+                    PyErr_SetFromErrno(PyExc_OSError);
+                }
+                else {
+                    PyErr_Format(
+                        PyExc_RuntimeError,
+                        "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed");
+                }
+                goto error;
+            }
+            if (nb < sizeof(si)) {
+                PyErr_Format(PyExc_RuntimeError,
+                             "proc_pidinfo(PROC_PIDFDVNODEPATHINFO) failed "
+                             "(buffer mismatch)");
+                goto error;
+            }
+            // --- /errors checking
+
+            //
+            int fd, family, type, lport, rport, state;
+            char lip[200], rip[200];
+            int inseq;
+            PyObject *_family;
+            PyObject *_type;
+
+            fd = (int)fdp_pointer->proc_fd;
+            family = si.psi.soi_family;
+            type = si.psi.soi_type;
+
+            // apply filters
+            _family = PyLong_FromLong((long)family);
+            inseq = PySequence_Contains(af_filter, _family);
+            Py_DECREF(_family);
+            if (inseq == 0) {
+                continue;
+            }
+            _type = PyLong_FromLong((long)type);
+            inseq = PySequence_Contains(type_filter, _type);
+            Py_DECREF(_type);
+            if (inseq == 0) {
+                continue;
+            }
+
+            if (errno != 0) {
+                PyErr_SetFromErrno(PyExc_OSError);
+                goto error;
+            }
+
+            if ((family == AF_INET) || (family == AF_INET6)) {
+                if (family == AF_INET) {
+                    inet_ntop(AF_INET,
+                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
+                                  insi_laddr.ina_46.i46a_addr4,
+                              lip,
+                              sizeof(lip));
+                    inet_ntop(AF_INET,
+                              &si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_faddr. \
+                                  ina_46.i46a_addr4,
+                              rip,
+                              sizeof(rip));
+                }
+                else {
+                    inet_ntop(AF_INET6,
+                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
+                                  insi_laddr.ina_6,
+                              lip, sizeof(lip));
+                    inet_ntop(AF_INET6,
+                              &si.psi.soi_proto.pri_tcp.tcpsi_ini. \
+                                  insi_faddr.ina_6,
+                              rip, sizeof(rip));
+                }
+
+                // check for inet_ntop failures
+                if (errno != 0) {
+                    PyErr_SetFromErrno(PyExc_OSError);
+                    goto error;
+                }
+
+                lport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_lport);
+                rport = ntohs(si.psi.soi_proto.pri_tcp.tcpsi_ini.insi_fport);
+                if (type == SOCK_STREAM) {
+                    state = (int)si.psi.soi_proto.pri_tcp.tcpsi_state;
+                }
+                else {
+                    state = PSUTIL_CONN_NONE;
+                }
+
+                laddr = Py_BuildValue("(si)", lip, lport);
+                if (!laddr)
+                    goto error;
+                if (rport != 0) {
+                    raddr = Py_BuildValue("(si)", rip, rport);
+                }
+                else {
+                    raddr = Py_BuildValue("()");
+                }
+                if (!raddr)
+                    goto error;
+
+                // construct the python list
+                tuple = Py_BuildValue("(iiiNNi)", fd, family, type, laddr,
+                                      raddr, state);
+                if (!tuple)
+                    goto error;
+                if (PyList_Append(retList, tuple))
+                    goto error;
+                Py_DECREF(tuple);
+            }
+            else if (family == AF_UNIX) {
+                // construct the python list
+                tuple = Py_BuildValue(
+                    "(iiissi)",
+                    fd, family, type,
+                    si.psi.soi_proto.pri_un.unsi_addr.ua_sun.sun_path,
+                    si.psi.soi_proto.pri_un.unsi_caddr.ua_sun.sun_path,
+                    PSUTIL_CONN_NONE);
+                if (!tuple)
+                    goto error;
+                if (PyList_Append(retList, tuple))
+                    goto error;
+                Py_DECREF(tuple);
+            }
+        }
+    }
+
+    free(fds_pointer);
+    return retList;
+
+error:
+    Py_XDECREF(tuple);
+    Py_XDECREF(laddr);
+    Py_XDECREF(raddr);
+    Py_DECREF(retList);
+
+    if (fds_pointer != NULL) {
+        free(fds_pointer);
+    }
+    if (errno != 0) {
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+    else if (! psutil_pid_exists(pid) ) {
+        return NoSuchProcess();
+    }
+    else {
+        return PyErr_Format(PyExc_RuntimeError,
+                            "proc_pidinfo(PROC_PIDLISTFDS) failed");
+    }
+}
+
+
+/*
+ * Return number of file descriptors opened by process.
+ */
+static PyObject *
+psutil_proc_num_fds(PyObject *self, PyObject *args)
+{
+    long pid;
+    int pidinfo_result;
+    int num;
+    struct proc_fdinfo *fds_pointer;
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+    if (pidinfo_result <= 0) {
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+
+    fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        return PyErr_NoMemory();
+    }
+    pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
+                                  pidinfo_result);
+    if (pidinfo_result <= 0) {
+        free(fds_pointer);
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+
+    num = (pidinfo_result / PROC_PIDLISTFD_SIZE);
+    free(fds_pointer);
+    return Py_BuildValue("i", num);
+}
+
+
+/*
+ * Return a Python list of named tuples with overall network I/O information
+ */
+static PyObject *
+psutil_net_io_counters(PyObject *self, PyObject *args)
+{
+    char *buf = NULL, *lim, *next;
+    struct if_msghdr *ifm;
+    int mib[6];
+    size_t len;
+    PyObject *py_retdict = PyDict_New();
+    PyObject *py_ifc_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
+
+    mib[0] = CTL_NET;          // networking subsystem
+    mib[1] = PF_ROUTE;         // type of information
+    mib[2] = 0;                // protocol (IPPROTO_xxx)
+    mib[3] = 0;                // address family
+    mib[4] = NET_RT_IFLIST2;   // operation
+    mib[5] = 0;
+
+    if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    buf = malloc(len);
+    if (buf == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+
+    if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
+        PyErr_SetFromErrno(PyExc_OSError);
+        goto error;
+    }
+
+    lim = buf + len;
+
+    for (next = buf; next < lim; ) {
+        ifm = (struct if_msghdr *)next;
+        next += ifm->ifm_msglen;
+
+        if (ifm->ifm_type == RTM_IFINFO2) {
+            py_ifc_info = NULL;
+            struct if_msghdr2 *if2m = (struct if_msghdr2 *)ifm;
+            struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
+            char ifc_name[32];
+
+            strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
+            ifc_name[sdl->sdl_nlen] = 0;
+
+            py_ifc_info = Py_BuildValue(
+                "(KKKKKKKi)",
+                if2m->ifm_data.ifi_obytes,
+                if2m->ifm_data.ifi_ibytes,
+                if2m->ifm_data.ifi_opackets,
+                if2m->ifm_data.ifi_ipackets,
+                if2m->ifm_data.ifi_ierrors,
+                if2m->ifm_data.ifi_oerrors,
+                if2m->ifm_data.ifi_iqdrops,
+                0);  // dropout not supported
+
+            if (!py_ifc_info)
+                goto error;
+            if (PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info))
+                goto error;
+            Py_DECREF(py_ifc_info);
+        }
+        else {
+            continue;
+        }
+    }
+
+    free(buf);
+    return py_retdict;
+
+error:
+    Py_XDECREF(py_ifc_info);
+    Py_DECREF(py_retdict);
+    if (buf != NULL)
+        free(buf);
+    return NULL;
+}
+
+
+/*
+ * Return a Python dict of tuples for disk I/O information
+ */
+static PyObject *
+psutil_disk_io_counters(PyObject *self, PyObject *args)
+{
+    CFDictionaryRef parent_dict;
+    CFDictionaryRef props_dict;
+    CFDictionaryRef stats_dict;
+    io_registry_entry_t parent;
+    io_registry_entry_t disk;
+    io_iterator_t disk_list;
+    PyObject *py_retdict = PyDict_New();
+    PyObject *py_disk_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
+
+    // Get list of disks
+    if (IOServiceGetMatchingServices(kIOMasterPortDefault,
+                                     IOServiceMatching(kIOMediaClass),
+                                     &disk_list) != kIOReturnSuccess) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "unable to get the list of disks.");
+        goto error;
+    }
+
+    // Iterate over disks
+    while ((disk = IOIteratorNext(disk_list)) != 0) {
+        py_disk_info = NULL;
+        parent_dict = NULL;
+        props_dict = NULL;
+        stats_dict = NULL;
+
+        if (IORegistryEntryGetParentEntry(disk, kIOServicePlane, &parent)
+                != kIOReturnSuccess) {
+            PyErr_SetString(PyExc_RuntimeError,
+                            "unable to get the disk's parent.");
+            IOObjectRelease(disk);
+            goto error;
+        }
+
+        if (IOObjectConformsTo(parent, "IOBlockStorageDriver")) {
+            if (IORegistryEntryCreateCFProperties(
+                    disk,
+                    (CFMutableDictionaryRef *) &parent_dict,
+                    kCFAllocatorDefault,
+                    kNilOptions
+                ) != kIOReturnSuccess)
+            {
+                PyErr_SetString(PyExc_RuntimeError,
+                                "unable to get the parent's properties.");
+                IOObjectRelease(disk);
+                IOObjectRelease(parent);
+                goto error;
+            }
+
+            if (IORegistryEntryCreateCFProperties(
+                    parent,
+                    (CFMutableDictionaryRef *) &props_dict,
+                    kCFAllocatorDefault,
+                    kNilOptions
+                ) != kIOReturnSuccess)
+            {
+                PyErr_SetString(PyExc_RuntimeError,
+                                "unable to get the disk properties.");
+                CFRelease(props_dict);
+                IOObjectRelease(disk);
+                IOObjectRelease(parent);
+                goto error;
+            }
+
+            const int kMaxDiskNameSize = 64;
+            CFStringRef disk_name_ref = (CFStringRef)CFDictionaryGetValue(
+                parent_dict, CFSTR(kIOBSDNameKey));
+            char disk_name[kMaxDiskNameSize];
+
+            CFStringGetCString(disk_name_ref,
+                               disk_name,
+                               kMaxDiskNameSize,
+                               CFStringGetSystemEncoding());
+
+            stats_dict = (CFDictionaryRef)CFDictionaryGetValue(
+                props_dict, CFSTR(kIOBlockStorageDriverStatisticsKey));
+
+            if (stats_dict == NULL) {
+                PyErr_SetString(PyExc_RuntimeError,
+                                "Unable to get disk stats.");
+                goto error;
+            }
+
+            CFNumberRef number;
+            int64_t reads = 0;
+            int64_t writes = 0;
+            int64_t read_bytes = 0;
+            int64_t write_bytes = 0;
+            int64_t read_time = 0;
+            int64_t write_time = 0;
+
+            // Get disk reads/writes
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsReadsKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &reads);
+            }
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsWritesKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &writes);
+            }
+
+            // Get disk bytes read/written
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &read_bytes);
+            }
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &write_bytes);
+            }
+
+            // Get disk time spent reading/writing (nanoseconds)
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsTotalReadTimeKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &read_time);
+            }
+            if ((number = (CFNumberRef)CFDictionaryGetValue(
+                    stats_dict,
+                    CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey))))
+            {
+                CFNumberGetValue(number, kCFNumberSInt64Type, &write_time);
+            }
+
+            // Read/Write time on OS X comes back in nanoseconds and in psutil
+            // we've standardized on milliseconds so do the conversion.
+            py_disk_info = Py_BuildValue(
+                "(KKKKKK)",
+                reads,
+                writes,
+                read_bytes,
+                write_bytes,
+                read_time / 1000 / 1000,
+                write_time / 1000 / 1000);
+           if (!py_disk_info)
+                goto error;
+            if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
+                goto error;
+            Py_DECREF(py_disk_info);
+
+            CFRelease(parent_dict);
+            IOObjectRelease(parent);
+            CFRelease(props_dict);
+            IOObjectRelease(disk);
+        }
+    }
+
+    IOObjectRelease (disk_list);
+
+    return py_retdict;
+
+error:
+    Py_XDECREF(py_disk_info);
+    Py_DECREF(py_retdict);
+    return NULL;
+}
+
+
+/*
+ * Return currently connected users as a list of tuples.
+ */
+static PyObject *
+psutil_users(PyObject *self, PyObject *args)
+{
+    struct utmpx *utx;
+    PyObject *ret_list = PyList_New(0);
+    PyObject *tuple = NULL;
+
+    if (ret_list == NULL)
+        return NULL;
+    while ((utx = getutxent()) != NULL) {
+        if (utx->ut_type != USER_PROCESS)
+            continue;
+        tuple = Py_BuildValue(
+            "(sssf)",
+            utx->ut_user,             // username
+            utx->ut_line,             // tty
+            utx->ut_host,             // hostname
+            (float)utx->ut_tv.tv_sec  // start time
+        );
+        if (!tuple) {
+            endutxent();
+            goto error;
+        }
+        if (PyList_Append(ret_list, tuple)) {
+            endutxent();
+            goto error;
+        }
+        Py_DECREF(tuple);
+    }
+
+    endutxent();
+    return ret_list;
+
+error:
+    Py_XDECREF(tuple);
+    Py_DECREF(ret_list);
+    return NULL;
+}
+
+
+/*
+ * define the psutil C module methods and initialize the module.
+ */
+static PyMethodDef
+PsutilMethods[] =
+{
+    // --- per-process functions
+
+    {"proc_name", psutil_proc_name, METH_VARARGS,
+     "Return process name"},
+    {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS,
+     "Return process cmdline as a list of cmdline arguments"},
+    {"proc_exe", psutil_proc_exe, METH_VARARGS,
+     "Return path of the process executable"},
+    {"proc_cwd", psutil_proc_cwd, METH_VARARGS,
+     "Return process current working directory."},
+    {"proc_ppid", psutil_proc_ppid, METH_VARARGS,
+     "Return process ppid as an integer"},
+    {"proc_uids", psutil_proc_uids, METH_VARARGS,
+     "Return process real user id as an integer"},
+    {"proc_gids", psutil_proc_gids, METH_VARARGS,
+     "Return process real group id as an integer"},
+    {"proc_cpu_times", psutil_proc_cpu_times, METH_VARARGS,
+     "Return tuple of user/kern time for the given PID"},
+    {"proc_create_time", psutil_proc_create_time, METH_VARARGS,
+     "Return a float indicating the process create time expressed in "
+     "seconds since the epoch"},
+    {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS,
+     "Return memory information about a process"},
+    {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS,
+     "Return number of threads used by process"},
+    {"proc_status", psutil_proc_status, METH_VARARGS,
+     "Return process status as an integer"},
+    {"proc_threads", psutil_proc_threads, METH_VARARGS,
+     "Return process threads as a list of tuples"},
+    {"proc_open_files", psutil_proc_open_files, METH_VARARGS,
+     "Return files opened by process as a list of tuples"},
+    {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS,
+     "Return the number of fds opened by process."},
+    {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS,
+     "Return the number of context switches performed by process"},
+    {"proc_connections", psutil_proc_connections, METH_VARARGS,
+     "Get process TCP and UDP connections as a list of tuples"},
+    {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS,
+     "Return process tty number as an integer"},
+    {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS,
+     "Return a list of tuples for every process's memory map"},
+
+    // --- system-related functions
+
+    {"pids", psutil_pids, METH_VARARGS,
+     "Returns a list of PIDs currently running on the system"},
+    {"cpu_count_logical", psutil_cpu_count_logical, METH_VARARGS,
+     "Return number of logical CPUs on the system"},
+    {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS,
+     "Return number of physical CPUs on the system"},
+    {"virtual_mem", psutil_virtual_mem, METH_VARARGS,
+     "Return system virtual memory stats"},
+    {"swap_mem", psutil_swap_mem, METH_VARARGS,
+     "Return stats about swap memory, in bytes"},
+    {"cpu_times", psutil_cpu_times, METH_VARARGS,
+     "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
+    {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS,
+     "Return system per-cpu times as a list of tuples"},
+    {"boot_time", psutil_boot_time, METH_VARARGS,
+     "Return the system boot time expressed in seconds since the epoch."},
+    {"disk_partitions", psutil_disk_partitions, METH_VARARGS,
+     "Return a list of tuples including device, mount point and "
+     "fs type for all partitions mounted on the system."},
+    {"net_io_counters", psutil_net_io_counters, METH_VARARGS,
+     "Return dict of tuples of networks I/O information."},
+    {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS,
+     "Return dict of tuples of disks I/O information."},
+    {"users", psutil_users, METH_VARARGS,
+     "Return currently connected users as a list of tuples"},
+
+    {NULL, NULL, 0, NULL}
+};
+
+
+struct module_state {
+    PyObject *error;
+};
+
+#if PY_MAJOR_VERSION >= 3
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#else
+#define GETSTATE(m) (&_state)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+static int
+psutil_osx_traverse(PyObject *m, visitproc visit, void *arg) {
+    Py_VISIT(GETSTATE(m)->error);
+    return 0;
+}
+
+static int
+psutil_osx_clear(PyObject *m) {
+    Py_CLEAR(GETSTATE(m)->error);
+    return 0;
+}
+
+
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "psutil_osx",
+    NULL,
+    sizeof(struct module_state),
+    PsutilMethods,
+    NULL,
+    psutil_osx_traverse,
+    psutil_osx_clear,
+    NULL
+};
+
+#define INITERROR return NULL
+
+PyMODINIT_FUNC PyInit__psutil_osx(void)
+
+#else
+#define INITERROR return
+
+void
+init_psutil_osx(void)
+#endif
+{
+#if PY_MAJOR_VERSION >= 3
+    PyObject *module = PyModule_Create(&moduledef);
+#else
+    PyObject *module = Py_InitModule("_psutil_osx", PsutilMethods);
+#endif
+    // process status constants, defined in:
+    // http://fxr.watson.org/fxr/source/bsd/sys/proc.h?v=xnu-792.6.70#L149
+    PyModule_AddIntConstant(module, "SIDL", SIDL);
+    PyModule_AddIntConstant(module, "SRUN", SRUN);
+    PyModule_AddIntConstant(module, "SSLEEP", SSLEEP);
+    PyModule_AddIntConstant(module, "SSTOP", SSTOP);
+    PyModule_AddIntConstant(module, "SZOMB", SZOMB);
+    // connection status constants
+    PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED);
+    PyModule_AddIntConstant(module, "TCPS_CLOSING", TCPS_CLOSING);
+    PyModule_AddIntConstant(module, "TCPS_CLOSE_WAIT", TCPS_CLOSE_WAIT);
+    PyModule_AddIntConstant(module, "TCPS_LISTEN", TCPS_LISTEN);
+    PyModule_AddIntConstant(module, "TCPS_ESTABLISHED", TCPS_ESTABLISHED);
+    PyModule_AddIntConstant(module, "TCPS_SYN_SENT", TCPS_SYN_SENT);
+    PyModule_AddIntConstant(module, "TCPS_SYN_RECEIVED", TCPS_SYN_RECEIVED);
+    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_1", TCPS_FIN_WAIT_1);
+    PyModule_AddIntConstant(module, "TCPS_FIN_WAIT_2", TCPS_FIN_WAIT_2);
+    PyModule_AddIntConstant(module, "TCPS_LAST_ACK", TCPS_LAST_ACK);
+    PyModule_AddIntConstant(module, "TCPS_TIME_WAIT", TCPS_TIME_WAIT);
+    PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", PSUTIL_CONN_NONE);
+
+    if (module == NULL) {
+        INITERROR;
+    }
+#if PY_MAJOR_VERSION >= 3
+    return module;
+#endif
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.h
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.h
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.h
new file mode 100644
index 0000000..907a8e5
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_osx.h
@@ -0,0 +1,41 @@
+/*
+ * 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
+ * found in the LICENSE file.
+ */
+
+#include <Python.h>
+
+// --- per-process functions
+static PyObject* psutil_proc_cmdline(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_connections(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_cpu_times(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_create_time(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_cwd(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_exe(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_gids(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_memory_info(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_memory_maps(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_name(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_num_fds(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_open_files(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_ppid(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_status(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_threads(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_tty_nr(PyObject* self, PyObject* args);
+static PyObject* psutil_proc_uids(PyObject* self, PyObject* args);
+
+// --- system-related functions
+static PyObject* psutil_boot_time(PyObject* self, PyObject* args);
+static PyObject* psutil_cpu_count_logical(PyObject* self, PyObject* args);
+static PyObject* psutil_cpu_count_phys(PyObject* self, PyObject* args);
+static PyObject* psutil_cpu_times(PyObject* self, PyObject* args);
+static PyObject* psutil_disk_io_counters(PyObject* self, PyObject* args);
+static PyObject* psutil_disk_partitions(PyObject* self, PyObject* args);
+static PyObject* psutil_net_io_counters(PyObject* self, PyObject* args);
+static PyObject* psutil_per_cpu_times(PyObject* self, PyObject* args);
+static PyObject* psutil_pids(PyObject* self, PyObject* args);
+static PyObject* psutil_swap_mem(PyObject* self, PyObject* args);
+static PyObject* psutil_users(PyObject* self, PyObject* args);
+static PyObject* psutil_virtual_mem(PyObject* self, PyObject* args);

http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.c
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.c
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.c
new file mode 100644
index 0000000..ad2e59d
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Functions specific to all POSIX compliant platforms.
+ */
+
+#include <Python.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+
+#include "_psutil_posix.h"
+
+
+/*
+ * Given a PID return process priority as a Python integer.
+ */
+static PyObject *
+psutil_posix_getpriority(PyObject *self, PyObject *args)
+{
+    long pid;
+    int priority;
+    errno = 0;
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    priority = getpriority(PRIO_PROCESS, pid);
+    if (errno != 0) {
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+    return Py_BuildValue("i", priority);
+}
+
+
+/*
+ * Given a PID and a value change process priority.
+ */
+static PyObject *
+psutil_posix_setpriority(PyObject *self, PyObject *args)
+{
+    long pid;
+    int priority;
+    int retval;
+    if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
+        return NULL;
+    }
+    retval = setpriority(PRIO_PROCESS, pid, priority);
+    if (retval == -1) {
+        return PyErr_SetFromErrno(PyExc_OSError);
+    }
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+
+
+/*
+ * define the psutil C module methods and initialize the module.
+ */
+static PyMethodDef
+PsutilMethods[] =
+{
+    {"getpriority", psutil_posix_getpriority, METH_VARARGS,
+     "Return process priority"},
+    {"setpriority", psutil_posix_setpriority, METH_VARARGS,
+     "Set process priority"},
+    {NULL, NULL, 0, NULL}
+};
+
+struct module_state {
+    PyObject *error;
+};
+
+#if PY_MAJOR_VERSION >= 3
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+#else
+#define GETSTATE(m) (&_state)
+#endif
+
+#if PY_MAJOR_VERSION >= 3
+
+static int
+psutil_posix_traverse(PyObject *m, visitproc visit, void *arg) {
+    Py_VISIT(GETSTATE(m)->error);
+    return 0;
+}
+
+static int
+psutil_posix_clear(PyObject *m) {
+    Py_CLEAR(GETSTATE(m)->error);
+    return 0;
+}
+
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "psutil_posix",
+    NULL,
+    sizeof(struct module_state),
+    PsutilMethods,
+    NULL,
+    psutil_posix_traverse,
+    psutil_posix_clear,
+    NULL
+};
+
+#define INITERROR return NULL
+
+PyMODINIT_FUNC PyInit__psutil_posix(void)
+
+#else
+#define INITERROR return
+
+void init_psutil_posix(void)
+#endif
+{
+#if PY_MAJOR_VERSION >= 3
+    PyObject *module = PyModule_Create(&moduledef);
+#else
+    PyObject *module = Py_InitModule("_psutil_posix", PsutilMethods);
+#endif
+    if (module == NULL) {
+        INITERROR;
+    }
+#if PY_MAJOR_VERSION >= 3
+    return module;
+#endif
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/a52f8a55/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.h
----------------------------------------------------------------------
diff --git 
a/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.h
 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.h
new file mode 100644
index 0000000..5a4681d
--- /dev/null
+++ 
b/ambari-metrics/ambari-metrics-host-monitoring/src/main/python/psutil/psutil/_psutil_posix.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <Python.h>
+
+static PyObject* psutil_posix_getpriority(PyObject* self, PyObject* args);
+static PyObject* psutil_posix_setpriority(PyObject* self, PyObject* args);

Reply via email to