From aa2946513b85161f732963d1b7e30d0fe7d00d79 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Thu, 13 Apr 2023 15:14:30 +0200 Subject: OpenBSD: rewrite net_connections() from scratch (#2230) --- HISTORY.rst | 7 ++ MANIFEST.in | 2 + docs/index.rst | 19 ++-- psutil/_psbsd.py | 46 ++++---- psutil/_psutil_bsd.c | 7 +- psutil/_psutil_osx.c | 1 + psutil/arch/openbsd/proc.c | 223 +-------------------------------------- psutil/arch/openbsd/proc.h | 2 - psutil/arch/openbsd/socks.c | 180 +++++++++++++++++++++++++++++++ psutil/arch/openbsd/socks.h | 8 ++ psutil/tests/test_connections.py | 14 +-- psutil/tests/test_unicode.py | 13 +-- setup.py | 1 + 13 files changed, 246 insertions(+), 277 deletions(-) create mode 100644 psutil/arch/openbsd/socks.c create mode 100644 psutil/arch/openbsd/socks.h diff --git a/HISTORY.rst b/HISTORY.rst index 8d22111a..dcb6a0d2 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -9,9 +9,16 @@ `KeyError` bit deriving from a missed cache hit. - 2217_: print the full traceback when a `DeprecationWarning` or `UserWarning` is raised. +- 2230_, [OpenBSD]: `psutil.net_connections`_ implementation was rewritten from + scratch: + - We're now able to retrieve the path of AF_UNIX sockets (before it was an + empty string) + - The function is faster since it no longer iterates over all processes. + - No longer produces duplicate connection entries. **Bug fixes** +- 1043_, [OpenBSD] `psutil.net_connections`_ returns duplicate entries. - 1915_, [Linux]: on certain kernels, ``"MemAvailable"`` field from ``/proc/meminfo`` returns ``0`` (possibly a kernel bug), in which case we calculate an approximation for ``available`` memory which matches "free" diff --git a/MANIFEST.in b/MANIFEST.in index 0ed5c320..2653b691 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -73,6 +73,8 @@ include psutil/arch/openbsd/mem.c include psutil/arch/openbsd/mem.h include psutil/arch/openbsd/proc.c include psutil/arch/openbsd/proc.h +include psutil/arch/openbsd/socks.c +include psutil/arch/openbsd/socks.h include psutil/arch/osx/cpu.c include psutil/arch/osx/cpu.h include psutil/arch/osx/process_info.c diff --git a/docs/index.rst b/docs/index.rst index 119102a8..c722ee21 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -659,19 +659,18 @@ Network (Solaris) UNIX sockets are not supported. .. note:: - (Linux, FreeBSD) "raddr" field for UNIX sockets is always set to "". - This is a limitation of the OS. - - .. note:: - (OpenBSD) "laddr" and "raddr" fields for UNIX sockets are always set to - "". This is a limitation of the OS. + (Linux, FreeBSD, OpenBSD) *raddr* field for UNIX sockets is always set to + ``""`` (empty string). This is a limitation of the OS. .. versionadded:: 2.1.0 .. versionchanged:: 5.3.0 : socket "fd" is now set for real instead of being ``-1``. - .. versionchanged:: 5.3.0 : "laddr" and "raddr" are named tuples. + .. versionchanged:: 5.3.0 : *laddr* and *raddr* are named tuples. + + .. versionchanged:: 5.9.5 : OpenBSD: retrieve *laddr* path for AF_UNIX + sockets (before it was an empty string). .. function:: net_if_addrs() @@ -1943,18 +1942,18 @@ Process class (Solaris) UNIX sockets are not supported. .. note:: - (Linux, FreeBSD) "raddr" field for UNIX sockets is always set to "". + (Linux, FreeBSD) *raddr* field for UNIX sockets is always set to "". This is a limitation of the OS. .. note:: - (OpenBSD) "laddr" and "raddr" fields for UNIX sockets are always set to + (OpenBSD) *laddr* and *raddr* fields for UNIX sockets are always set to "". This is a limitation of the OS. .. note:: (AIX) :class:`psutil.AccessDenied` is always raised unless running as root (lsof does the same). - .. versionchanged:: 5.3.0 : "laddr" and "raddr" are named tuples. + .. versionchanged:: 5.3.0 : *laddr* and *raddr* are named tuples. .. method:: is_running() diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index a0f07ee2..1180a94e 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -401,26 +401,23 @@ def net_if_stats(): def net_connections(kind): """System-wide network connections.""" - if OPENBSD: - ret = [] - for pid in pids(): - try: - cons = Process(pid).connections(kind) - except (NoSuchProcess, ZombieProcess): - continue - else: - for conn in cons: - conn = list(conn) - conn.append(pid) - ret.append(_common.sconn(*conn)) - return ret - if kind not in _common.conn_tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in conn_tmap]))) families, types = conn_tmap[kind] ret = set() - if NETBSD: + + if OPENBSD: + rawlist = cext.net_connections(-1, families, types) + ret = set() + for item in rawlist: + fd, fam, type, laddr, raddr, status, pid = item + if fam in families and type in types: + nt = conn_to_ntuple(fd, fam, type, laddr, raddr, status, + TCP_STATUSES, pid) + ret.add(nt) + return list(ret) + elif NETBSD: rawlist = cext.net_connections(-1) else: rawlist = cext.net_connections() @@ -773,9 +770,9 @@ class Process(object): if kind not in conn_tmap: raise ValueError("invalid %r kind argument; choose between %s" % (kind, ', '.join([repr(x) for x in conn_tmap]))) + families, types = conn_tmap[kind] if NETBSD: - families, types = conn_tmap[kind] ret = [] rawlist = cext.net_connections(self.pid) for item in rawlist: @@ -786,9 +783,22 @@ class Process(object): TCP_STATUSES) ret.append(nt) self._assert_alive() - return list(ret) + return ret - families, types = conn_tmap[kind] + elif OPENBSD: + ret = [] + rawlist = cext.net_connections(self.pid, families, types) + for item in rawlist: + fd, fam, type, laddr, raddr, status, pid = item + assert pid == self.pid + if fam in families and type in types: + nt = conn_to_ntuple(fd, fam, type, laddr, raddr, status, + TCP_STATUSES) + ret.append(nt) + self._assert_alive() + return ret + + # FreeBSD rawlist = cext.proc_connections(self.pid, families, types) ret = [] for item in rawlist: diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 3c3f50e3..b2afbb28 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -84,6 +84,7 @@ #include "arch/openbsd/disk.h" #include "arch/openbsd/mem.h" #include "arch/openbsd/proc.h" + #include "arch/openbsd/socks.h" #include #include // for VREG @@ -1064,7 +1065,7 @@ static PyMethodDef mod_methods[] = { {"proc_name", psutil_proc_name, METH_VARARGS}, {"proc_oneshot_info", psutil_proc_oneshot_info, METH_VARARGS}, {"proc_threads", psutil_proc_threads, METH_VARARGS}, -#if defined(PSUTIL_FREEBSD) || defined(PSUTIL_OPENBSD) +#if defined(PSUTIL_FREEBSD) {"proc_connections", psutil_proc_connections, METH_VARARGS}, #endif {"proc_cwd", psutil_proc_cwd, METH_VARARGS}, @@ -1093,6 +1094,7 @@ static PyMethodDef mod_methods[] = { {"cpu_times", psutil_cpu_times, METH_VARARGS}, {"disk_io_counters", psutil_disk_io_counters, METH_VARARGS}, {"disk_partitions", psutil_disk_partitions, METH_VARARGS}, + {"net_connections", psutil_net_connections, METH_VARARGS}, {"net_io_counters", psutil_net_io_counters, METH_VARARGS}, {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS}, {"pids", psutil_pids, METH_VARARGS}, @@ -1102,9 +1104,6 @@ static PyMethodDef mod_methods[] = { #if defined(PSUTIL_FREEBSD) || defined(PSUTIL_OPENBSD) {"cpu_freq", psutil_cpu_freq, METH_VARARGS}, #endif -#if defined(PSUTIL_FREEBSD) || defined(PSUTIL_NETBSD) - {"net_connections", psutil_net_connections, METH_VARARGS}, -#endif #if defined(PSUTIL_FREEBSD) {"sensors_battery", psutil_sensors_battery, METH_VARARGS}, {"sensors_cpu_temperature", psutil_sensors_cpu_temperature, METH_VARARGS}, diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c index ed29b33b..9ba0fd2b 100644 --- a/psutil/_psutil_osx.c +++ b/psutil/_psutil_osx.c @@ -1152,6 +1152,7 @@ psutil_proc_connections(PyObject *self, PyObject *args) { // int fd, family, type, lport, rport, state; + // TODO: use INET6_ADDRSTRLEN instead of 200 char lip[200], rip[200]; int inseq; PyObject *py_family; diff --git a/psutil/arch/openbsd/proc.c b/psutil/arch/openbsd/proc.c index 35acab25..344d6010 100644 --- a/psutil/arch/openbsd/proc.c +++ b/psutil/arch/openbsd/proc.c @@ -6,25 +6,12 @@ */ #include -#include -#include -#include -#include -#include #include #include #include #include -#include #include -#include #include -#include // for NI_MAXHOST -#include -#define _KERNEL // for DTYPE_* -#include -#undef _KERNEL -#include // for inet_ntoa() #include "../../_psutil_common.h" #include "../../_psutil_posix.h" @@ -155,6 +142,7 @@ psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount) { } +// TODO: refactor this (it's clunky) static char ** _psutil_get_argv(pid_t pid) { static char **argv; @@ -322,212 +310,3 @@ psutil_proc_cwd(PyObject *self, PyObject *args) { } return PyUnicode_DecodeFSDefault(path); } - - -// see sys/kern/kern_sysctl.c lines 1100 and -// usr.bin/fstat/fstat.c print_inet_details() -static char * -psutil_convert_ipv4(int family, uint32_t addr[4]) { - struct in_addr a; - memcpy(&a, addr, sizeof(a)); - return inet_ntoa(a); -} - - -static char * -psutil_inet6_addrstr(struct in6_addr *p) -{ - struct sockaddr_in6 sin6; - static char hbuf[NI_MAXHOST]; - const int niflags = NI_NUMERICHOST; - - memset(&sin6, 0, sizeof(sin6)); - sin6.sin6_family = AF_INET6; - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_addr = *p; - if (IN6_IS_ADDR_LINKLOCAL(p) && - *(u_int16_t *)&sin6.sin6_addr.s6_addr[2] != 0) { - sin6.sin6_scope_id = - ntohs(*(u_int16_t *)&sin6.sin6_addr.s6_addr[2]); - sin6.sin6_addr.s6_addr[2] = sin6.sin6_addr.s6_addr[3] = 0; - } - - if (getnameinfo((struct sockaddr *)&sin6, sin6.sin6_len, - hbuf, sizeof(hbuf), NULL, 0, niflags)) - return "invalid"; - - return hbuf; -} - - -/* - * List process connections. - * Note: there is no net_connections() on OpenBSD. The Python - * implementation will iterate over all processes and use this - * function. - * Note: local and remote paths cannot be determined for UNIX sockets. - */ -PyObject * -psutil_proc_connections(PyObject *self, PyObject *args) { - pid_t pid; - int i; - int cnt; - struct kinfo_file *freep = NULL; - struct kinfo_file *kif; - char *tcplist = NULL; - 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 *_type = NULL; - - if (py_retlist == NULL) - return NULL; - if (! PyArg_ParseTuple(args, _Py_PARSE_PID "OO", &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) { - goto error; - } - - for (i = 0; i < cnt; i++) { - int state; - int lport; - int rport; - char addrbuf[NI_MAXHOST + 2]; - int inseq; - struct in6_addr laddr6; - py_tuple = NULL; - py_laddr = NULL; - py_raddr = NULL; - - kif = &freep[i]; - if (kif->f_type == DTYPE_SOCKET) { - // apply filters - py_family = PyLong_FromLong((long)kif->so_family); - inseq = PySequence_Contains(py_af_filter, py_family); - Py_DECREF(py_family); - if (inseq == 0) - continue; - _type = PyLong_FromLong((long)kif->so_type); - inseq = PySequence_Contains(py_type_filter, _type); - Py_DECREF(_type); - if (inseq == 0) - continue; - - // IPv4 / IPv6 socket - if ((kif->so_family == AF_INET) || (kif->so_family == AF_INET6)) { - // fill status - if (kif->so_type == SOCK_STREAM) - state = kif->t_state; - else - state = PSUTIL_CONN_NONE; - - // ports - lport = ntohs(kif->inp_lport); - rport = ntohs(kif->inp_fport); - - // local address, IPv4 - if (kif->so_family == AF_INET) { - py_laddr = Py_BuildValue( - "(si)", - psutil_convert_ipv4(kif->so_family, kif->inp_laddru), - lport); - if (!py_laddr) - goto error; - } - else { - // local address, IPv6 - memcpy(&laddr6, kif->inp_laddru, sizeof(laddr6)); - snprintf(addrbuf, sizeof(addrbuf), "%s", - psutil_inet6_addrstr(&laddr6)); - py_laddr = Py_BuildValue("(si)", addrbuf, lport); - if (!py_laddr) - goto error; - } - - if (rport != 0) { - // remote address, IPv4 - if (kif->so_family == AF_INET) { - py_raddr = Py_BuildValue( - "(si)", - psutil_convert_ipv4( - kif->so_family, kif->inp_faddru), - rport); - } - else { - // remote address, IPv6 - memcpy(&laddr6, kif->inp_faddru, sizeof(laddr6)); - snprintf(addrbuf, sizeof(addrbuf), "%s", - psutil_inet6_addrstr(&laddr6)); - py_raddr = Py_BuildValue("(si)", addrbuf, rport); - if (!py_raddr) - goto error; - } - } - else { - py_raddr = Py_BuildValue("()"); - } - - if (!py_raddr) - goto error; - py_tuple = Py_BuildValue( - "(iiiNNi)", - kif->fd_fd, - kif->so_family, - kif->so_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. - // XXX: local addr is supposed to be in "unp_path" but it - // always empty; also "fstat" command is not able to show - // UNIX socket paths. - else if (kif->so_family == AF_UNIX) { - py_tuple = Py_BuildValue( - "(iiissi)", - kif->fd_fd, - kif->so_family, - kif->so_type, - "", // laddr (kif->unp_path is empty) - "", // raddr - 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; -} diff --git a/psutil/arch/openbsd/proc.h b/psutil/arch/openbsd/proc.h index 5ca5890d..747507dd 100644 --- a/psutil/arch/openbsd/proc.h +++ b/psutil/arch/openbsd/proc.h @@ -18,5 +18,3 @@ PyObject *psutil_get_cmdline(pid_t pid); PyObject *psutil_proc_threads(PyObject *self, PyObject *args); PyObject *psutil_proc_num_fds(PyObject *self, PyObject *args); PyObject *psutil_proc_cwd(PyObject *self, PyObject *args); -PyObject *psutil_proc_connections(PyObject *self, PyObject *args); - diff --git a/psutil/arch/openbsd/socks.c b/psutil/arch/openbsd/socks.c new file mode 100644 index 00000000..69daa447 --- /dev/null +++ b/psutil/arch/openbsd/socks.c @@ -0,0 +1,180 @@ +/* + * 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 +#include +#include +#include +#define _KERNEL // silence compiler warning +#include // DTYPE_SOCKET +#include // INET6_ADDRSTRLEN, in6_addr +#undef _KERNEL + +#include "../../_psutil_common.h" +#include "../../_psutil_posix.h" + + +PyObject * +psutil_net_connections(PyObject *self, PyObject *args) { + pid_t pid; + int i; + int cnt; + int state; + int lport; + int rport; + char lip[INET6_ADDRSTRLEN]; + char rip[INET6_ADDRSTRLEN]; + int inseq; + + char errbuf[_POSIX2_LINE_MAX]; + kvm_t *kd = NULL; + + struct kinfo_file *kif; + struct kinfo_file *ikf; + struct in6_addr laddr6; + + PyObject *py_retlist = PyList_New(0); + PyObject *py_tuple = NULL; + PyObject *py_laddr = NULL; + PyObject *py_raddr = NULL; + PyObject *py_lpath = NULL; + PyObject *py_af_filter = NULL; + PyObject *py_type_filter = NULL; + PyObject *py_family = NULL; + PyObject *_type = NULL; + + + if (py_retlist == NULL) + return NULL; + if (! PyArg_ParseTuple(args, _Py_PARSE_PID "OO", &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; + } + + kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); + if (! kd) { + convert_kvm_err("kvm_openfiles", errbuf); + goto error; + } + + ikf = kvm_getfiles(kd, KERN_FILE_BYPID, -1, sizeof(*ikf), &cnt); + if (! ikf) { + PyErr_SetFromOSErrnoWithSyscall("kvm_getfiles"); + goto error; + } + + for (int i = 0; i < cnt; i++) { + const struct kinfo_file *kif = ikf + i; + py_tuple = NULL; + py_laddr = NULL; + py_raddr = NULL; + py_lpath = NULL; + + // apply filters + if (kif->f_type != DTYPE_SOCKET) + continue; + if (pid != -1 && kif->p_pid != (uint32_t)pid) + continue; + py_family = PyLong_FromLong((long)kif->so_family); + inseq = PySequence_Contains(py_af_filter, py_family); + Py_DECREF(py_family); + if (inseq == 0) + continue; + _type = PyLong_FromLong((long)kif->so_type); + inseq = PySequence_Contains(py_type_filter, _type); + Py_DECREF(_type); + if (inseq == 0) + continue; + + // IPv4 / IPv6 socket + if ((kif->so_family == AF_INET) || (kif->so_family == AF_INET6)) { + // status + if (kif->so_type == SOCK_STREAM) + state = kif->t_state; + else + state = PSUTIL_CONN_NONE; + + // local & remote port + lport = ntohs(kif->inp_lport); + rport = ntohs(kif->inp_fport); + + // local addr + inet_ntop(kif->so_family, &kif->inp_laddru, lip, sizeof(lip)); + py_laddr = Py_BuildValue("(si)", lip, lport); + if (! py_laddr) + goto error; + + // remote addr + if (rport != 0) { + inet_ntop(kif->so_family, &kif->inp_faddru, rip, sizeof(rip)); + py_raddr = Py_BuildValue("(si)", rip, rport); + } + else { + py_raddr = Py_BuildValue("()"); + } + if (! py_raddr) + goto error; + + // populate tuple and list + py_tuple = Py_BuildValue( + "(iiiNNil)", + kif->fd_fd, + kif->so_family, + kif->so_type, + py_laddr, + py_raddr, + state, + kif->p_pid + ); + if (! py_tuple) + goto error; + if (PyList_Append(py_retlist, py_tuple)) + goto error; + Py_DECREF(py_tuple); + } + // UNIX socket + else if (kif->so_family == AF_UNIX) { + py_lpath = PyUnicode_DecodeFSDefault(kif->unp_path); + if (! py_lpath) + goto error; + + py_tuple = Py_BuildValue( + "(iiiOsil)", + kif->fd_fd, + kif->so_family, + kif->so_type, + py_lpath, + "", // raddr + PSUTIL_CONN_NONE, + kif->p_pid + ); + if (! py_tuple) + goto error; + if (PyList_Append(py_retlist, py_tuple)) + goto error; + Py_DECREF(py_lpath); + Py_DECREF(py_tuple); + Py_INCREF(Py_None); + } + } + + kvm_close(kd); + return py_retlist; + +error: + Py_XDECREF(py_tuple); + Py_XDECREF(py_laddr); + Py_XDECREF(py_raddr); + Py_DECREF(py_retlist); + if (kd != NULL) + kvm_close(kd); + return NULL; +} diff --git a/psutil/arch/openbsd/socks.h b/psutil/arch/openbsd/socks.h new file mode 100644 index 00000000..90b678bb --- /dev/null +++ b/psutil/arch/openbsd/socks.h @@ -0,0 +1,8 @@ +/* + * 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. + */ + +PyObject *psutil_net_connections(PyObject* self, PyObject* args); diff --git a/psutil/tests/test_connections.py b/psutil/tests/test_connections.py index d47233bc..ad615ed0 100755 --- a/psutil/tests/test_connections.py +++ b/psutil/tests/test_connections.py @@ -143,11 +143,7 @@ class TestUnconnectedSockets(ConnectionTestCase): laddr = laddr.decode() if sock.family == AF_INET6: laddr = laddr[:2] - if sock.family == AF_UNIX and OPENBSD: - # No addresses are set for UNIX sockets on OpenBSD. - pass - else: - self.assertEqual(conn.laddr, laddr) + self.assertEqual(conn.laddr, laddr) # XXX Solaris can't retrieve system-wide UNIX sockets if sock.family == AF_UNIX and HAS_CONNECTIONS_UNIX: @@ -243,22 +239,16 @@ class TestConnectedSocket(ConnectionTestCase): # a UNIX connection to /var/run/log. cons = [c for c in cons if c.raddr != '/var/run/log'] self.assertEqual(len(cons), 2, msg=cons) - if LINUX or FREEBSD or SUNOS: + if LINUX or FREEBSD or SUNOS or OPENBSD: # remote path is never set self.assertEqual(cons[0].raddr, "") self.assertEqual(cons[1].raddr, "") # one local address should though self.assertEqual(testfn, cons[0].laddr or cons[1].laddr) - elif OPENBSD: - # No addresses whatsoever here. - for addr in (cons[0].laddr, cons[0].raddr, - cons[1].laddr, cons[1].raddr): - self.assertEqual(addr, "") else: # On other systems either the laddr or raddr # of both peers are set. self.assertEqual(cons[0].laddr or cons[1].laddr, testfn) - self.assertEqual(cons[0].raddr or cons[1].raddr, testfn) finally: server.close() client.close() diff --git a/psutil/tests/test_unicode.py b/psutil/tests/test_unicode.py index 43cf2b49..c7d8dfbc 100755 --- a/psutil/tests/test_unicode.py +++ b/psutil/tests/test_unicode.py @@ -82,7 +82,6 @@ from contextlib import closing import psutil from psutil import BSD -from psutil import OPENBSD from psutil import POSIX from psutil import WINDOWS from psutil._compat import PY3 @@ -257,9 +256,7 @@ class TestFSAPIs(BaseUnicodeTest): with closing(sock): conn = psutil.Process().connections('unix')[0] self.assertIsInstance(conn.laddr, str) - # AF_UNIX addr not set on OpenBSD - if not OPENBSD: # XXX - self.assertEqual(conn.laddr, name) + self.assertEqual(conn.laddr, name) @unittest.skipIf(not POSIX, "POSIX only") @unittest.skipIf(not HAS_CONNECTIONS_UNIX, "can't list UNIX sockets") @@ -281,11 +278,9 @@ class TestFSAPIs(BaseUnicodeTest): raise unittest.SkipTest("not supported") with closing(sock): cons = psutil.net_connections(kind='unix') - # AF_UNIX addr not set on OpenBSD - if not OPENBSD: - conn = find_sock(cons) - self.assertIsInstance(conn.laddr, str) - self.assertEqual(conn.laddr, name) + conn = find_sock(cons) + self.assertIsInstance(conn.laddr, str) + self.assertEqual(conn.laddr, name) def test_disk_usage(self): dname = self.funky_name + "2" diff --git a/setup.py b/setup.py index a4f719b2..c69f6e3d 100755 --- a/setup.py +++ b/setup.py @@ -275,6 +275,7 @@ elif OPENBSD: 'psutil/arch/openbsd/disk.c', 'psutil/arch/openbsd/mem.c', 'psutil/arch/openbsd/proc.c', + 'psutil/arch/openbsd/socks.c', ], define_macros=macros, libraries=["kvm"], -- cgit v1.2.1