Skip to content

Commit

Permalink
Add support for DragonFlyBSD
Browse files Browse the repository at this point in the history
  • Loading branch information
ricardobranco777 committed Mar 8, 2024
1 parent 19decb3 commit 0142173
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 23 deletions.
8 changes: 5 additions & 3 deletions bsd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions bsd/extern.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
#include <sys/types.h>

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
29 changes: 24 additions & 5 deletions bsd/kinfo_getallproc.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#ifdef __DragonFly__
#include <sys/user.h>
#else
#include <sys/proc.h>
#endif

#include <stdlib.h>

#include "extern.h"

#ifdef __DragonFly__
#define p_pid kp_pid
#endif

/*
* Sort processes by pid
*/
Expand All @@ -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));
Expand Down
19 changes: 6 additions & 13 deletions bsd/kinfo_getargv.c
Original file line number Diff line number Diff line change
@@ -1,24 +1,17 @@
#include <sys/cdefs.h>
#include <sys/param.h>
#include <sys/sysctl.h>
#ifdef __DragonFly__
#include <sys/user.h>
#else
#include <sys/proc.h>
#endif

#include <stdlib.h>
#include <string.h>

#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)
{
Expand Down Expand Up @@ -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;
Expand Down
78 changes: 78 additions & 0 deletions bsd/kinfo_getvmmap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#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);
}
12 changes: 10 additions & 2 deletions bsd/restartable.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
#include <sys/param.h>
#include <sys/sysctl.h>
#include <util.h>
#elif defined(__DragonFly__)
#include <sys/kinfo.h>
#endif

#include <stdio.h>
Expand All @@ -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"
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand Down
13 changes: 13 additions & 0 deletions bsd/util.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <stddef.h>

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;
}

0 comments on commit 0142173

Please sign in to comment.