diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2015-11-12 05:16:31 +0100 |
---|---|---|
committer | Giampaolo Rodola <g.rodola@gmail.com> | 2015-11-12 05:16:31 +0100 |
commit | b4625abc5d131d751d84b7ab40a9c31a23e3b296 (patch) | |
tree | 19c1a3ac72f24042656829eafd34026119f479c0 | |
parent | a7f4fe2dfd14e53244dcb9fa75ef6093432762c2 (diff) | |
download | psutil-b4625abc5d131d751d84b7ab40a9c31a23e3b296.tar.gz |
merge _psutil_openbsd.c into _psutil_bsd.c
-rw-r--r-- | psutil/_psbsd.py | 5 | ||||
-rw-r--r-- | psutil/_psutil_bsd.c | 304 | ||||
-rw-r--r-- | psutil/_psutil_openbsd.c | 2419 |
3 files changed, 232 insertions, 2496 deletions
diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 57d847b9..58039245 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -111,9 +111,8 @@ def virtual_memory(): def swap_memory(): """System swap memory as (total, used, free, sin, sout) namedtuple.""" - if OPENBSD: - PAGESIZE = 1 - total, used, free, sin, sout = [x * PAGESIZE for x in cext.swap_mem()] + pagesize = 1 if OPENBSD else PAGESIZE + total, used, free, sin, sout = [x * pagesize for x in cext.swap_mem()] percent = usage_percent(used, total, _round=1) return _common.sswap(total, used, free, percent, sin, sout) diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 69d473da..9c979306 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -1,9 +1,18 @@ /* - * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved. + * Copyright (c) 2009, Giampaolo Rodola', Landry Breuil (OpenBSD). + * All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * - * FreeBSD platform-specific module methods for _psutil_bsd + * Platform-specific module methods for FreeBSD and OpenBSD. + + * OpenBSD references: + * - OpenBSD source code: http://anoncvs.spacehopper.org/openbsd-src/ + * + * OpenBSD: missing compared to FreeBSD implementation: + * - psutil.net_connections() + * - psutil.Process.get/set_cpu_affinity() (not supported natively) + * - psutil.Process.memory_maps() */ @@ -16,56 +25,83 @@ #include <fcntl.h> #include <paths.h> #include <sys/types.h> -#include <sys/sysctl.h> #include <sys/param.h> +#include <sys/sysctl.h> #include <sys/user.h> #include <sys/proc.h> #include <sys/file.h> -#include <sys/cpuset.h> -#include <net/route.h> - #include <sys/socket.h> +#include <net/route.h> #include <sys/socketvar.h> // for struct xsocket #include <sys/un.h> #include <sys/unpcb.h> -#include <sys/sockio.h> // for xinpcb struct #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/ip.h> #include <netinet/in_pcb.h> +#include <netinet/tcp.h> +#include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> // for struct xtcpcb #include <netinet/tcp_fsm.h> // for TCP connection states #include <arpa/inet.h> // for inet_ntop() -#if __FreeBSD_version < 900000 -#include <utmp.h> // system users -#else -#include <utmpx.h> -#endif -#include <devstat.h> // get io counters -#include <sys/vmmeter.h> // needed for vmtotal struct -#include <libutil.h> // process open files, shared libs (kinfo_getvmmap) #include <sys/mount.h> #include <net/if.h> // net io counters #include <net/if_dl.h> #include <net/route.h> -#include <net/if_media.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" + +#ifdef __FreeBSD__ + #include "arch/bsd/process_info.h" +#elif __OpenBSD__ + #include "arch/bsd/openbsd.h" +#endif + +#ifdef __FreeBSD__ + #include <sys/cpuset.h> + #include <net/if_media.h> + #include <devstat.h> // get io counters + #include <sys/vmmeter.h> // needed for vmtotal struct + #include <libutil.h> // process open files, shared libs (kinfo_getvmmap) + + #if __FreeBSD_version < 900000 + #include <utmp.h> // system users + #else + #include <utmpx.h> + #endif +#endif + +#ifdef __OpenBSD__ + #include <utmp.h> + #include <sys/vnode.h> // for VREG + #define _KERNEL // for DTYPE_VNODE + #include <sys/file.h> + #undef _KERNEL + #include <sys/sched.h> // for CPUSTATES & CP_* +#endif -// convert a timeval struct to a double #define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) -// convert a bintime struct to milliseconds -#define BT2MSEC(bt) (bt.sec * 1000 + ( ( (uint64_t) 1000000000 * (uint32_t) (bt.frac >> 32) ) >> 32 ) / 1000000) +#ifdef __FreeBSD__ + // convert a timeval struct to a double + // convert a bintime struct to milliseconds + #define BT2MSEC(bt) (bt.sec * 1000 + ( ( (uint64_t) 1000000000 * (uint32_t) (bt.frac >> 32) ) >> 32 ) / 1000000) +#endif + +#ifdef __OpenBSD__ + #define KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0) +#endif + + +#ifdef __FreeBSD__ /* * Utility function which fills a kinfo_proc struct based on process pid */ @@ -92,8 +128,10 @@ psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc) { } return 0; } +#endif +#ifdef __FreeBSD__ /* * Set exception to AccessDenied if pid exists else NoSuchProcess. */ @@ -108,6 +146,7 @@ psutil_raise_ad_or_nsp(long pid) { else return NULL; } +#endif /* @@ -133,7 +172,11 @@ psutil_pids(PyObject *self, PyObject *args) { if (num_processes > 0) { orig_address = proclist; // save so we can free it after we're done for (idx = 0; idx < num_processes; idx++) { +#ifdef __FreeBSD__ py_pid = Py_BuildValue("i", proclist->ki_pid); +#elif __OpenBSD__ + py_pid = Py_BuildValue("i", proclist->p_pid); +#endif if (!py_pid) goto error; if (PyList_Append(py_retlist, py_pid)) @@ -185,10 +228,15 @@ psutil_proc_name(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; +#ifdef __FreeBSD__ return Py_BuildValue("s", kp.ki_comm); +#elif __OpenBSD__ + return Py_BuildValue("s", kp.p_comm); +#endif } +#ifdef __FreeBSD__ /* * Return process pathname executable. * Thanks to Robert N. M. Watson: @@ -228,6 +276,7 @@ psutil_proc_exe(PyObject *self, PyObject *args) { } return Py_BuildValue("s", pathname); } +#endif /* @@ -241,9 +290,7 @@ psutil_proc_cmdline(PyObject *self, PyObject *args) { if (! PyArg_ParseTuple(args, "l", &pid)) return NULL; - // get the commandline, defined in arch/bsd/process_info.c py_retlist = psutil_get_cmdline(pid); - // psutil_get_cmdline() returns NULL only if psutil_cmd_args // failed with ESRCH (no process with that PID) if (NULL == py_retlist) @@ -263,7 +310,11 @@ psutil_proc_ppid(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; +#ifdef __FreeBSD__ return Py_BuildValue("l", (long)kp.ki_ppid); +#elif __OpenBSD__ + return Py_BuildValue("l", (long)kp.p_ppid); +#endif } @@ -278,7 +329,11 @@ psutil_proc_status(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; +#ifdef __FreeBSD__ return Py_BuildValue("i", (int)kp.ki_stat); +#elif __OpenBSD__ + return Py_BuildValue("i", (int)kp.p_stat); +#endif } @@ -295,9 +350,15 @@ psutil_proc_uids(PyObject *self, PyObject *args) { if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("lll", +#ifdef __FreeBSD__ (long)kp.ki_ruid, (long)kp.ki_uid, (long)kp.ki_svuid); +#elif __OpenBSD__ + (long)kp.p_ruid, + (long)kp.p_uid, + (long)kp.p_svuid); +#endif } @@ -314,9 +375,15 @@ psutil_proc_gids(PyObject *self, PyObject *args) { if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("lll", +#ifdef __FreeBSD__ (long)kp.ki_rgid, (long)kp.ki_groups[0], (long)kp.ki_svuid); +#elif __OpenBSD__ + (long)kp.p_rgid, + (long)kp.p_groups[0], + (long)kp.p_svuid); +#endif } @@ -332,7 +399,11 @@ psutil_proc_tty_nr(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; +#ifdef __FreeBSD__ return Py_BuildValue("i", kp.ki_tdev); +#elif __OpenBSD__ + return Py_BuildValue("i", kp.p_tdev); +#endif } @@ -348,11 +419,17 @@ psutil_proc_num_ctx_switches(PyObject *self, PyObject *args) { if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; return Py_BuildValue("(ll)", +#ifdef __FreeBSD__ kp.ki_rusage.ru_nvcsw, kp.ki_rusage.ru_nivcsw); +#elif __OpenBSD__ + kp.p_uru_nvcsw, + kp.p_uru_nivcsw); +#endif } +#ifdef __FreeBSD__ /* * Return number of threads used by process as a Python integer. */ @@ -366,15 +443,18 @@ psutil_proc_num_threads(PyObject *self, PyObject *args) { return NULL; return Py_BuildValue("l", (long)kp.ki_numthreads); } +#endif /* * Retrieves all threads used by process returning a list of tuples * including thread id, user time and system time. - * Thanks to Robert N. M. Watson: + * Thanks to Robert N. M. Watson (FreeBSD): * http://fxr.googlebit.com/source/usr.bin/procstat/ * procstat_threads.c?v=8-CURRENT */ + +#ifdef __FreeBSD__ static PyObject * psutil_proc_threads(PyObject *self, PyObject *args) { long pid; @@ -447,6 +527,7 @@ error: free(kip); return NULL; } +#endif /* @@ -462,8 +543,13 @@ psutil_proc_cpu_times(PyObject *self, PyObject *args) { if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; // convert from microseconds to seconds +#ifdef __FreeBSD__ user_t = TV2DOUBLE(kp.ki_rusage.ru_utime); sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime); +#elif __OpenBSD__ + user_t = KPT2DOUBLE(kp.p_uutime); + sys_t = KPT2DOUBLE(kp.p_ustime); +#endif return Py_BuildValue("(dd)", user_t, sys_t); } @@ -489,6 +575,7 @@ psutil_cpu_count_logical(PyObject *self, PyObject *args) { } +#ifdef __FreeBSD__ /* * Return an XML string from which we'll determine the number of * physical CPU cores in the system. @@ -520,6 +607,7 @@ error: free(topology); Py_RETURN_NONE; } +#endif /* @@ -534,7 +622,11 @@ psutil_proc_create_time(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; +#ifdef __FreeBSD__ return Py_BuildValue("d", TV2DOUBLE(kp.ki_start)); +#elif __OpenBSD__ + return Py_BuildValue("d", KPT2DOUBLE(kp.p_ustart)); +#endif } @@ -552,13 +644,22 @@ psutil_proc_io_counters(PyObject *self, PyObject *args) { return NULL; // there's apparently no way to determine bytes count, hence return -1. return Py_BuildValue("(llll)", +#ifdef __FreeBSD__ kp.ki_rusage.ru_inblock, kp.ki_rusage.ru_oublock, +#elif __OpenBSD__ + kp.p_uru_inblock, + kp.p_uru_oublock, +#endif -1, -1); } +#ifdef __OpenBSD__ +#define ptoa(x) ((paddr_t)(x) << PAGE_SHIFT) +#endif + /* * Return extended memory info for a process as a Python tuple. */ @@ -570,15 +671,27 @@ psutil_proc_memory_info(PyObject *self, PyObject *args) { return NULL; if (psutil_kinfo_proc(pid, &kp) == -1) return NULL; - return Py_BuildValue("(lllll)", - ptoa(kp.ki_rssize), // rss - (long)kp.ki_size, // vms - ptoa(kp.ki_tsize), // text - ptoa(kp.ki_dsize), // data - ptoa(kp.ki_ssize)); // stack + return Py_BuildValue( + "(lllll)", +#ifdef __FreeBSD__ + ptoa(kp.ki_rssize), // rss + (long)kp.ki_size, // vms + ptoa(kp.ki_tsize), // text + ptoa(kp.ki_dsize), // data + ptoa(kp.ki_ssize)); // stack +#elif __OpenBSD__ + ptoa(kp.p_vm_rssize), // rss + // vms, this is how ps does it, see: + // http://anoncvs.spacehopper.org/openbsd-src/tree/bin/ps/print.c#n461 + ptoa(kp.p_vm_dsize + kp.p_vm_ssize + kp.p_vm_tsize), // vms + ptoa(kp.p_vm_tsize), // text + ptoa(kp.p_vm_dsize), // data + ptoa(kp.p_vm_ssize)); // stack +#endif } +#ifdef __FreeBSD__ /* * Return virtual memory usage statistics. */ @@ -631,12 +744,14 @@ error: PyErr_SetFromErrno(PyExc_OSError); return NULL; } +#endif #ifndef _PATH_DEVNULL #define _PATH_DEVNULL "/dev/null" #endif +#ifdef __FreeBSD__ /* * Return swap memory stats (see 'swapinfo' cmdline tool) */ @@ -681,6 +796,7 @@ sbn_error: PyErr_SetFromErrno(PyExc_OSError); return NULL; } +#endif /* @@ -689,11 +805,16 @@ sbn_error: static PyObject * psutil_cpu_times(PyObject *self, PyObject *args) { long cpu_time[CPUSTATES]; - size_t size; - - size = sizeof(cpu_time); + size_t size = sizeof(cpu_time); + int ret; - if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) { +#ifdef __FreeBSD__ + ret = sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0); +#elif __OpenBSD__ + int mib[] = {CTL_KERN, KERN_CPTIME}; + ret = sysctl(mib, 2, &cpu_time, &size, NULL, 0); +#endif + if (ret == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } @@ -708,21 +829,13 @@ psutil_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. * TODO: this is broken as it may report empty paths. 'procstat' * utility has the same problem see: * https://github.com/giampaolo/psutil/issues/595 */ +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ static PyObject * psutil_proc_open_files(PyObject *self, PyObject *args) { long pid; @@ -748,10 +861,17 @@ psutil_proc_open_files(PyObject *self, PyObject *args) { for (i = 0; i < cnt; i++) { kif = &freep[i]; +#ifdef __FreeBSD__ if ((kif->kf_type == KF_TYPE_VNODE) && (kif->kf_vnode_type == KF_VTYPE_VREG)) { py_tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd); +#else + if ((kif->f_type == DTYPE_VNODE) && + (kif->v_type == VREG)) + { + py_tuple = Py_BuildValue("(si)", "", kif->fd_fd); +#endif if (py_tuple == NULL) goto error; if (PyList_Append(py_retlist, py_tuple)) @@ -769,8 +889,10 @@ error: free(freep); return NULL; } +#endif +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 /* * Return files opened by process as a list of (path, fd) tuples */ @@ -796,8 +918,10 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) { return Py_BuildValue("i", cnt); } +#endif +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 /* * Return process current working directory. */ @@ -847,8 +971,10 @@ error: free(freep); return NULL; } +#endif +#ifdef __FreeBSD__ // The tcplist fetching and walking is borrowed from netstat/inet.c. static char * psutil_fetch_tcplist(void) { @@ -1132,11 +1258,10 @@ error: free(tcplist); return NULL; } +#endif -/* - * Return a Python list of tuple representing per-cpu times - */ +#ifdef __FreeBSD__ static PyObject * psutil_per_cpu_times(PyObject *self, PyObject *args) { static int maxcpus; @@ -1198,8 +1323,10 @@ error: Py_DECREF(py_retlist); return NULL; } +#endif +#ifdef __FreeBSD__ // remove spaces from string void remove_spaces(char *str) { char *p1 = str; @@ -1207,7 +1334,7 @@ void remove_spaces(char *str) { do while (*p2 == ' ') p2++; - while ((*p1++ = *p2++)); + while (*p1++ = *p2++); } @@ -1374,6 +1501,7 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { strlcat(opts, "ro", sizeof(opts)); else strlcat(opts, "rw", sizeof(opts)); +#ifdef __FreeBSD__ if (flags & MNT_SYNCHRONOUS) strlcat(opts, ",sync", sizeof(opts)); if (flags & MNT_NOEXEC) @@ -1404,7 +1532,20 @@ psutil_disk_partitions(PyObject *self, PyObject *args) { strlcat(opts, ",noclusterw", sizeof(opts)); if (flags & MNT_NFS4ACLS) strlcat(opts, ",nfs4acls", sizeof(opts)); - +#elif __OpenBSD__ + 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_ASYNC) + strlcat(opts, ",async", sizeof(opts)); + if (flags & MNT_SOFTDEP) + strlcat(opts, ",softdep", sizeof(opts)); + if (flags & MNT_NOATIME) + strlcat(opts, ",noatime", sizeof(opts)); +#endif py_tuple = Py_BuildValue("(ssss)", fs[i].f_mntfromname, // device fs[i].f_mntonname, // mount point @@ -1440,9 +1581,9 @@ psutil_net_io_counters(PyObject *self, PyObject *args) { 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) @@ -1519,6 +1660,7 @@ error: } +#ifdef __FreeBSD__ /* * Return a Python dict of tuples for disk I/O information */ @@ -1586,6 +1728,7 @@ error: free(stats.dinfo); return NULL; } +#endif /* @@ -1599,7 +1742,7 @@ psutil_users(PyObject *self, PyObject *args) { if (py_retlist == NULL) return NULL; -#if __FreeBSD_version < 900000 +#if __FreeBSD_version < 900000 || __OpenBSD__ struct utmp ut; FILE *fp; @@ -1666,11 +1809,10 @@ error: } - +#ifdef __FreeBSD__ /* * System-wide open connections. */ - #define HASHSIZE 1009 static struct xfile *psutil_xfiles; static int psutil_nxfiles; @@ -2085,22 +2227,19 @@ error: Py_DECREF(py_cpu_seq); return NULL; } - +#endif /* * 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_connections", psutil_proc_connections, METH_VARARGS, "Return connections opened by process"}, - {"proc_exe", psutil_proc_exe, METH_VARARGS, - "Return process pathname executable"}, {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS, "Return process cmdline as a list of cmdline arguments"}, {"proc_ppid", psutil_proc_ppid, METH_VARARGS, @@ -2116,8 +2255,6 @@ PsutilMethods[] = { "seconds since the epoch"}, {"proc_memory_info", psutil_proc_memory_info, METH_VARARGS, "Return extended memory info for a process as a Python tuple."}, - {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS, - "Return number of threads used by process"}, {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS, "Return the number of context switches performed by process"}, {"proc_threads", psutil_proc_threads, METH_VARARGS, @@ -2128,20 +2265,31 @@ PsutilMethods[] = { "Return process IO counters"}, {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS, "Return process tty (terminal) number"}, - {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS, - "Return process CPU affinity."}, - {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS, - "Set process CPU affinity."}, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 - {"proc_open_files", psutil_proc_open_files, METH_VARARGS, - "Return files opened by process as a list of (path, fd) tuples"}, {"proc_cwd", psutil_proc_cwd, METH_VARARGS, "Return process current working directory."}, - {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS, - "Return a list of tuples for every process's memory map"}, +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS, "Return the number of file descriptors opened by this process"}, #endif +#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ + {"proc_open_files", psutil_proc_open_files, METH_VARARGS, + "Return files opened by process as a list of (path, fd) tuples"}, +#endif + +#ifdef __FreeBSD__ + {"proc_exe", psutil_proc_exe, METH_VARARGS, + "Return process pathname executable"}, + {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS, + "Return number of threads used by process"}, + {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS, + "Return a list of tuples for every process's memory map"}, + {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS, + "Return process CPU affinity."}, + {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS, + "Set process CPU affinity."}, + {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS, + "Return an XML string to determine the number physical CPUs."}, +#endif // --- system-related functions @@ -2149,18 +2297,14 @@ PsutilMethods[] = { "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 an XML string to determine the number physical CPUs."}, {"virtual_mem", psutil_virtual_mem, METH_VARARGS, "Return system virtual memory usage statistics"}, {"swap_mem", psutil_swap_mem, METH_VARARGS, "Return swap mem stats"}, {"cpu_times", psutil_cpu_times, METH_VARARGS, "Return system cpu times as a tuple (user, system, nice, idle, irc)"}, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS, "Return system per-cpu times as a list of tuples"}, -#endif {"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, @@ -2172,9 +2316,10 @@ PsutilMethods[] = { "Return a Python dict of tuples for disk I/O information"}, {"users", psutil_users, METH_VARARGS, "Return currently connected users as a list of tuples"}, +#ifdef __FreeBSD__ {"net_connections", psutil_net_connections, METH_VARARGS, "Return system-wide open connections."}, - +#endif {NULL, NULL, 0, NULL} }; @@ -2231,8 +2376,9 @@ void init_psutil_bsd(void) PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods); #endif PyModule_AddIntConstant(module, "version", PSUTIL_VERSION); - // process status constants + +#ifdef __FreeBSD__ PyModule_AddIntConstant(module, "SIDL", SIDL); PyModule_AddIntConstant(module, "SRUN", SRUN); PyModule_AddIntConstant(module, "SSLEEP", SSLEEP); @@ -2240,6 +2386,15 @@ void init_psutil_bsd(void) PyModule_AddIntConstant(module, "SZOMB", SZOMB); PyModule_AddIntConstant(module, "SWAIT", SWAIT); PyModule_AddIntConstant(module, "SLOCK", SLOCK); +#elif __OpenBSD__ + 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); // unused + PyModule_AddIntConstant(module, "SDEAD", SDEAD); + PyModule_AddIntConstant(module, "SONPROC", SONPROC); +#endif // connection status constants PyModule_AddIntConstant(module, "TCPS_CLOSED", TCPS_CLOSED); @@ -2253,7 +2408,8 @@ void init_psutil_bsd(void) 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); + // PSUTIL_CONN_NONE + PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", 128); if (module == NULL) INITERROR; diff --git a/psutil/_psutil_openbsd.c b/psutil/_psutil_openbsd.c deleted file mode 100644 index 9c979306..00000000 --- a/psutil/_psutil_openbsd.c +++ /dev/null @@ -1,2419 +0,0 @@ -/* - * Copyright (c) 2009, Giampaolo Rodola', Landry Breuil (OpenBSD). - * All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - * - * Platform-specific module methods for FreeBSD and OpenBSD. - - * OpenBSD references: - * - OpenBSD source code: http://anoncvs.spacehopper.org/openbsd-src/ - * - * OpenBSD: missing compared to FreeBSD implementation: - * - psutil.net_connections() - * - psutil.Process.get/set_cpu_affinity() (not supported natively) - * - psutil.Process.memory_maps() - */ - - -#include <Python.h> -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <stdio.h> -#include <signal.h> -#include <fcntl.h> -#include <paths.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/sysctl.h> -#include <sys/user.h> -#include <sys/proc.h> -#include <sys/file.h> -#include <sys/socket.h> -#include <net/route.h> -#include <sys/socketvar.h> // for struct xsocket -#include <sys/un.h> -#include <sys/unpcb.h> -// for xinpcb struct -#include <netinet/in.h> -#include <netinet/in_systm.h> -#include <netinet/ip.h> -#include <netinet/in_pcb.h> -#include <netinet/tcp.h> -#include <netinet/tcp_timer.h> -#include <netinet/tcp_var.h> // for struct xtcpcb -#include <netinet/tcp_fsm.h> // for TCP connection states -#include <arpa/inet.h> // for inet_ntop() - -#include <sys/mount.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" - -#ifdef __FreeBSD__ - #include "arch/bsd/process_info.h" -#elif __OpenBSD__ - #include "arch/bsd/openbsd.h" -#endif - -#ifdef __FreeBSD__ - #include <sys/cpuset.h> - #include <net/if_media.h> - #include <devstat.h> // get io counters - #include <sys/vmmeter.h> // needed for vmtotal struct - #include <libutil.h> // process open files, shared libs (kinfo_getvmmap) - - #if __FreeBSD_version < 900000 - #include <utmp.h> // system users - #else - #include <utmpx.h> - #endif -#endif - -#ifdef __OpenBSD__ - #include <utmp.h> - #include <sys/vnode.h> // for VREG - #define _KERNEL // for DTYPE_VNODE - #include <sys/file.h> - #undef _KERNEL - #include <sys/sched.h> // for CPUSTATES & CP_* -#endif - - -#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0) - -#ifdef __FreeBSD__ - // convert a timeval struct to a double - // convert a bintime struct to milliseconds - #define BT2MSEC(bt) (bt.sec * 1000 + ( ( (uint64_t) 1000000000 * (uint32_t) (bt.frac >> 32) ) >> 32 ) / 1000000) -#endif - -#ifdef __OpenBSD__ - #define KPT2DOUBLE(t) (t ## _sec + t ## _usec / 1000000.0) -#endif - - -#ifdef __FreeBSD__ -/* - * Utility function which fills a kinfo_proc struct based on process pid - */ -static int -psutil_kinfo_proc(const pid_t pid, struct kinfo_proc *proc) { - int mib[4]; - size_t size; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = pid; - - size = sizeof(struct kinfo_proc); - - if (sysctl((int *)mib, 4, proc, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return -1; - } - - // sysctl stores 0 in the size if we can't find the process information. - if (size == 0) { - NoSuchProcess(); - return -1; - } - return 0; -} -#endif - - -#ifdef __FreeBSD__ -/* - * Set exception to AccessDenied if pid exists else NoSuchProcess. - */ -void -psutil_raise_ad_or_nsp(long pid) { - int ret; - ret = psutil_pid_exists(pid); - if (ret == 0) - NoSuchProcess(); - else if (ret == 1) - AccessDenied(); - else - return NULL; -} -#endif - - -/* - * 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 *py_retlist = PyList_New(0); - PyObject *py_pid = NULL; - - if (py_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) { - orig_address = proclist; // save so we can free it after we're done - for (idx = 0; idx < num_processes; idx++) { -#ifdef __FreeBSD__ - py_pid = Py_BuildValue("i", proclist->ki_pid); -#elif __OpenBSD__ - py_pid = Py_BuildValue("i", proclist->p_pid); -#endif - if (!py_pid) - goto error; - if (PyList_Append(py_retlist, py_pid)) - goto error; - Py_DECREF(py_pid); - proclist++; - } - free(orig_address); - } - - return py_retlist; - -error: - Py_XDECREF(py_pid); - Py_DECREF(py_retlist); - if (orig_address != NULL) - free(orig_address); - 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 boottime; - size_t len = sizeof(boottime); - - if (sysctl(request, 2, &boottime, &len, NULL, 0) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return Py_BuildValue("d", (double)boottime.tv_sec); -} - - -/* - * 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_kinfo_proc(pid, &kp) == -1) - return NULL; -#ifdef __FreeBSD__ - return Py_BuildValue("s", kp.ki_comm); -#elif __OpenBSD__ - return Py_BuildValue("s", kp.p_comm); -#endif -} - - -#ifdef __FreeBSD__ -/* - * Return process pathname executable. - * Thanks to Robert N. M. Watson: - * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_bin.c?v=8-CURRENT - */ -static PyObject * -psutil_proc_exe(PyObject *self, PyObject *args) { - long pid; - char pathname[PATH_MAX]; - int error; - int mib[4]; - int ret; - size_t size; - - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = pid; - - size = sizeof(pathname); - error = sysctl(mib, 4, pathname, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - if (size == 0 || strlen(pathname) == 0) { - ret = psutil_pid_exists(pid); - if (ret == -1) - return NULL; - else if (ret == 0) - return NoSuchProcess(); - else - strcpy(pathname, ""); - } - return Py_BuildValue("s", pathname); -} -#endif - - -/* - * Return process cmdline as a Python list of cmdline arguments. - */ -static PyObject * -psutil_proc_cmdline(PyObject *self, PyObject *args) { - long pid; - PyObject *py_retlist = NULL; - - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - - py_retlist = psutil_get_cmdline(pid); - // psutil_get_cmdline() returns NULL only if psutil_cmd_args - // failed with ESRCH (no process with that PID) - if (NULL == py_retlist) - return PyErr_SetFromErrno(PyExc_OSError); - return Py_BuildValue("N", py_retlist); -} - - -/* - * 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_kinfo_proc(pid, &kp) == -1) - return NULL; -#ifdef __FreeBSD__ - return Py_BuildValue("l", (long)kp.ki_ppid); -#elif __OpenBSD__ - return Py_BuildValue("l", (long)kp.p_ppid); -#endif -} - - -/* - * 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_kinfo_proc(pid, &kp) == -1) - return NULL; -#ifdef __FreeBSD__ - return Py_BuildValue("i", (int)kp.ki_stat); -#elif __OpenBSD__ - return Py_BuildValue("i", (int)kp.p_stat); -#endif -} - - -/* - * Return process real, effective and saved user ids from kinfo_proc - * as a Python tuple. - */ -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_kinfo_proc(pid, &kp) == -1) - return NULL; - return Py_BuildValue("lll", -#ifdef __FreeBSD__ - (long)kp.ki_ruid, - (long)kp.ki_uid, - (long)kp.ki_svuid); -#elif __OpenBSD__ - (long)kp.p_ruid, - (long)kp.p_uid, - (long)kp.p_svuid); -#endif -} - - -/* - * Return process real, effective and saved group ids from kinfo_proc - * as a Python tuple. - */ -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_kinfo_proc(pid, &kp) == -1) - return NULL; - return Py_BuildValue("lll", -#ifdef __FreeBSD__ - (long)kp.ki_rgid, - (long)kp.ki_groups[0], - (long)kp.ki_svuid); -#elif __OpenBSD__ - (long)kp.p_rgid, - (long)kp.p_groups[0], - (long)kp.p_svuid); -#endif -} - - -/* - * Return process real, effective and saved group ids from kinfo_proc - * as a Python tuple. - */ -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_kinfo_proc(pid, &kp) == -1) - return NULL; -#ifdef __FreeBSD__ - return Py_BuildValue("i", kp.ki_tdev); -#elif __OpenBSD__ - return Py_BuildValue("i", kp.p_tdev); -#endif -} - - -/* - * Return the number of context switches performed by process as a tuple. - */ -static PyObject * -psutil_proc_num_ctx_switches(PyObject *self, PyObject *args) { - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kp) == -1) - return NULL; - return Py_BuildValue("(ll)", -#ifdef __FreeBSD__ - kp.ki_rusage.ru_nvcsw, - kp.ki_rusage.ru_nivcsw); -#elif __OpenBSD__ - kp.p_uru_nvcsw, - kp.p_uru_nivcsw); -#endif -} - - -#ifdef __FreeBSD__ -/* - * Return number of threads used by process as a Python integer. - */ -static PyObject * -psutil_proc_num_threads(PyObject *self, PyObject *args) { - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kp) == -1) - return NULL; - return Py_BuildValue("l", (long)kp.ki_numthreads); -} -#endif - - -/* - * Retrieves all threads used by process returning a list of tuples - * including thread id, user time and system time. - * Thanks to Robert N. M. Watson (FreeBSD): - * http://fxr.googlebit.com/source/usr.bin/procstat/ - * procstat_threads.c?v=8-CURRENT - */ - -#ifdef __FreeBSD__ -static PyObject * -psutil_proc_threads(PyObject *self, PyObject *args) { - long pid; - int mib[4]; - struct kinfo_proc *kip = NULL; - struct kinfo_proc *kipp = NULL; - int error; - unsigned int i; - size_t size; - PyObject *py_retlist = PyList_New(0); - PyObject *py_tuple = NULL; - - if (py_retlist == NULL) - return NULL; - if (! PyArg_ParseTuple(args, "l", &pid)) - goto error; - - // we need to re-query for thread information, so don't use *kipp - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD; - mib[3] = pid; - - size = 0; - error = sysctl(mib, 4, NULL, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - if (size == 0) { - NoSuchProcess(); - goto error; - } - - kip = malloc(size); - if (kip == NULL) { - PyErr_NoMemory(); - goto error; - } - - error = sysctl(mib, 4, kip, &size, NULL, 0); - if (error == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - if (size == 0) { - NoSuchProcess(); - goto error; - } - - for (i = 0; i < size / sizeof(*kipp); i++) { - kipp = &kip[i]; - py_tuple = Py_BuildValue("Idd", - kipp->ki_tid, - TV2DOUBLE(kipp->ki_rusage.ru_utime), - TV2DOUBLE(kipp->ki_rusage.ru_stime)); - if (py_tuple == NULL) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - } - free(kip); - return py_retlist; - -error: - Py_XDECREF(py_tuple); - Py_DECREF(py_retlist); - if (kip != NULL) - free(kip); - return NULL; -} -#endif - - -/* - * Return a Python tuple (user_time, kernel_time) - */ -static PyObject * -psutil_proc_cpu_times(PyObject *self, PyObject *args) { - long pid; - double user_t, sys_t; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kp) == -1) - return NULL; - // convert from microseconds to seconds -#ifdef __FreeBSD__ - user_t = TV2DOUBLE(kp.ki_rusage.ru_utime); - sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime); -#elif __OpenBSD__ - user_t = KPT2DOUBLE(kp.p_uutime); - sys_t = KPT2DOUBLE(kp.p_ustime); -#endif - return Py_BuildValue("(dd)", user_t, sys_t); -} - - -/* - * Return the number of logical CPUs in the system. - * XXX this could be shared with OSX - */ -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) - Py_RETURN_NONE; // mimic os.cpu_count() - else - return Py_BuildValue("i", ncpu); -} - - -#ifdef __FreeBSD__ -/* - * Return an XML string from which we'll determine the number of - * physical CPU cores in the system. - */ -static PyObject * -psutil_cpu_count_phys(PyObject *self, PyObject *args) { - void *topology = NULL; - size_t size = 0; - PyObject *py_str; - - if (sysctlbyname("kern.sched.topology_spec", NULL, &size, NULL, 0)) - goto error; - - topology = malloc(size); - if (!topology) { - PyErr_NoMemory(); - return NULL; - } - - if (sysctlbyname("kern.sched.topology_spec", topology, &size, NULL, 0)) - goto error; - - py_str = Py_BuildValue("s", topology); - free(topology); - return py_str; - -error: - if (topology != NULL) - free(topology); - Py_RETURN_NONE; -} -#endif - - -/* - * 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_kinfo_proc(pid, &kp) == -1) - return NULL; -#ifdef __FreeBSD__ - return Py_BuildValue("d", TV2DOUBLE(kp.ki_start)); -#elif __OpenBSD__ - return Py_BuildValue("d", KPT2DOUBLE(kp.p_ustart)); -#endif -} - - -/* - * Return a Python float indicating the process create time expressed in - * seconds since the epoch. - */ -static PyObject * -psutil_proc_io_counters(PyObject *self, PyObject *args) { - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kp) == -1) - return NULL; - // there's apparently no way to determine bytes count, hence return -1. - return Py_BuildValue("(llll)", -#ifdef __FreeBSD__ - kp.ki_rusage.ru_inblock, - kp.ki_rusage.ru_oublock, -#elif __OpenBSD__ - kp.p_uru_inblock, - kp.p_uru_oublock, -#endif - -1, - -1); -} - - -#ifdef __OpenBSD__ -#define ptoa(x) ((paddr_t)(x) << PAGE_SHIFT) -#endif - -/* - * Return extended memory info for a process as a Python tuple. - */ -static PyObject * -psutil_proc_memory_info(PyObject *self, PyObject *args) { - long pid; - struct kinfo_proc kp; - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kp) == -1) - return NULL; - return Py_BuildValue( - "(lllll)", -#ifdef __FreeBSD__ - ptoa(kp.ki_rssize), // rss - (long)kp.ki_size, // vms - ptoa(kp.ki_tsize), // text - ptoa(kp.ki_dsize), // data - ptoa(kp.ki_ssize)); // stack -#elif __OpenBSD__ - ptoa(kp.p_vm_rssize), // rss - // vms, this is how ps does it, see: - // http://anoncvs.spacehopper.org/openbsd-src/tree/bin/ps/print.c#n461 - ptoa(kp.p_vm_dsize + kp.p_vm_ssize + kp.p_vm_tsize), // vms - ptoa(kp.p_vm_tsize), // text - ptoa(kp.p_vm_dsize), // data - ptoa(kp.p_vm_ssize)); // stack -#endif -} - - -#ifdef __FreeBSD__ -/* - * Return virtual memory usage statistics. - */ -static PyObject * -psutil_virtual_mem(PyObject *self, PyObject *args) { - unsigned int total, active, inactive, wired, cached, free; - size_t size = sizeof(total); - struct vmtotal vm; - int mib[] = {CTL_VM, VM_METER}; - long pagesize = getpagesize(); -#if __FreeBSD_version > 702101 - long buffers; -#else - int buffers; -#endif - size_t buffers_size = sizeof(buffers); - - if (sysctlbyname("vm.stats.vm.v_page_count", &total, &size, NULL, 0)) - goto error; - if (sysctlbyname("vm.stats.vm.v_active_count", &active, &size, NULL, 0)) - goto error; - if (sysctlbyname("vm.stats.vm.v_inactive_count", - &inactive, &size, NULL, 0)) - goto error; - if (sysctlbyname("vm.stats.vm.v_wire_count", &wired, &size, NULL, 0)) - goto error; - if (sysctlbyname("vm.stats.vm.v_cache_count", &cached, &size, NULL, 0)) - goto error; - if (sysctlbyname("vm.stats.vm.v_free_count", &free, &size, NULL, 0)) - goto error; - if (sysctlbyname("vfs.bufspace", &buffers, &buffers_size, NULL, 0)) - goto error; - - size = sizeof(vm); - if (sysctl(mib, 2, &vm, &size, NULL, 0) != 0) - goto error; - - return Py_BuildValue("KKKKKKKK", - (unsigned long long) total * pagesize, - (unsigned long long) free * pagesize, - (unsigned long long) active * pagesize, - (unsigned long long) inactive * pagesize, - (unsigned long long) wired * pagesize, - (unsigned long long) cached * pagesize, - (unsigned long long) buffers, - (unsigned long long) (vm.t_vmshr + vm.t_rmshr) * pagesize // shared - ); - -error: - PyErr_SetFromErrno(PyExc_OSError); - return NULL; -} -#endif - - -#ifndef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#endif - -#ifdef __FreeBSD__ -/* - * Return swap memory stats (see 'swapinfo' cmdline tool) - */ -static PyObject * -psutil_swap_mem(PyObject *self, PyObject *args) { - kvm_t *kd; - struct kvm_swap kvmsw[1]; - unsigned int swapin, swapout, nodein, nodeout; - size_t size = sizeof(unsigned int); - - kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open failed"); - if (kd == NULL) { - PyErr_SetString(PyExc_RuntimeError, "kvm_open failed"); - return NULL; - } - - if (kvm_getswapinfo(kd, kvmsw, 1, 0) < 0) { - kvm_close(kd); - PyErr_SetString(PyExc_RuntimeError, "kvm_getswapinfo failed"); - return NULL; - } - - kvm_close(kd); - - if (sysctlbyname("vm.stats.vm.v_swapin", &swapin, &size, NULL, 0) == -1) - goto sbn_error; - if (sysctlbyname("vm.stats.vm.v_swapout", &swapout, &size, NULL, 0) == -1) - goto sbn_error; - if (sysctlbyname("vm.stats.vm.v_vnodein", &nodein, &size, NULL, 0) == -1) - goto sbn_error; - if (sysctlbyname("vm.stats.vm.v_vnodeout", &nodeout, &size, NULL, 0) == -1) - goto sbn_error; - - return Py_BuildValue("(iiiII)", - kvmsw[0].ksw_total, // total - kvmsw[0].ksw_used, // used - kvmsw[0].ksw_total - kvmsw[0].ksw_used, // free - swapin + swapout, // swap in - nodein + nodeout); // swap out - -sbn_error: - PyErr_SetFromErrno(PyExc_OSError); - return NULL; -} -#endif - - -/* - * Return a Python tuple representing user, kernel and idle CPU times - */ -static PyObject * -psutil_cpu_times(PyObject *self, PyObject *args) { - long cpu_time[CPUSTATES]; - size_t size = sizeof(cpu_time); - int ret; - -#ifdef __FreeBSD__ - ret = sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0); -#elif __OpenBSD__ - int mib[] = {CTL_KERN, KERN_CPTIME}; - ret = sysctl(mib, 2, &cpu_time, &size, NULL, 0); -#endif - if (ret == -1) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - return Py_BuildValue("(ddddd)", - (double)cpu_time[CP_USER] / CLOCKS_PER_SEC, - (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC, - (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC, - (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC, - (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC - ); -} - - - /* - * Return files opened by process as a list of (path, fd) tuples. - * TODO: this is broken as it may report empty paths. 'procstat' - * utility has the same problem see: - * https://github.com/giampaolo/psutil/issues/595 - */ -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ -static PyObject * -psutil_proc_open_files(PyObject *self, PyObject *args) { - long pid; - int i, cnt; - struct kinfo_file *freep = NULL; - struct kinfo_file *kif; - struct kinfo_proc kipp; - PyObject *py_retlist = PyList_New(0); - PyObject *py_tuple = NULL; - - if (py_retlist == NULL) - return NULL; - if (! PyArg_ParseTuple(args, "l", &pid)) - goto error; - if (psutil_kinfo_proc(pid, &kipp) == -1) - goto error; - - freep = kinfo_getfile(pid, &cnt); - if (freep == NULL) { - psutil_raise_ad_or_nsp(pid); - goto error; - } - - for (i = 0; i < cnt; i++) { - kif = &freep[i]; -#ifdef __FreeBSD__ - if ((kif->kf_type == KF_TYPE_VNODE) && - (kif->kf_vnode_type == KF_VTYPE_VREG)) - { - py_tuple = Py_BuildValue("(si)", kif->kf_path, kif->kf_fd); -#else - if ((kif->f_type == DTYPE_VNODE) && - (kif->v_type == VREG)) - { - py_tuple = Py_BuildValue("(si)", "", kif->fd_fd); -#endif - if (py_tuple == NULL) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - } - } - free(freep); - return py_retlist; - -error: - Py_XDECREF(py_tuple); - Py_DECREF(py_retlist); - if (freep != NULL) - free(freep); - return NULL; -} -#endif - - -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 -/* - * Return files opened by process as a list of (path, fd) tuples - */ -static PyObject * -psutil_proc_num_fds(PyObject *self, PyObject *args) { - long pid; - int cnt; - - struct kinfo_file *freep; - struct kinfo_proc kipp; - - if (! PyArg_ParseTuple(args, "l", &pid)) - return NULL; - if (psutil_kinfo_proc(pid, &kipp) == -1) - return NULL; - - freep = kinfo_getfile(pid, &cnt); - if (freep == NULL) { - psutil_raise_ad_or_nsp(pid); - return NULL; - } - free(freep); - - return Py_BuildValue("i", cnt); -} -#endif - - -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 -/* - * Return process current working directory. - */ -static PyObject * -psutil_proc_cwd(PyObject *self, PyObject *args) { - long pid; - struct kinfo_file *freep = NULL; - struct kinfo_file *kif; - struct kinfo_proc kipp; - PyObject *py_path = NULL; - - int i, cnt; - - if (! PyArg_ParseTuple(args, "l", &pid)) - goto error; - if (psutil_kinfo_proc(pid, &kipp) == -1) - goto error; - - freep = kinfo_getfile(pid, &cnt); - if (freep == NULL) { - psutil_raise_ad_or_nsp(pid); - goto error; - } - - for (i = 0; i < cnt; i++) { - kif = &freep[i]; - if (kif->kf_fd == KF_FD_TYPE_CWD) { - py_path = Py_BuildValue("s", kif->kf_path); - if (!py_path) - goto error; - 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 (py_path == NULL) - py_path = Py_BuildValue("s", ""); - free(freep); - return py_path; - -error: - Py_XDECREF(py_path); - if (freep != NULL) - free(freep); - return NULL; -} -#endif - - -#ifdef __FreeBSD__ -// The tcplist fetching and walking is borrowed from netstat/inet.c. -static char * -psutil_fetch_tcplist(void) { - char *buf; - size_t len; - - for (;;) { - if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) < 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - buf = malloc(len); - if (buf == NULL) { - PyErr_NoMemory(); - return NULL; - } - if (sysctlbyname("net.inet.tcp.pcblist", buf, &len, NULL, 0) < 0) { - free(buf); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - return buf; - } -} - -static int -psutil_sockaddr_port(int family, struct sockaddr_storage *ss) { - struct sockaddr_in6 *sin6; - struct sockaddr_in *sin; - - if (family == AF_INET) { - sin = (struct sockaddr_in *)ss; - return (sin->sin_port); - } - else { - sin6 = (struct sockaddr_in6 *)ss; - return (sin6->sin6_port); - } -} - -static void * -psutil_sockaddr_addr(int family, struct sockaddr_storage *ss) { - struct sockaddr_in6 *sin6; - struct sockaddr_in *sin; - - if (family == AF_INET) { - sin = (struct sockaddr_in *)ss; - return (&sin->sin_addr); - } - else { - sin6 = (struct sockaddr_in6 *)ss; - return (&sin6->sin6_addr); - } -} - -static socklen_t -psutil_sockaddr_addrlen(int family) { - if (family == AF_INET) - return (sizeof(struct in_addr)); - else - return (sizeof(struct in6_addr)); -} - -static int -psutil_sockaddr_matches(int family, int port, void *pcb_addr, - struct sockaddr_storage *ss) { - if (psutil_sockaddr_port(family, ss) != port) - return (0); - return (memcmp(psutil_sockaddr_addr(family, ss), pcb_addr, - psutil_sockaddr_addrlen(family)) == 0); -} - -static struct tcpcb * -psutil_search_tcplist(char *buf, struct kinfo_file *kif) { - struct tcpcb *tp; - struct inpcb *inp; - struct xinpgen *xig, *oxig; - struct xsocket *so; - - oxig = xig = (struct xinpgen *)buf; - for (xig = (struct xinpgen *)((char *)xig + xig->xig_len); - xig->xig_len > sizeof(struct xinpgen); - xig = (struct xinpgen *)((char *)xig + xig->xig_len)) { - tp = &((struct xtcpcb *)xig)->xt_tp; - inp = &((struct xtcpcb *)xig)->xt_inp; - so = &((struct xtcpcb *)xig)->xt_socket; - - if (so->so_type != kif->kf_sock_type || - so->xso_family != kif->kf_sock_domain || - so->xso_protocol != kif->kf_sock_protocol) - continue; - - if (kif->kf_sock_domain == AF_INET) { - if (!psutil_sockaddr_matches( - AF_INET, inp->inp_lport, &inp->inp_laddr, - &kif->kf_sa_local)) - continue; - if (!psutil_sockaddr_matches( - AF_INET, inp->inp_fport, &inp->inp_faddr, - &kif->kf_sa_peer)) - continue; - } else { - if (!psutil_sockaddr_matches( - AF_INET6, inp->inp_lport, &inp->in6p_laddr, - &kif->kf_sa_local)) - continue; - if (!psutil_sockaddr_matches( - AF_INET6, inp->inp_fport, &inp->in6p_faddr, - &kif->kf_sa_peer)) - continue; - } - - return (tp); - } - return NULL; -} - - -// a signaler for connections without an actual status -static int PSUTIL_CONN_NONE = 128; - -/* - * Return connections opened by process. - */ -static PyObject * -psutil_proc_connections(PyObject *self, PyObject *args) { - long pid; - int i, cnt; - - struct kinfo_file *freep = NULL; - struct kinfo_file *kif; - char *tcplist = NULL; - struct tcpcb *tcp; - - PyObject *py_retlist = PyList_New(0); - PyObject *py_tuple = NULL; - PyObject *py_laddr = NULL; - PyObject *py_raddr = NULL; - PyObject *py_af_filter = NULL; - PyObject *py_type_filter = NULL; - PyObject *py_family = NULL; - PyObject *py_type = NULL; - - if (py_retlist == NULL) - return NULL; - if (! PyArg_ParseTuple(args, "lOO", &pid, &py_af_filter, &py_type_filter)) - goto error; - if (!PySequence_Check(py_af_filter) || !PySequence_Check(py_type_filter)) { - PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence"); - goto error; - } - - freep = kinfo_getfile(pid, &cnt); - if (freep == NULL) { - psutil_raise_ad_or_nsp(pid); - goto error; - } - - tcplist = psutil_fetch_tcplist(); - if (tcplist == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - for (i = 0; i < cnt; i++) { - int lport, rport, state; - char lip[200], rip[200]; - char path[PATH_MAX]; - int inseq; - py_tuple = NULL; - py_laddr = NULL; - py_raddr = NULL; - - kif = &freep[i]; - if (kif->kf_type == KF_TYPE_SOCKET) { - // apply filters - py_family = PyLong_FromLong((long)kif->kf_sock_domain); - inseq = PySequence_Contains(py_af_filter, py_family); - Py_DECREF(py_family); - if (inseq == 0) - continue; - py_type = PyLong_FromLong((long)kif->kf_sock_type); - inseq = PySequence_Contains(py_type_filter, py_type); - Py_DECREF(py_type); - if (inseq == 0) - continue; - // IPv4 / IPv6 socket - if ((kif->kf_sock_domain == AF_INET) || - (kif->kf_sock_domain == AF_INET6)) { - // fill status - state = PSUTIL_CONN_NONE; - if (kif->kf_sock_type == SOCK_STREAM) { - tcp = psutil_search_tcplist(tcplist, kif); - if (tcp != NULL) - state = (int)tcp->t_state; - } - - // build addr and port - inet_ntop( - kif->kf_sock_domain, - psutil_sockaddr_addr(kif->kf_sock_domain, - &kif->kf_sa_local), - lip, - sizeof(lip)); - inet_ntop( - kif->kf_sock_domain, - psutil_sockaddr_addr(kif->kf_sock_domain, - &kif->kf_sa_peer), - rip, - sizeof(rip)); - lport = htons(psutil_sockaddr_port(kif->kf_sock_domain, - &kif->kf_sa_local)); - rport = htons(psutil_sockaddr_port(kif->kf_sock_domain, - &kif->kf_sa_peer)); - - // construct python tuple/list - py_laddr = Py_BuildValue("(si)", lip, lport); - if (!py_laddr) - goto error; - if (rport != 0) - py_raddr = Py_BuildValue("(si)", rip, rport); - else - py_raddr = Py_BuildValue("()"); - if (!py_raddr) - goto error; - py_tuple = Py_BuildValue( - "(iiiNNi)", - kif->kf_fd, - kif->kf_sock_domain, - kif->kf_sock_type, - py_laddr, - py_raddr, - state - ); - if (!py_tuple) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - } - // UNIX socket - else if (kif->kf_sock_domain == AF_UNIX) { - struct sockaddr_un *sun; - - sun = (struct sockaddr_un *)&kif->kf_sa_local; - snprintf( - path, sizeof(path), "%.*s", - (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))), - sun->sun_path); - - py_tuple = Py_BuildValue( - "(iiisOi)", - kif->kf_fd, - kif->kf_sock_domain, - kif->kf_sock_type, - path, - Py_None, - PSUTIL_CONN_NONE - ); - if (!py_tuple) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - Py_INCREF(Py_None); - } - } - } - free(freep); - free(tcplist); - return py_retlist; - -error: - Py_XDECREF(py_tuple); - Py_XDECREF(py_laddr); - Py_XDECREF(py_raddr); - Py_DECREF(py_retlist); - if (freep != NULL) - free(freep); - if (tcplist != NULL) - free(tcplist); - return NULL; -} -#endif - - -#ifdef __FreeBSD__ -static PyObject * -psutil_per_cpu_times(PyObject *self, PyObject *args) { - static int maxcpus; - int mib[2]; - int ncpu; - size_t len; - size_t size; - int i; - PyObject *py_retlist = PyList_New(0); - PyObject *py_cputime = NULL; - - if (py_retlist == NULL) - return NULL; - - // retrieve maxcpus value - size = sizeof(maxcpus); - if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) { - Py_DECREF(py_retlist); - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - long cpu_time[maxcpus][CPUSTATES]; - - // retrieve the number of cpus - mib[0] = CTL_HW; - mib[1] = HW_NCPU; - len = sizeof(ncpu); - if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - // per-cpu info - size = sizeof(cpu_time); - if (sysctlbyname("kern.cp_times", &cpu_time, &size, NULL, 0) == -1) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - for (i = 0; i < ncpu; i++) { - py_cputime = Py_BuildValue( - "(ddddd)", - (double)cpu_time[i][CP_USER] / CLOCKS_PER_SEC, - (double)cpu_time[i][CP_NICE] / CLOCKS_PER_SEC, - (double)cpu_time[i][CP_SYS] / CLOCKS_PER_SEC, - (double)cpu_time[i][CP_IDLE] / CLOCKS_PER_SEC, - (double)cpu_time[i][CP_INTR] / CLOCKS_PER_SEC); - if (!py_cputime) - goto error; - if (PyList_Append(py_retlist, py_cputime)) - goto error; - Py_DECREF(py_cputime); - } - - return py_retlist; - -error: - Py_XDECREF(py_cputime); - Py_DECREF(py_retlist); - return NULL; -} -#endif - - -#ifdef __FreeBSD__ -// remove spaces from string -void remove_spaces(char *str) { - char *p1 = str; - char *p2 = str; - do - while (*p2 == ' ') - p2++; - while (*p1++ = *p2++); -} - - -/* - * 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) { - long pid; - int ptrwidth; - int i, cnt; - char addr[1000]; - char perms[4]; - const char *path; - struct kinfo_proc kp; - struct kinfo_vmentry *freep = NULL; - struct kinfo_vmentry *kve; - ptrwidth = 2 * sizeof(void *); - PyObject *py_tuple = NULL; - PyObject *py_retlist = PyList_New(0); - - if (py_retlist == NULL) - return NULL; - if (! PyArg_ParseTuple(args, "l", &pid)) - goto error; - if (psutil_kinfo_proc(pid, &kp) == -1) - goto error; - - freep = kinfo_getvmmap(pid, &cnt); - if (freep == NULL) { - psutil_raise_ad_or_nsp(pid); - goto error; - } - for (i = 0; i < cnt; i++) { - py_tuple = NULL; - kve = &freep[i]; - addr[0] = '\0'; - perms[0] = '\0'; - sprintf(addr, "%#*jx-%#*jx", ptrwidth, (uintmax_t)kve->kve_start, - ptrwidth, (uintmax_t)kve->kve_end); - remove_spaces(addr); - strlcat(perms, kve->kve_protection & KVME_PROT_READ ? "r" : "-", - sizeof(perms)); - strlcat(perms, kve->kve_protection & KVME_PROT_WRITE ? "w" : "-", - sizeof(perms)); - strlcat(perms, kve->kve_protection & KVME_PROT_EXEC ? "x" : "-", - sizeof(perms)); - - if (strlen(kve->kve_path) == 0) { - switch (kve->kve_type) { - case KVME_TYPE_NONE: - path = "[none]"; - break; - case KVME_TYPE_DEFAULT: - path = "[default]"; - break; - case KVME_TYPE_VNODE: - path = "[vnode]"; - break; - case KVME_TYPE_SWAP: - path = "[swap]"; - break; - case KVME_TYPE_DEVICE: - path = "[device]"; - break; - case KVME_TYPE_PHYS: - path = "[phys]"; - break; - case KVME_TYPE_DEAD: - path = "[dead]"; - break; - case KVME_TYPE_SG: - path = "[sg]"; - break; - case KVME_TYPE_UNKNOWN: - path = "[unknown]"; - break; - default: - path = "[?]"; - break; - } - } - else { - path = kve->kve_path; - } - - py_tuple = Py_BuildValue("sssiiii", - addr, // "start-end" address - perms, // "rwx" permissions - path, // path - kve->kve_resident, // rss - kve->kve_private_resident, // private - kve->kve_ref_count, // ref count - kve->kve_shadow_count); // shadow count - if (!py_tuple) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - } - free(freep); - return py_retlist; - -error: - Py_XDECREF(py_tuple); - Py_DECREF(py_retlist); - if (freep != NULL) - free(freep); - return NULL; -} -#endif - - -/* - * 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[200]; - 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++) { - py_tuple = NULL; - 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)); -#ifdef __FreeBSD__ - 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_SUIDDIR) - strlcat(opts, ",suiddir", sizeof(opts)); - if (flags & MNT_SOFTDEP) - strlcat(opts, ",softdep", sizeof(opts)); - if (flags & MNT_NOSYMFOLLOW) - strlcat(opts, ",nosymfollow", sizeof(opts)); - if (flags & MNT_GJOURNAL) - strlcat(opts, ",gjournal", sizeof(opts)); - if (flags & MNT_MULTILABEL) - strlcat(opts, ",multilabel", sizeof(opts)); - if (flags & MNT_ACLS) - strlcat(opts, ",acls", sizeof(opts)); - if (flags & MNT_NOATIME) - strlcat(opts, ",noatime", sizeof(opts)); - if (flags & MNT_NOCLUSTERR) - strlcat(opts, ",noclusterr", sizeof(opts)); - if (flags & MNT_NOCLUSTERW) - strlcat(opts, ",noclusterw", sizeof(opts)); - if (flags & MNT_NFS4ACLS) - strlcat(opts, ",nfs4acls", sizeof(opts)); -#elif __OpenBSD__ - 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_ASYNC) - strlcat(opts, ",async", sizeof(opts)); - if (flags & MNT_SOFTDEP) - strlcat(opts, ",softdep", sizeof(opts)); - if (flags & MNT_NOATIME) - strlcat(opts, ",noatime", sizeof(opts)); -#endif - 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 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_IFLIST; // 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; ) { - py_ifc_info = NULL; - ifm = (struct if_msghdr *)next; - next += ifm->ifm_msglen; - - if (ifm->ifm_type == RTM_IFINFO) { - struct if_msghdr *if2m = (struct if_msghdr *)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; - // XXX: ignore usbus interfaces: - // http://lists.freebsd.org/pipermail/freebsd-current/ - // 2011-October/028752.html - // 'ifconfig -a' doesn't show them, nor do we. - if (strncmp(ifc_name, "usbus", 5) == 0) - continue; - - 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; -} - - -#ifdef __FreeBSD__ -/* - * Return a Python dict of tuples for disk I/O information - */ -static PyObject * -psutil_disk_io_counters(PyObject *self, PyObject *args) { - int i; - struct statinfo stats; - - PyObject *py_retdict = PyDict_New(); - PyObject *py_disk_info = NULL; - - if (py_retdict == NULL) - return NULL; - if (devstat_checkversion(NULL) < 0) { - PyErr_Format(PyExc_RuntimeError, "devstat_checkversion() failed"); - goto error; - } - - stats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); - if (stats.dinfo == NULL) { - PyErr_NoMemory(); - goto error; - } - bzero(stats.dinfo, sizeof(struct devinfo)); - - if (devstat_getdevs(NULL, &stats) == -1) { - PyErr_Format(PyExc_RuntimeError, "devstat_getdevs() failed"); - goto error; - } - - for (i = 0; i < stats.dinfo->numdevs; i++) { - py_disk_info = NULL; - 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) BT2MSEC(current.duration[DEVSTAT_READ]), // r time - (long long) BT2MSEC(current.duration[DEVSTAT_WRITE]) // w time - ); // finished transactions - if (!py_disk_info) - goto error; - if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info)) - goto error; - Py_DECREF(py_disk_info); - } - - if (stats.dinfo->mem_ptr) - free(stats.dinfo->mem_ptr); - free(stats.dinfo); - return py_retdict; - -error: - Py_XDECREF(py_disk_info); - Py_DECREF(py_retdict); - if (stats.dinfo != NULL) - free(stats.dinfo); - return NULL; -} -#endif - - -/* - * Return currently connected users as a list of tuples. - */ -static PyObject * -psutil_users(PyObject *self, PyObject *args) { - PyObject *py_retlist = PyList_New(0); - PyObject *py_tuple = NULL; - - if (py_retlist == NULL) - return NULL; - -#if __FreeBSD_version < 900000 || __OpenBSD__ - struct utmp ut; - FILE *fp; - - fp = fopen(_PATH_UTMP, "r"); - if (fp == NULL) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - while (fread(&ut, sizeof(ut), 1, fp) == 1) { - if (*ut.ut_name == '\0') - continue; - py_tuple = Py_BuildValue( - "(sssf)", - ut.ut_name, // username - ut.ut_line, // tty - ut.ut_host, // hostname - (float)ut.ut_time); // start time - if (!py_tuple) { - fclose(fp); - goto error; - } - if (PyList_Append(py_retlist, py_tuple)) { - fclose(fp); - goto error; - } - Py_DECREF(py_tuple); - } - - fclose(fp); -#else - struct utmpx *utx; - - while ((utx = getutxent()) != NULL) { - if (utx->ut_type != USER_PROCESS) - continue; - py_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 (!py_tuple) { - endutxent(); - goto error; - } - if (PyList_Append(py_retlist, py_tuple)) { - endutxent(); - goto error; - } - Py_DECREF(py_tuple); - } - - endutxent(); -#endif - return py_retlist; - -error: - Py_XDECREF(py_tuple); - Py_DECREF(py_retlist); - return NULL; -} - - -#ifdef __FreeBSD__ -/* - * System-wide open connections. - */ -#define HASHSIZE 1009 -static struct xfile *psutil_xfiles; -static int psutil_nxfiles; - -int -psutil_populate_xfiles() { - size_t len; - - if ((psutil_xfiles = malloc(len = sizeof *psutil_xfiles)) == NULL) { - PyErr_NoMemory(); - return 0; - } - while (sysctlbyname("kern.file", psutil_xfiles, &len, 0, 0) == -1) { - if (errno != ENOMEM) { - PyErr_SetFromErrno(0); - return 0; - } - len *= 2; - if ((psutil_xfiles = realloc(psutil_xfiles, len)) == NULL) { - PyErr_NoMemory(); - return 0; - } - } - if (len > 0 && psutil_xfiles->xf_size != sizeof *psutil_xfiles) { - PyErr_Format(PyExc_RuntimeError, "struct xfile size mismatch"); - return 0; - } - psutil_nxfiles = len / sizeof *psutil_xfiles; - return 1; -} - -int -psutil_get_pid_from_sock(int sock_hash) { - struct xfile *xf; - int hash, n; - for (xf = psutil_xfiles, n = 0; n < psutil_nxfiles; ++n, ++xf) { - if (xf->xf_data == NULL) - continue; - hash = (int)((uintptr_t)xf->xf_data % HASHSIZE); - if (sock_hash == hash) - return xf->xf_pid; - } - return -1; -} - - -// Reference: -// https://gitorious.org/freebsd/freebsd/source/ -// f1d6f4778d2044502209708bc167c05f9aa48615:usr.bin/sockstat/sockstat.c -int psutil_gather_inet(int proto, PyObject *py_retlist) { - struct xinpgen *xig, *exig; - struct xinpcb *xip; - struct xtcpcb *xtp; - struct inpcb *inp; - struct xsocket *so; - const char *varname = NULL; - size_t len, bufsize; - void *buf; - int hash; - int retry; - int type; - - PyObject *py_tuple = NULL; - PyObject *py_laddr = NULL; - PyObject *py_raddr = NULL; - - switch (proto) { - case IPPROTO_TCP: - varname = "net.inet.tcp.pcblist"; - type = SOCK_STREAM; - break; - case IPPROTO_UDP: - varname = "net.inet.udp.pcblist"; - type = SOCK_DGRAM; - break; - } - - buf = NULL; - bufsize = 8192; - retry = 5; - do { - for (;;) { - buf = realloc(buf, bufsize); - if (buf == NULL) - continue; // XXX - len = bufsize; - if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) - break; - if (errno != ENOMEM) { - PyErr_SetFromErrno(0); - goto error; - } - bufsize *= 2; - } - xig = (struct xinpgen *)buf; - exig = (struct xinpgen *)(void *)((char *)buf + len - sizeof *exig); - if (xig->xig_len != sizeof *xig || exig->xig_len != sizeof *exig) { - PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch"); - goto error; - } - } while (xig->xig_gen != exig->xig_gen && retry--); - - - for (;;) { - int lport, rport, pid, status, family; - - xig = (struct xinpgen *)(void *)((char *)xig + xig->xig_len); - if (xig >= exig) - break; - - switch (proto) { - case IPPROTO_TCP: - xtp = (struct xtcpcb *)xig; - if (xtp->xt_len != sizeof *xtp) { - PyErr_Format(PyExc_RuntimeError, - "struct xtcpcb size mismatch"); - goto error; - } - inp = &xtp->xt_inp; - so = &xtp->xt_socket; - status = xtp->xt_tp.t_state; - break; - case IPPROTO_UDP: - xip = (struct xinpcb *)xig; - if (xip->xi_len != sizeof *xip) { - PyErr_Format(PyExc_RuntimeError, - "struct xinpcb size mismatch"); - goto error; - } - inp = &xip->xi_inp; - so = &xip->xi_socket; - status = PSUTIL_CONN_NONE; - break; - default: - PyErr_Format(PyExc_RuntimeError, "invalid proto"); - goto error; - } - - char lip[200], rip[200]; - - hash = (int)((uintptr_t)so->xso_so % HASHSIZE); - pid = psutil_get_pid_from_sock(hash); - if (pid < 0) - continue; - lport = ntohs(inp->inp_lport); - rport = ntohs(inp->inp_fport); - - if (inp->inp_vflag & INP_IPV4) { - family = AF_INET; - inet_ntop(AF_INET, &inp->inp_laddr.s_addr, lip, sizeof(lip)); - inet_ntop(AF_INET, &inp->inp_faddr.s_addr, rip, sizeof(rip)); - } - else if (inp->inp_vflag & INP_IPV6) { - family = AF_INET6; - inet_ntop(AF_INET6, &inp->in6p_laddr.s6_addr, lip, sizeof(lip)); - inet_ntop(AF_INET6, &inp->in6p_faddr.s6_addr, rip, sizeof(rip)); - } - - // construct python tuple/list - py_laddr = Py_BuildValue("(si)", lip, lport); - if (!py_laddr) - goto error; - if (rport != 0) - py_raddr = Py_BuildValue("(si)", rip, rport); - else - py_raddr = Py_BuildValue("()"); - if (!py_raddr) - goto error; - py_tuple = Py_BuildValue("(iiiNNii)", -1, family, type, py_laddr, - py_raddr, status, pid); - if (!py_tuple) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - } - - free(buf); - return 1; - -error: - Py_XDECREF(py_tuple); - Py_XDECREF(py_laddr); - Py_XDECREF(py_raddr); - free(buf); - return 0; -} - - -int psutil_gather_unix(int proto, PyObject *py_retlist) { - struct xunpgen *xug, *exug; - struct xunpcb *xup; - const char *varname = NULL; - const char *protoname = NULL; - size_t len; - size_t bufsize; - void *buf; - int hash; - int retry; - int pid; - struct sockaddr_un *sun; - char path[PATH_MAX]; - - PyObject *py_tuple = NULL; - PyObject *py_laddr = NULL; - PyObject *py_raddr = NULL; - - switch (proto) { - case SOCK_STREAM: - varname = "net.local.stream.pcblist"; - protoname = "stream"; - break; - case SOCK_DGRAM: - varname = "net.local.dgram.pcblist"; - protoname = "dgram"; - break; - } - - buf = NULL; - bufsize = 8192; - retry = 5; - - do { - for (;;) { - buf = realloc(buf, bufsize); - if (buf == NULL) { - PyErr_NoMemory(); - goto error; - } - len = bufsize; - if (sysctlbyname(varname, buf, &len, NULL, 0) == 0) - break; - if (errno != ENOMEM) { - PyErr_SetFromErrno(0); - goto error; - } - bufsize *= 2; - } - xug = (struct xunpgen *)buf; - exug = (struct xunpgen *)(void *) - ((char *)buf + len - sizeof *exug); - if (xug->xug_len != sizeof *xug || exug->xug_len != sizeof *exug) { - PyErr_Format(PyExc_RuntimeError, "struct xinpgen size mismatch"); - goto error; - } - } while (xug->xug_gen != exug->xug_gen && retry--); - - for (;;) { - xug = (struct xunpgen *)(void *)((char *)xug + xug->xug_len); - if (xug >= exug) - break; - xup = (struct xunpcb *)xug; - if (xup->xu_len != sizeof *xup) - goto error; - - hash = (int)((uintptr_t) xup->xu_socket.xso_so % HASHSIZE); - pid = psutil_get_pid_from_sock(hash); - if (pid < 0) - continue; - - sun = (struct sockaddr_un *)&xup->xu_addr; - snprintf(path, sizeof(path), "%.*s", - (int)(sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))), - sun->sun_path); - - py_tuple = Py_BuildValue("(iiisOii)", -1, AF_UNIX, proto, path, - Py_None, PSUTIL_CONN_NONE, pid); - if (!py_tuple) - goto error; - if (PyList_Append(py_retlist, py_tuple)) - goto error; - Py_DECREF(py_tuple); - Py_INCREF(Py_None); - } - - free(buf); - return 1; - -error: - Py_XDECREF(py_tuple); - Py_XDECREF(py_laddr); - Py_XDECREF(py_raddr); - free(buf); - return 0; -} - - -/* - * Return system-wide open connections. - */ -static PyObject* -psutil_net_connections(PyObject* self, PyObject* args) { - PyObject *py_retlist = PyList_New(0); - - if (py_retlist == NULL) - return NULL; - if (psutil_populate_xfiles() != 1) - goto error; - if (psutil_gather_inet(IPPROTO_TCP, py_retlist) == 0) - goto error; - if (psutil_gather_inet(IPPROTO_UDP, py_retlist) == 0) - goto error; - if (psutil_gather_unix(SOCK_STREAM, py_retlist) == 0) - goto error; - if (psutil_gather_unix(SOCK_DGRAM, py_retlist) == 0) - goto error; - - free(psutil_xfiles); - return py_retlist; - -error: - Py_DECREF(py_retlist); - free(psutil_xfiles); - return NULL; -} - - -/* - * Get process CPU affinity. - * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c - */ -static PyObject* -psutil_proc_cpu_affinity_get(PyObject* self, PyObject* args) { - long pid; - int ret; - int i; - cpuset_t mask; - PyObject* py_retlist; - PyObject* py_cpu_num; - - if (!PyArg_ParseTuple(args, "i", &pid)) - return NULL; - ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, - sizeof(mask), &mask); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - return NULL; - } - - py_retlist = PyList_New(0); - if (py_retlist == NULL) - return NULL; - - for (i = 0; i < CPU_SETSIZE; i++) { - if (CPU_ISSET(i, &mask)) { - py_cpu_num = Py_BuildValue("i", i); - if (py_cpu_num == NULL) - goto error; - if (PyList_Append(py_retlist, py_cpu_num)) - goto error; - } - } - - return py_retlist; - -error: - Py_XDECREF(py_cpu_num); - Py_DECREF(py_retlist); - return NULL; -} - - -/* - * Set process CPU affinity. - * Reference: http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c - */ -static PyObject * -psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) { - long pid; - int i; - int seq_len; - int ret; - cpuset_t cpu_set; - PyObject *py_cpu_set; - PyObject *py_cpu_seq = NULL; - - if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set)) - return NULL; - - py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer"); - if (!py_cpu_seq) - return NULL; - seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq); - - // calculate the mask - CPU_ZERO(&cpu_set); - for (i = 0; i < seq_len; i++) { - PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i); -#if PY_MAJOR_VERSION >= 3 - long value = PyLong_AsLong(item); -#else - long value = PyInt_AsLong(item); -#endif - if (value == -1 && PyErr_Occurred()) - goto error; - CPU_SET(value, &cpu_set); - } - - // set affinity - ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid, - sizeof(cpu_set), &cpu_set); - if (ret != 0) { - PyErr_SetFromErrno(PyExc_OSError); - goto error; - } - - Py_DECREF(py_cpu_seq); - Py_RETURN_NONE; - -error: - if (py_cpu_seq != NULL) - Py_DECREF(py_cpu_seq); - return NULL; -} -#endif - -/* - * 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_connections", psutil_proc_connections, METH_VARARGS, - "Return connections opened by process"}, - {"proc_cmdline", psutil_proc_cmdline, METH_VARARGS, - "Return process cmdline as a list of cmdline arguments"}, - {"proc_ppid", psutil_proc_ppid, METH_VARARGS, - "Return process ppid as an integer"}, - {"proc_uids", psutil_proc_uids, METH_VARARGS, - "Return process real effective and saved user ids as a Python tuple"}, - {"proc_gids", psutil_proc_gids, METH_VARARGS, - "Return process real effective and saved group ids as a Python tuple"}, - {"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 extended memory info for a process as a Python tuple."}, - {"proc_num_ctx_switches", psutil_proc_num_ctx_switches, METH_VARARGS, - "Return the number of context switches performed by process"}, - {"proc_threads", psutil_proc_threads, METH_VARARGS, - "Return process threads"}, - {"proc_status", psutil_proc_status, METH_VARARGS, - "Return process status as an integer"}, - {"proc_io_counters", psutil_proc_io_counters, METH_VARARGS, - "Return process IO counters"}, - {"proc_tty_nr", psutil_proc_tty_nr, METH_VARARGS, - "Return process tty (terminal) number"}, - {"proc_cwd", psutil_proc_cwd, METH_VARARGS, - "Return process current working directory."}, -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ - {"proc_num_fds", psutil_proc_num_fds, METH_VARARGS, - "Return the number of file descriptors opened by this process"}, -#endif -#if defined(__FreeBSD_version) && __FreeBSD_version >= 800000 || __OpenBSD__ - {"proc_open_files", psutil_proc_open_files, METH_VARARGS, - "Return files opened by process as a list of (path, fd) tuples"}, -#endif - -#ifdef __FreeBSD__ - {"proc_exe", psutil_proc_exe, METH_VARARGS, - "Return process pathname executable"}, - {"proc_num_threads", psutil_proc_num_threads, METH_VARARGS, - "Return number of threads used by process"}, - {"proc_memory_maps", psutil_proc_memory_maps, METH_VARARGS, - "Return a list of tuples for every process's memory map"}, - {"proc_cpu_affinity_get", psutil_proc_cpu_affinity_get, METH_VARARGS, - "Return process CPU affinity."}, - {"proc_cpu_affinity_set", psutil_proc_cpu_affinity_set, METH_VARARGS, - "Set process CPU affinity."}, - {"cpu_count_phys", psutil_cpu_count_phys, METH_VARARGS, - "Return an XML string to determine the number physical CPUs."}, -#endif - - // --- 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"}, - {"virtual_mem", psutil_virtual_mem, METH_VARARGS, - "Return system virtual memory usage statistics"}, - {"swap_mem", psutil_swap_mem, METH_VARARGS, - "Return swap mem stats"}, - {"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 a Python dict of tuples for disk I/O information"}, - {"users", psutil_users, METH_VARARGS, - "Return currently connected users as a list of tuples"}, -#ifdef __FreeBSD__ - {"net_connections", psutil_net_connections, METH_VARARGS, - "Return system-wide open connections."}, -#endif - {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_bsd_traverse(PyObject *m, visitproc visit, void *arg) { - Py_VISIT(GETSTATE(m)->error); - return 0; -} - -static int -psutil_bsd_clear(PyObject *m) { - Py_CLEAR(GETSTATE(m)->error); - return 0; -} - -static struct PyModuleDef - moduledef = { - PyModuleDef_HEAD_INIT, - "psutil_bsd", - NULL, - sizeof(struct module_state), - PsutilMethods, - NULL, - psutil_bsd_traverse, - psutil_bsd_clear, - NULL -}; - -#define INITERROR return NULL - -PyMODINIT_FUNC PyInit__psutil_bsd(void) - -#else -#define INITERROR return - -void init_psutil_bsd(void) -#endif -{ -#if PY_MAJOR_VERSION >= 3 - PyObject *module = PyModule_Create(&moduledef); -#else - PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods); -#endif - PyModule_AddIntConstant(module, "version", PSUTIL_VERSION); - // process status constants - -#ifdef __FreeBSD__ - 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); - PyModule_AddIntConstant(module, "SWAIT", SWAIT); - PyModule_AddIntConstant(module, "SLOCK", SLOCK); -#elif __OpenBSD__ - 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); // unused - PyModule_AddIntConstant(module, "SDEAD", SDEAD); - PyModule_AddIntConstant(module, "SONPROC", SONPROC); -#endif - - // 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); - // PSUTIL_CONN_NONE - PyModule_AddIntConstant(module, "PSUTIL_CONN_NONE", 128); - - if (module == NULL) - INITERROR; -#if PY_MAJOR_VERSION >= 3 - return module; -#endif -} |