blob: f0fda1078da63279882f458c09d9b8226bceef76 [file] [log] [blame] [raw]
/* libprocstat
Copyright 2015-2022 Rivoreo
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at
your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
*/
#include "procstat.h"
#include "procstat-private.h"
#include <sys/param.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
struct procstat_handle {
const struct procstat_interface *interface;
struct procstat_private_handle *handle;
};
extern const struct procstat_interface procstat_available_interfaces[];
/*
#if defined BSD || __FreeBSD_kernel__
#include "procstat.sysctl.c"
#elif defined __SVR4
#include "procstat.sysv.c"
#elif defined __linux__ || defined __CYGWIN__
#include "procstat.linux-procfs.c"
#elif defined __INTERIX
#include "procstat.interix.c"
#elif _WINDOWSNT_NATIVE
#include "procstat.nt.c"
#elif _WIN32
#include "procstat.windows.c"
#else
#error "Unsupported platform"
#endif
extern int _check[sizeof available_interfaces ? 1 : -1];
*/
struct procstat_handle *procstat_open() {
unsigned int i;
const struct procstat_interface *interface;
struct procstat_private_handle *handle = NULL;
struct procstat_handle *r = malloc(sizeof(struct procstat_handle));
if(!r) return NULL;
const char *interface_name = getenv("PROCSTAT_INTERFACE");
if(interface_name && *interface_name) {
//for(i = 0; i < sizeof available_interfaces / sizeof *available_interfaces; i++) {
unsigned int i = 0;
while(1) {
interface = procstat_available_interfaces + i++;
if(!interface->name) {
fprintf(stderr, "procstat: requested interface '%s' not found\n",
interface_name);
break;
}
if(strcmp(interface->name, interface_name)) continue;
handle = interface->open(r);
if(!handle) {
fprintf(stderr, "procstat: failed to open requested interface '%s'\n",
interface_name);
interface = NULL;
}
break;
}
}
if(!handle) {
unsigned int i = 0;
do {
interface = procstat_available_interfaces + i++;
if(!interface->name) {
int e = errno;
free(r);
errno = e;
return NULL;
}
handle = interface->open(r);
} while(!handle);
}
r->handle = handle;
r->interface = interface;
return r;
}
void procstat_close(struct procstat_handle *handle) {
handle->interface->close(handle->handle);
free(handle);
}
int procstat_get(struct procstat_handle *handle, pid_t pid, int flags, struct procstat *ps) {
return handle->interface->get(handle->handle, pid, flags, ps);
}
int procstat_get_command_line(struct procstat_handle *handle, pid_t pid, char **command_line) {
return handle->interface->get_command_line(handle->handle, pid, command_line);
}
int procstat_get_argv(struct procstat_handle *handle, pid_t pid, int *argc, char ***argv) {
return handle->interface->get_argv(handle->handle, pid, argc, argv);
}
int procstat_get_path(struct procstat_handle *handle, pid_t pid, char **path) {
return handle->interface->get_path(handle->handle, pid, path);
}
int procstat_get_mac_label(struct procstat_handle *handle, pid_t pid, char **label) {
return handle->interface->get_mac_label(handle->handle, pid, label);
}
void procstat_walk(struct procstat_handle *handle, int walk_type, int flags, int (*func)(struct procstat_handle *, struct procstat *, void *), void *arg) {
return handle->interface->walk(handle->handle, walk_type, flags, func, arg);
}