machine: Explain use of machine and tidy Linuxisms

The functions machine.h provides are deliberately using standard
functions from a base install of the operating system. This IS
intentional. I'd like to be able to modify and reuse this anywhere
without having to untangle additional dependencies from machine to
machine.
This commit is contained in:
Alastair Poole 2020-07-11 13:09:38 +01:00
parent b018c8a3f7
commit 09e8249689
4 changed files with 61 additions and 66 deletions

View File

@ -13,6 +13,7 @@
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#define _DEFAULT_SOURCE #define _DEFAULT_SOURCE
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -76,7 +77,7 @@ _network_transfer_get_thread_cb(void *arg)
system_network_transfer_get(usage); system_network_transfer_get(usage);
return (void *)0; return NULL;
} }
void void
@ -86,13 +87,10 @@ system_info_all_free(Sys_Info *info)
int i; int i;
for (i = 0; i < info->cpu_count; i++) for (i = 0; i < info->cpu_count; i++)
{ free(info->cores[i]);
free(info->cores[i]);
}
free(info->cores); free(info->cores);
for (i = 0; i < info->sensor_count; i++) for (i = 0; i < info->sensor_count; i++) {
{
snsr = info->sensors[i]; snsr = info->sensors[i];
if (snsr->name) if (snsr->name)
free(snsr->name); free(snsr->name);
@ -101,8 +99,7 @@ system_info_all_free(Sys_Info *info)
if (info->sensors) if (info->sensors)
free(info->sensors); free(info->sensors);
for (i = 0; i < info->power.battery_count; i++) for (i = 0; i < info->power.battery_count; i++) {
{
if (info->power.batteries[i]->name) if (info->power.batteries[i]->name)
free(info->power.batteries[i]->name); free(info->power.batteries[i]->name);
#if defined(__OpenBSD__) #if defined(__OpenBSD__)

View File

@ -1,6 +1,12 @@
#ifndef __MACHINE_H__ #ifndef __MACHINE_H__
#define __MACHINE_H__ #define __MACHINE_H__
/* All functions and data types implementing these APIs have no additional
* system dependencies deliberately.
*
* See machine.c and the files includes in machine/ sub directory.
*/
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -13,15 +19,15 @@ typedef struct
typedef struct typedef struct
{ {
unsigned long long total; uint64_t total;
unsigned long long used; uint64_t used;
unsigned long long cached; uint64_t cached;
unsigned long long buffered; uint64_t buffered;
unsigned long long shared; uint64_t shared;
unsigned long long swap_total; uint64_t swap_total;
unsigned long long swap_used; uint64_t swap_used;
unsigned long long zfs_arc_used; uint64_t zfs_arc_used;
} meminfo_t; } meminfo_t;
typedef struct typedef struct
@ -63,11 +69,12 @@ struct Sys_Info
{ {
int cpu_count; int cpu_count;
cpu_core_t **cores; cpu_core_t **cores;
meminfo_t memory; meminfo_t memory;
power_t power; power_t power;
int sensor_count; int sensor_count;
sensor_t **sensors; sensor_t **sensors;
network_t network_usage; network_t network_usage;
}; };

View File

@ -15,6 +15,9 @@
*/ */
#if defined(__linux__) #if defined(__linux__)
#include <stdarg.h>
char * char *
file_contents(const char *path) file_contents(const char *path)
{ {
@ -49,6 +52,20 @@ file_contents(const char *path)
return buf; return buf;
} }
char *
strsli_printf(const char *fmt, ...)
{
static char buf[4096];
va_list ap;
buf[0] = 0x00;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
return buf;
}
#endif #endif
#if defined(__FreeBSD__) || defined(__DragonFly__) #if defined(__FreeBSD__) || defined(__DragonFly__)

View File

@ -71,7 +71,6 @@ system_sensors_thermal_get(int *sensor_count)
#elif defined(__linux__) #elif defined(__linux__)
sensor_t *sensor; sensor_t *sensor;
char *type, *value; char *type, *value;
char path[PATH_MAX];
struct dirent **names; struct dirent **names;
int i, n; int i, n;
@ -84,10 +83,8 @@ system_sensors_thermal_get(int *sensor_count)
free(names[i]); free(names[i]);
continue; continue;
} }
snprintf(path, sizeof(path), "/sys/class/thermal/%s/type",
names[i]->d_name);
type = file_contents(path); type = file_contents(strsli_printf("/sys/class/thermal/%s/type", names[i]->d_name));
if (type) if (type)
{ {
sensors = sensors =
@ -95,11 +92,9 @@ system_sensors_thermal_get(int *sensor_count)
sensors[(*sensor_count)++] = sensors[(*sensor_count)++] =
sensor = calloc(1, sizeof(sensor_t)); sensor = calloc(1, sizeof(sensor_t));
sensor->name = strdup(type); sensor->name = type;
snprintf(path, sizeof(path), "/sys/class/thermal/%s/temp",
names[i]->d_name);
value = file_contents(path); value = file_contents(strsli_printf("/sys/class/thermal/%s/temp", names[i]->d_name));
if (!value) if (!value)
sensor->invalid = true; sensor->invalid = true;
else else
@ -107,7 +102,6 @@ system_sensors_thermal_get(int *sensor_count)
sensor->value = (float)atoi(value) / 1000.0; sensor->value = (float)atoi(value) / 1000.0;
free(value); free(value);
} }
free(type);
} }
free(names[i]); free(names[i]);
@ -180,7 +174,6 @@ _power_battery_count_get(power_t *power)
} }
#elif defined(__linux__) #elif defined(__linux__)
char *type; char *type;
char path[PATH_MAX];
struct dirent **names; struct dirent **names;
int i, n, id; int i, n, id;
@ -188,10 +181,7 @@ _power_battery_count_get(power_t *power)
if (n < 0) return power->battery_count; if (n < 0) return power->battery_count;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
snprintf(path, sizeof(path), "/sys/class/power_supply/%s/type", type = file_contents(strsli_printf("/sys/class/power_supply/%s/type", names[i]->d_name));
names[i]->d_name);
type = file_contents(path);
if (type) if (type)
{ {
if (!strncmp(type, "Battery", 7)) if (!strncmp(type, "Battery", 7))
@ -287,24 +277,20 @@ _battery_state_get(power_t *power)
close(fd); close(fd);
#elif defined(__linux__) #elif defined(__linux__)
char path[PATH_MAX]; const char *path;
struct dirent *dh; struct dirent *dh;
struct stat st; struct stat st;
DIR *dir; DIR *dir;
char *model, *vendor; char *model, *vendor;
char *buf, *naming = NULL; char *buf, *naming = NULL;
int i = 0;
unsigned long charge_full = 0;
unsigned long charge_current = 0;
for (i = 0; i < power->battery_count; i++) { for (int i = 0; i < power->battery_count; i++) {
naming = NULL; naming = NULL;
snprintf(path, sizeof(path), "/sys/class/power_supply/%s",
power->batteries[i]->name);
if (stat(path, &st) < 0) continue; path = strsli_printf("/sys/class/power_suppy/%s", power->batteries[i]->name);
if (S_ISLNK(st.st_mode)) continue;
if (!S_ISDIR(st.st_mode)) continue; if (((stat(path, &st) < 0)) || (S_ISLNK(st.st_mode)) || (!S_ISDIR(st.st_mode)))
continue;
dir = opendir(path); dir = opendir(path);
if (!dir) return; if (!dir) return;
@ -324,34 +310,28 @@ _battery_state_get(power_t *power)
if (!naming) if (!naming)
continue; continue;
snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_full", buf = file_contents(strsli_printf("/sys/class/power_supply/%s/%s_full",
power->batteries[i]->name, naming); power->batteries[i]->name, naming));
buf = file_contents(path);
if (buf) if (buf)
{ {
charge_full = atol(buf); power->batteries[i]->charge_full = atol(buf);
free(buf); free(buf);
} }
snprintf(path, sizeof(path), "/sys/class/power_supply/%s/%s_now", buf = file_contents(strsli_printf("/sys/class/power_supply/%s/%s_now",
power->batteries[i]->name, naming); power->batteries[i]->name, naming));
buf = file_contents(path);
if (buf) if (buf)
{ {
charge_current = atol(buf); power->batteries[i]->charge_current = atol(buf);
free(buf); free(buf);
} }
snprintf(path, sizeof(path), "/sys/class/power_supply/%s/manufacturer", vendor = file_contents(strsli_printf("/sys/class/power_supply/%s/manufacturer",
power->batteries[i]->name); power->batteries[i]->name));
vendor = file_contents(path); model = file_contents(strsli_printf("/sys/class/power_supply/%s/model_name",
power->batteries[i]->name));
snprintf(path, sizeof(path), "/sys/class/power_supply/%s/model_name",
power->batteries[i]->name);
model = file_contents(path);
if (vendor && vendor[0] && model && model[0]) if (vendor && vendor[0] && model && model[0])
{ {
char name[256];
int len; int len;
len = strlen(vendor) - 1; len = strlen(vendor) - 1;
@ -363,13 +343,8 @@ _battery_state_get(power_t *power)
model[len] = '\0'; model[len] = '\0';
free(power->batteries[i]->name);; free(power->batteries[i]->name);;
snprintf(name, sizeof(name), "%s %s", vendor, model); power->batteries[i]->name = strdup(strsli_printf("%s %s", vendor, model));
power->batteries[i]->name = strdup(name);
} }
power->batteries[i]->charge_full = charge_full;
power->batteries[i]->charge_current = charge_current;
if (model) if (model)
free(model); free(model);
if (vendor) if (vendor)
@ -417,13 +392,12 @@ system_power_state_get(power_t *power)
} }
#endif #endif
_battery_state_get(power); _battery_state_get(power);
for (i = 0; i < power->battery_count; i++) { for (i = 0; i < power->battery_count; i++) {
double percent = 100 * power->batteries[i]->percent = 100 *
(power->batteries[i]->charge_current / (power->batteries[i]->charge_current /
power->batteries[i]->charge_full); power->batteries[i]->charge_full);
power->batteries[i]->percent = percent;
} }
} }