diff --git a/HISTORY.rst b/HISTORY.rst index c854ef80b..6ed9bd3da 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -25,6 +25,9 @@ XXXX-XX-XX Python 3.13. (patch by Sam Gross) - 2455_, [Linux]: ``IndexError`` may occur when reading /proc/pid/stat and field 40 (blkio_ticks) is missing. +- 2460_, [OpenBSD]: `Process.num_fds()`_ and `Process.open_files()`_ may fail + with `NoSuchProcess`_ for PID 0. Instead, we now return "null" values (0 and + [] respectively). 6.0.0 ====== diff --git a/INSTALL.rst b/INSTALL.rst index a425400fd..8e06d400e 100644 --- a/INSTALL.rst +++ b/INSTALL.rst @@ -82,7 +82,7 @@ OpenBSD :: - export PKG_PATH=http://ftp.eu.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/ + export PKG_PATH=https://cdn.openbsd.org/pub/OpenBSD/`uname -r`/packages/`uname -m`/ pkg_add -v python3 gcc pip install psutil @@ -93,7 +93,7 @@ Assuming Python 3.11 (the most recent at the time of writing): :: - export PKG_PATH="http://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All" + export PKG_PATH="https://ftp.netbsd.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All" pkg_add -v pkgin pkgin install python311-* gcc12-* py311-setuptools-* py311-pip-* python3.11 -m pip install psutil diff --git a/psutil/arch/bsd/proc.c b/psutil/arch/bsd/proc.c index 5d353ff35..959b28ee0 100644 --- a/psutil/arch/bsd/proc.c +++ b/psutil/arch/bsd/proc.c @@ -442,8 +442,17 @@ psutil_proc_open_files(PyObject *self, PyObject *args) { errno = 0; freep = kinfo_getfile(pid, &cnt); + if (freep == NULL) { -#if !defined(PSUTIL_OPENBSD) +#if defined(PSUTIL_OPENBSD) + if ((pid == 0) && (errno == ESRCH)) { + psutil_debug( + "open_files() returned ESRCH for PID 0; forcing `return []`" + ); + PyErr_Clear(); + return py_retlist; + } +#else psutil_raise_for_pid(pid, "kinfo_getfile()"); #endif goto error; diff --git a/psutil/arch/openbsd/proc.c b/psutil/arch/openbsd/proc.c index 0881ccd55..bf4015be4 100644 --- a/psutil/arch/openbsd/proc.c +++ b/psutil/arch/openbsd/proc.c @@ -41,7 +41,7 @@ psutil_kinfo_proc(pid_t pid, struct kinfo_proc *proc) { ret = sysctl((int*)mib, 6, proc, &size, NULL, 0); if (ret == -1) { - PyErr_SetFromErrno(PyExc_OSError); + psutil_PyErr_SetFromOSErrnoWithSyscall("sysctl(kinfo_proc)"); return -1; } // sysctl stores 0 in the size if we can't find the process information. @@ -69,7 +69,7 @@ kinfo_getfile(pid_t pid, int* cnt) { /* get the size of what would be returned */ if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { - PyErr_SetFromErrno(PyExc_OSError); + psutil_PyErr_SetFromOSErrnoWithSyscall("sysctl(kinfo_file) (1/2)"); return NULL; } if ((kf = malloc(len)) == NULL) { @@ -79,7 +79,7 @@ kinfo_getfile(pid_t pid, int* cnt) { mib[5] = (int)(len / sizeof(struct kinfo_file)); if (sysctl(mib, 6, kf, &len, NULL, 0) < 0) { free(kf); - PyErr_SetFromErrno(PyExc_OSError); + psutil_PyErr_SetFromOSErrnoWithSyscall("sysctl(kinfo_file) (2/2)"); return NULL; } @@ -288,8 +288,19 @@ psutil_proc_num_fds(PyObject *self, PyObject *args) { return NULL; freep = kinfo_getfile(pid, &cnt); - if (freep == NULL) + + if (freep == NULL) { +#if defined(PSUTIL_OPENBSD) + if ((pid == 0) && (errno == ESRCH)) { + psutil_debug( + "num_fds() returned ESRCH for PID 0; forcing `return 0`" + ); + PyErr_Clear(); + return Py_BuildValue("i", 0); + } +#endif return NULL; + } free(freep); return Py_BuildValue("i", cnt);