summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2023-04-13 15:14:30 +0200
committerGitHub <noreply@github.com>2023-04-13 15:14:30 +0200
commitaa2946513b85161f732963d1b7e30d0fe7d00d79 (patch)
treea47ff69a5e2e7fe8fc1eb5fe4a979f727a800e2c
parent0dde184075f81a9b6e22caa7255396d21ae63769 (diff)
downloadpsutil-aa2946513b85161f732963d1b7e30d0fe7d00d79.tar.gz
OpenBSD: rewrite net_connections() from scratch (#2230)
-rw-r--r--HISTORY.rst7
-rw-r--r--MANIFEST.in2
-rw-r--r--docs/index.rst19
-rw-r--r--psutil/_psbsd.py46
-rw-r--r--psutil/_psutil_bsd.c7
-rw-r--r--psutil/_psutil_osx.c1
-rw-r--r--psutil/arch/openbsd/proc.c223
-rw-r--r--psutil/arch/openbsd/proc.h2
-rw-r--r--psutil/arch/openbsd/socks.c180
-rw-r--r--psutil/arch/openbsd/socks.h8
-rwxr-xr-xpsutil/tests/test_connections.py14
-rwxr-xr-xpsutil/tests/test_unicode.py13
-rwxr-xr-xsetup.py1
13 files changed, 246 insertions, 277 deletions
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 <utmp.h>
#include <sys/vnode.h> // 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 <Python.h>
-#include <assert.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysctl.h>
-#include <sys/user.h>
#include <sys/proc.h>
-#include <signal.h>
#include <kvm.h>
-#include <netdb.h> // for NI_MAXHOST
-#include <sys/socket.h>
-#define _KERNEL // for DTYPE_*
-#include <sys/file.h>
-#undef _KERNEL
-#include <arpa/inet.h> // 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 <Python.h>
+#include <sys/sysctl.h>
+#include <sys/socket.h>
+#include <kvm.h>
+#define _KERNEL // silence compiler warning
+#include <sys/file.h> // DTYPE_SOCKET
+#include <netdb.h> // 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"],