From 01421731f36288a5f0200eb0903cc298bd6cb087 Mon Sep 17 00:00:00 2001 From: Ricardo Branco Date: Fri, 8 Mar 2024 19:58:25 +0100 Subject: [PATCH] Add support for DragonFlyBSD --- bsd/Makefile | 8 +++-- bsd/extern.h | 19 ++++++++++ bsd/kinfo_getallproc.c | 29 +++++++++++++--- bsd/kinfo_getargv.c | 19 ++++------ bsd/kinfo_getvmmap.c | 78 ++++++++++++++++++++++++++++++++++++++++++ bsd/restartable.c | 12 +++++-- bsd/util.c | 13 +++++++ 7 files changed, 155 insertions(+), 23 deletions(-) create mode 100644 bsd/kinfo_getvmmap.c create mode 100644 bsd/util.c diff --git a/bsd/Makefile b/bsd/Makefile index 32afc1b..ca72a0f 100644 --- a/bsd/Makefile +++ b/bsd/Makefile @@ -4,14 +4,16 @@ PROG= restartable WARNS= 3 CFLAGS+= -O2 LDFLAGS= -lutil -SRCS= restartable.c kinfo_getargv.c +SRCS= restartable.c kinfo_getargv.c util.c HDRS= extern.h +BINDIR= /usr/local/bin + .if ${OPSYS} == "NetBSD" BINDIR= /usr/pkg/bin SRCS+= kinfo_getallproc.c -.else -BINDIR= /usr/local/bin +.elif ${OPSYS} == "DragonFly" +SRCS+= kinfo_getallproc.c kinfo_getvmmap.c .endif MK_DEBUG_FILES= no diff --git a/bsd/extern.h b/bsd/extern.h index 972c503..4c93453 100644 --- a/bsd/extern.h +++ b/bsd/extern.h @@ -1,8 +1,27 @@ +#include +int memnchr(const void *, int, size_t); void free_argv(char **); char **kinfo_getargv(pid_t pid); #ifdef __NetBSD__ #define kinfo_proc kinfo_proc2 +#endif + +#if defined(__NetBSD__) || defined(__DragonFly__) struct kinfo_proc *kinfo_getallproc(int *); #endif + +#ifdef __DragonFly__ +struct kinfo_vmentry { + int kve_type; /* Type of map entry. */ + int kve_protection; /* Protection bitmask. */ + char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ +}; + +#define KVME_TYPE_VNODE 2 +#define KVME_PROT_EXEC 4 + +struct kinfo_vmentry *kinfo_getvmmap(pid_t, int *); + +#endif diff --git a/bsd/kinfo_getallproc.c b/bsd/kinfo_getallproc.c index acada99..df4a5b0 100644 --- a/bsd/kinfo_getallproc.c +++ b/bsd/kinfo_getallproc.c @@ -1,11 +1,20 @@ #include #include #include +#ifdef __DragonFly__ +#include +#else #include +#endif + #include #include "extern.h" +#ifdef __DragonFly__ +#define p_pid kp_pid +#endif + /* * Sort processes by pid */ @@ -28,26 +37,36 @@ struct kinfo_proc * kinfo_getallproc(int *cntp) { struct kinfo_proc *kipp; - size_t len; + size_t len = 65; int mib[6]; + int n; mib[0] = CTL_KERN; + mib[3] = 0; +#if defined(__NetBSD__) mib[1] = KERN_PROC2; mib[2] = KERN_PROC_ALL; - mib[3] = 0; mib[4] = sizeof(struct kinfo_proc); mib[5] = 0; + n = 6; +#elif defined(__DragonFly__) + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_ALL; + n = 3; +#endif len = 0; - if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) + if (sysctl(mib, n, NULL, &len, NULL, 0) < 0) return (NULL); - mib[5] = (int) (len / sizeof(struct kinfo_proc)); +#ifdef __NetBSD__ + mib[n-1] = (int) (len / sizeof(struct kinfo_proc)); +#endif kipp = malloc(len); if (kipp == NULL) return (NULL); - if (sysctl(mib, 6, kipp, &len, NULL, 0) < 0) + if (sysctl(mib, n, kipp, &len, NULL, 0) < 0) goto bad; *cntp = len / sizeof(*kipp); kinfo_proc_sort(kipp, len / sizeof(*kipp)); diff --git a/bsd/kinfo_getargv.c b/bsd/kinfo_getargv.c index 091c87e..0378cf1 100644 --- a/bsd/kinfo_getargv.c +++ b/bsd/kinfo_getargv.c @@ -1,24 +1,17 @@ #include #include #include +#ifdef __DragonFly__ +#include +#else #include +#endif + #include #include #include "extern.h" -static int -memnchr(const void *p, int c, size_t len) -{ - int n = 0; - - for (size_t i = 0; i < len; i++) - if (*((const unsigned char *)p + i) == c) - n++; - - return n; -} - void free_argv(char **argv) { @@ -46,7 +39,7 @@ kinfo_getargv(pid_t pid) return (NULL); mib[0] = CTL_KERN; -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__DragonFly__) mib[1] = KERN_PROC; mib[2] = KERN_PROC_ARGS; mib[3] = pid; diff --git a/bsd/kinfo_getvmmap.c b/bsd/kinfo_getvmmap.c new file mode 100644 index 0000000..2bef942 --- /dev/null +++ b/bsd/kinfo_getvmmap.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "extern.h" + +static char * +procmap(pid_t pid) +{ + char path[PATH_MAX]; + size_t size = 65536; + char *buf; + int fd; + + (void) snprintf(path, sizeof(path), "/proc/%d/map", pid); + if ((fd = open(path, O_RDONLY)) == -1) + return (NULL); + + if ((buf = calloc(1, size)) == NULL) + return (NULL); + + if (read(fd, buf, size - 1) == -1) + goto bad; + + (void) close(fd); + return (buf); + +bad: + (void) close(fd); + return (NULL); +} + +/* Minimal kinfo_getvmmap */ +struct kinfo_vmentry * +kinfo_getvmmap(pid_t pid, int *cntp) +{ + struct kinfo_vmentry *kiv; + struct stat st; + char prot[4], type[10]; + char *buf; + + if ((buf = procmap(pid)) == NULL) + return (NULL); + + *cntp = memnchr(buf, '\n', strlen(buf)); + kiv = calloc(*cntp, sizeof(struct kinfo_vmentry)); + if (kiv == NULL) + goto bad2; + + char *line = buf; + for (int i = 0; i < *cntp; i++) { + char *token = strsep(&line, "\n"); + if (token == NULL) + break; + /* + * Parse lines like this: + * 0x0000000000400000 0x0000000000403000 -1 -1 0xfffff80119599400 r-x 2 0 0x0000 COW NC vnode /bin/cat + */ + (void) sscanf(token, "%*x %*x %*d %*d %*x %3s %*d %*d %*x %*s %*s %10s %4095[^\n]", prot, type, &kiv[i].kve_path); + kiv[i].kve_protection = (prot[2] == 'x') ? KVME_PROT_EXEC : 0; + if (!strcmp(type, "vnode")) { + kiv[i].kve_type |= KVME_TYPE_VNODE; + if (lstat(kiv[i].kve_path, &st) < 0) + kiv[i].kve_path[0] = '\0'; + } + } + + return kiv; + +bad2: + free(buf); + return (NULL); +} diff --git a/bsd/restartable.c b/bsd/restartable.c index 137425e..2387044 100644 --- a/bsd/restartable.c +++ b/bsd/restartable.c @@ -34,6 +34,8 @@ #include #include #include +#elif defined(__DragonFly__) +#include #endif #include @@ -51,6 +53,12 @@ #define ki_pid p_pid #define ki_ppid p_ppid #define ki_ruid p_ruid +#elif defined(__DragonFly__) +#define ki_comm kp_comm +#define ki_login kp_login +#define ki_pid kp_pid +#define ki_ppid kp_ppid +#define ki_ruid kp_ruid #endif #include "extern.h" @@ -90,7 +98,7 @@ print_argv(pid_t pid) { static void print_proc(const struct kinfo_proc *kp) { -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__DragonFly__) int i, count; #elif defined(__NetBSD__) unsigned int i; @@ -102,7 +110,7 @@ print_proc(const struct kinfo_proc *kp) { struct kinfo_vmentry *vmmap = kinfo_getvmmap(kp->ki_pid, &count); if (vmmap == NULL) { - if (errno != EPERM) + if (errno != EPERM && errno != ENOENT) warn("kinfo_getvmmap(): %d", kp->ki_pid); return; } diff --git a/bsd/util.c b/bsd/util.c new file mode 100644 index 0000000..d78cc6f --- /dev/null +++ b/bsd/util.c @@ -0,0 +1,13 @@ +#include + +int +memnchr(const void *p, int c, size_t len) +{ + int n = 0; + + for (size_t i = 0; i < len; i++) + if (*((const unsigned char *)p + i) == c) + n++; + + return n; +}