| /* 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); |
| } |