os: Use KERN_PROC_ARGS to determine client command on DragonFly and FreeBSD

This commit is contained in:
Jan Beich 2023-01-27 09:55:33 +00:00 committed by Matt Turner
parent 58e8c967b6
commit 5c8f70a17c

View File

@ -73,6 +73,11 @@
#include <limits.h> #include <limits.h>
#endif #endif
#if defined(__DragonFly__) || defined(__FreeBSD__)
#include <sys/sysctl.h>
#include <errno.h>
#endif
#ifdef __APPLE__ #ifdef __APPLE__
#include <dispatch/dispatch.h> #include <dispatch/dispatch.h>
#include <errno.h> #include <errno.h>
@ -136,7 +141,7 @@ DetermineClientPid(struct _Client * client)
void void
DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs) DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
{ {
#if !defined(__APPLE__) #if !defined(__APPLE__) && !defined(__DragonFly__) && !defined(__FreeBSD__)
char path[PATH_MAX + 1]; char path[PATH_MAX + 1];
int totsize = 0; int totsize = 0;
int fd = 0; int fd = 0;
@ -248,6 +253,56 @@ DetermineClientCmd(pid_t pid, const char **cmdname, const char **cmdargs)
*cmdargs = strdup(args); *cmdargs = strdup(args);
} }
free(procargs);
}
#elif defined(__DragonFly__) || defined(__FreeBSD__)
/* on DragonFly and FreeBSD use KERN_PROC_ARGS */
{
int mib[] = {
CTL_KERN,
KERN_PROC,
KERN_PROC_ARGS,
pid,
};
/* Determine exact size instead of relying on kern.argmax */
size_t len;
if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) != 0) {
ErrorF("Failed to query KERN_PROC_ARGS length for PID %d: %s\n", pid, strerror(errno));
return;
}
/* Read KERN_PROC_ARGS contents. Similar to /proc/pid/cmdline
* the process name and each argument are separated by NUL byte. */
char *const procargs = malloc(len);
if (sysctl(mib, ARRAY_SIZE(mib), procargs, &len, NULL, 0) != 0) {
ErrorF("Failed to get KERN_PROC_ARGS for PID %d: %s\n", pid, strerror(errno));
free(procargs);
return;
}
/* Construct the process name without arguments. */
if (cmdname) {
*cmdname = strdup(procargs);
}
/* Construct the arguments for client process. */
if (cmdargs) {
size_t cmdsize = strlen(procargs) + 1;
size_t argsize = len - cmdsize;
char *args = NULL;
if (argsize > 0)
args = procargs + cmdsize;
if (args) {
/* Replace NUL with space except terminating NUL */
for (size_t i = 0; i < (argsize - 1); i++) {
if (args[i] == '\0')
args[i] = ' ';
}
*cmdargs = strdup(args);
}
}
free(procargs); free(procargs);
} }
#elif defined(__OpenBSD__) #elif defined(__OpenBSD__)