From: Claudio Jeker Subject: Re: KERN_PROC_PATHNAME workaround To: Rafael Sadowski Cc: ports@openbsd.org, tech@openbsd.org Date: Sun, 4 Jan 2026 13:55:38 +0100 On Sun, Jan 04, 2026 at 01:04:01PM +0100, Rafael Sadowski wrote: > Since we do not provide KERN_PROC_PATHNAME I picked up robets@'s "hack" > form www/chromium/patches/patch-base_base_paths_posix_cc. > > It certainly won't work in all cases, but it's enough for me in this context. > This implementation only makes sense if we don't call it too often. > > Is KERN_PROC_PATHNAME something we generally don't want? Or was it > simply not implied? We don't know the path to a vnode, now we could store the path in the kernel but a directory in that path could be moved and replaced. Or a symlink changed or the text file could be removed, ... So there is a lot of things that can go wrong. In all of these cases KERN_PROC_PATHNAME needs to return an error. On top of all of this do those application using this sysctl even consider a failure of this call? > Index: kwin/Makefile > =================================================================== > RCS file: /cvs/ports/x11/kde-plasma/kwin/Makefile,v > diff -u -p -r1.41 Makefile > --- kwin/Makefile 4 Jan 2026 09:12:01 -0000 1.41 > +++ kwin/Makefile 4 Jan 2026 11:55:27 -0000 > @@ -1,6 +1,6 @@ > COMMENT = Wayland window manager for KDE Plasma Desktops > DISTNAME = kwin-${VERSION} > -REVISION = 2 > +REVISION = 3 > > SHARED_LIBS += kcmkwincommon 1.0 # 0.0 > SHARED_LIBS += kwin 1.0 # 0.0 > Index: kwin/patches/patch-src_utils_executable_path_sysctl_cpp > =================================================================== > RCS file: /cvs/ports/x11/kde-plasma/kwin/patches/patch-src_utils_executable_path_sysctl_cpp,v > diff -u -p -r1.1 patch-src_utils_executable_path_sysctl_cpp > --- kwin/patches/patch-src_utils_executable_path_sysctl_cpp 4 Jan 2026 08:03:42 -0000 1.1 > +++ kwin/patches/patch-src_utils_executable_path_sysctl_cpp 4 Jan 2026 11:55:27 -0000 > @@ -2,11 +2,103 @@ https://invent.kde.org/plasma/kwin/-/mer > Index: src/utils/executable_path_sysctl.cpp > --- src/utils/executable_path_sysctl.cpp.orig > +++ src/utils/executable_path_sysctl.cpp > -@@ -12,11 +12,13 @@ > +@@ -7,16 +7,105 @@ > + #include > + #include > + #include > ++#if defined(__OpenBSD__) > ++#include > + > ++#include > ++#include > ++#include > ++#include > ++#include > ++#include > ++#endif > ++ > + #include "executable_path.h" > > QString executablePathFromPid(pid_t pid) > { > -+#if !defined(__OpenBSD__) > ++#if defined(__OpenBSD__) > ++ char resolved_path[PATH_MAX]; > ++ > ++ char errbuf[_POSIX2_LINE_MAX]; > ++ kvm_t *kd = NULL; > ++ struct kinfo_proc *proc = NULL; > ++ char **argv_proc = NULL; > ++ > ++ auto cleanup = [&](QString const &sErr) { > ++ if (kd != NULL) { > ++ kvm_close(kd); > ++ } > ++ qWarning() << sErr; > ++ return QString(); > ++ }; > ++ // Try to resolve path from argv[0] by searching in PATH > ++ auto search_path = [](const char *argv0, char *buf, size_t bufsize) { > ++ char *path_env; > ++ char *path; > ++ char *dir; > ++ char testpath[PATH_MAX]; > ++ struct stat sb; > ++ > ++ if (strchr(argv0, '/') != NULL) { > ++ return realpath(argv0, buf) ? 0 : -1; > ++ } > ++ > ++ // Search in PATH > ++ path_env = getenv("PATH"); > ++ if (path_env == NULL) { > ++ return -1; > ++ } > ++ > ++ path = strdup(path_env); > ++ if (path == NULL) { > ++ return -1; > ++ } > ++ > ++ dir = strtok(path, ":"); > ++ while (dir != NULL) { > ++ snprintf(testpath, sizeof(testpath), "%s/%s", dir, argv0); > ++ if (stat(testpath, &sb) == 0 && (sb.st_mode & S_IXUSR)) { > ++ char *result = realpath(testpath, buf); > ++ if (result != NULL && strlen(result) < bufsize) { > ++ free(path); > ++ return 0; > ++ } > ++ } > ++ dir = strtok(NULL, ":"); > ++ } > ++ > ++ free(path); > ++ return -1; > ++ }; > ++ > ++ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); > ++ if (kd == NULL) { > ++ return cleanup("kvm_openfiles failed: " + QString::fromLocal8Bit(errbuf)); > ++ } > ++ > ++ int cnt; > ++ proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cnt); > ++ if (proc == NULL || cnt == 0) { > ++ return cleanup("Process with PID: " + QString::number(static_cast(pid)) + " not found"); > ++ } > ++ > ++ argv_proc = kvm_getargv(kd, proc, 0); > ++ if (argv_proc == NULL || argv_proc[0] == NULL) { > ++ return cleanup("Could not get argv for PID: " + QString::number(static_cast(pid))); > ++ } > ++ > ++ // Try to resolve via PATH or direct path > ++ if (search_path(argv_proc[0], resolved_path, sizeof(resolved_path)) == 0) { > ++ return QString::fromLocal8Bit(resolved_path); > ++ } else { > ++ return cleanup("Could not resolve path for: " + QString::fromLocal8Bit(argv_proc[0])); > ++ } > ++#else > const int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, static_cast(pid)}; > char buf[MAXPATHLEN]; > size_t cb = sizeof(buf); > Index: kwin-x11/Makefile > =================================================================== > RCS file: /cvs/ports/x11/kde-plasma/kwin-x11/Makefile,v > diff -u -p -r1.9 Makefile > --- kwin-x11/Makefile 4 Jan 2026 09:17:00 -0000 1.9 > +++ kwin-x11/Makefile 4 Jan 2026 11:55:27 -0000 > @@ -1,6 +1,6 @@ > COMMENT = X11 window manager for KDE Plasma Desktops > DISTNAME = kwin-x11-${VERSION} > -REVISION = 2 > +REVISION = 3 > > SHARED_LIBS += kcmkwincommon-x11 0.0 # 0.0 > SHARED_LIBS += kwin-x11 0.0 # 0.0 > Index: kwin-x11/patches/patch-src_utils_executable_path_sysctl_cpp > =================================================================== > RCS file: /cvs/ports/x11/kde-plasma/kwin-x11/patches/patch-src_utils_executable_path_sysctl_cpp,v > diff -u -p -r1.1 patch-src_utils_executable_path_sysctl_cpp > --- kwin-x11/patches/patch-src_utils_executable_path_sysctl_cpp 4 Jan 2026 08:58:17 -0000 1.1 > +++ kwin-x11/patches/patch-src_utils_executable_path_sysctl_cpp 4 Jan 2026 11:55:27 -0000 > @@ -2,11 +2,103 @@ https://invent.kde.org/plasma/kwin/-/mer > Index: src/utils/executable_path_sysctl.cpp > --- src/utils/executable_path_sysctl.cpp.orig > +++ src/utils/executable_path_sysctl.cpp > -@@ -12,11 +12,13 @@ > +@@ -7,16 +7,105 @@ > + #include > + #include > + #include > ++#if defined(__OpenBSD__) > ++#include > + > ++#include > ++#include > ++#include > ++#include > ++#include > ++#include > ++#endif > ++ > + #include "executable_path.h" > > QString executablePathFromPid(pid_t pid) > { > -+#if !defined(__OpenBSD__) > ++#if defined(__OpenBSD__) > ++ char resolved_path[PATH_MAX]; > ++ > ++ char errbuf[_POSIX2_LINE_MAX]; > ++ kvm_t *kd = NULL; > ++ struct kinfo_proc *proc = NULL; > ++ char **argv_proc = NULL; > ++ > ++ auto cleanup = [&](QString const &sErr) { > ++ if (kd != NULL) { > ++ kvm_close(kd); > ++ } > ++ qWarning() << sErr; > ++ return QString(); > ++ }; > ++ // Try to resolve path from argv[0] by searching in PATH > ++ auto search_path = [](const char *argv0, char *buf, size_t bufsize) { > ++ char *path_env; > ++ char *path; > ++ char *dir; > ++ char testpath[PATH_MAX]; > ++ struct stat sb; > ++ > ++ if (strchr(argv0, '/') != NULL) { > ++ return realpath(argv0, buf) ? 0 : -1; > ++ } > ++ > ++ // Search in PATH > ++ path_env = getenv("PATH"); > ++ if (path_env == NULL) { > ++ return -1; > ++ } > ++ > ++ path = strdup(path_env); > ++ if (path == NULL) { > ++ return -1; > ++ } > ++ > ++ dir = strtok(path, ":"); > ++ while (dir != NULL) { > ++ snprintf(testpath, sizeof(testpath), "%s/%s", dir, argv0); > ++ if (stat(testpath, &sb) == 0 && (sb.st_mode & S_IXUSR)) { > ++ char *result = realpath(testpath, buf); > ++ if (result != NULL && strlen(result) < bufsize) { > ++ free(path); > ++ return 0; > ++ } > ++ } > ++ dir = strtok(NULL, ":"); > ++ } > ++ > ++ free(path); > ++ return -1; > ++ }; > ++ > ++ kd = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf); > ++ if (kd == NULL) { > ++ return cleanup("kvm_openfiles failed: " + QString::fromLocal8Bit(errbuf)); > ++ } > ++ > ++ int cnt; > ++ proc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &cnt); > ++ if (proc == NULL || cnt == 0) { > ++ return cleanup("Process with PID: " + QString::number(static_cast(pid)) + " not found"); > ++ } > ++ > ++ argv_proc = kvm_getargv(kd, proc, 0); > ++ if (argv_proc == NULL || argv_proc[0] == NULL) { > ++ return cleanup("Could not get argv for PID: " + QString::number(static_cast(pid))); > ++ } > ++ > ++ // Try to resolve via PATH or direct path > ++ if (search_path(argv_proc[0], resolved_path, sizeof(resolved_path)) == 0) { > ++ return QString::fromLocal8Bit(resolved_path); > ++ } else { > ++ return cleanup("Could not resolve path for: " + QString::fromLocal8Bit(argv_proc[0])); > ++ } > ++#else > const int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, static_cast(pid)}; > char buf[MAXPATHLEN]; > size_t cb = sizeof(buf); > -- :wq Claudio