Compare commits

...

2 Commits

  1. 7
      Makefile
  2. 156
      bmon.c

@ -1,10 +1,11 @@
CC = gcc CC = gcc
CFLAGS = -Wall -pedantic --std=c99 -O2 CFLAGS = -Wall -pedantic --std=c99 -O2
PREFIX = /usr/local
bmon: bmon.c bmon: bmon.c
dbg: install:
gcc -O0 -g bmon.c -o bmon-dbg cp bmon ${PREFIX}/bin/
clean: clean:
rm -f bmon bmon-dbg rm -f bmon

156
bmon.c

@ -1,8 +1,10 @@
#define _POSIX_C_SOURCE 200809L #define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h> #include <fcntl.h>
#include <dirent.h> #include <dirent.h>
#include <errno.h> #include <errno.h>
@ -10,8 +12,12 @@
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <limits.h>
const char *bat_base_path = "/sys/class/power_supply/"; // TODO: handle multiple batteries
const char *CAPACITY_PATH = "/sys/class/power_supply/BAT1/capacity";
const char *STATUS_PATH = "/sys/class/power_supply/BAT1/status";
const char *POWER_PATH = "/sys/class/power_supply/BAT1/power_now";
int dead = 0; int dead = 0;
void usage (void) void usage (void)
@ -26,9 +32,18 @@ void usage (void)
void int_handler (int signum) void int_handler (int signum)
{ {
(void)signum;
dead = 1; dead = 1;
} }
int read_int (FILE *fp)
{
int x;
freopen(NULL, "r", fp);
fscanf(fp, "%d", &x);
return x;
}
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
/* Handle SIGINT */ /* Handle SIGINT */
@ -73,100 +88,87 @@ int main (int argc, char *argv[])
} }
DIR *bdir = NULL; FILE *capacity_fp = NULL, *status_fp = NULL, *power_fp = NULL;
if (!(bdir = opendir(bat_base_path))) { capacity_fp = fopen(CAPACITY_PATH, "r");
perror("error opening base directory"); if (capacity_fp == NULL) {
fprintf(stderr, "Error opening %s: %s\n", CAPACITY_PATH, strerror(errno));
exit(1); exit(1);
} }
struct dirent *ent = NULL; if (wflag) {
FILE **fp_list = NULL; power_fp = fopen(POWER_PATH, "r");
int fp_num = 0; if (power_fp == NULL) {
for (;;) { fprintf(stderr, "Error opening %s: %s\n", POWER_PATH, strerror(errno));
errno = 0;
if (!(ent = readdir(bdir))) {
if (errno) {
perror("error reading base directory");
exit(1); exit(1);
} }
else break; status_fp = fopen(STATUS_PATH, "r");
if (status_fp == NULL) {
fprintf(stderr, "Error opening %s: %s\n", STATUS_PATH, strerror(errno));
exit(1);
} }
if (!strstr(ent->d_name, "BAT1"))
continue;
FILE *fp;
char path[sizeof(bat_base_path) + 256 + 64];
strcpy(path, bat_base_path);
strcat(path, ent->d_name);
if (wflag) {
char *tmp = malloc(1024);
strcpy(tmp, path);
strcat(tmp, "/status");
FILE *tmf = fopen(tmp, "r");
fgets(tmp, 1024, tmf);
if (!strstr(tmp, "Dis")) {
fprintf(stderr, "currently not discharging, cannot read power draw\n");
dead = 1;
} }
fclose(tmf);
free(tmp);
strcat(path, "/power_now");
} else strcat(path, "/capacity");
if ((fp = fopen(path, "r"))) {
FILE **tmp = NULL;
tmp = realloc(fp_list, sizeof(FILE *) * (fp_num + 1));
if (!tmp)
perror("failed realloc");
fp_list = tmp;
fp_list[fp_num++] = fp;
} else printf("err: %s\n", strerror(errno));
}
closedir(bdir);
if (!fp_num) {
printf("no files were opened\n");
dead = 1;
}
FILE * ofile_ptr = stdout; FILE *output_fp = stdout;
if (fflag) { if (fflag) {
if (!(ofile_ptr = fopen(ofile_path, "w"))) { if ((output_fp = fopen(ofile_path, "w")) == NULL) {
char *tmp = malloc(1024); fprintf(stderr, "Error opening %s: %s\n", ofile_path, strerror(errno));
snprintf(tmp, 1024, "could not open %s", ofile_path);
perror(tmp);
free(tmp);
exit(1); exit(1);
} }
} }
long int elapsed_time = 0; long int elapsed_time = 0;
long val; fprintf(output_fp, "TIME\t");
char buf[64]; fprintf(output_fp, "CAP\t");
for (; !dead ; sleep(wait_time)) { if (wflag) fprintf(output_fp, "WATTS");
for (int i = 0; i < fp_num; i++) { fprintf(output_fp, "\n");
if (!freopen(NULL, "r", fp_list[i])) { while (!dead) {
perror("error reading the file"); int capacity = read_int(capacity_fp);
dead = 1; float power = 0;
if (capacity < 0) {
fprintf(stderr, "Error reading capacity: %s\n", strerror(errno));
break;
} }
if (!fgets(buf, 64, fp_list[i])) if (wflag) {
dead = 1; power = read_int(power_fp);
val = atol(buf); if (power < 0) {
fprintf(ofile_ptr, "%ld\t", wflag ? (long)(val / 1E3) : val); fprintf(stderr, "Error reading power: %s\n", strerror(errno));
break;
} }
fprintf(ofile_ptr, "%ld\n", uflag ? time(NULL) : elapsed_time); static char b[128] = {0};
if (fflush(ofile_ptr)) { freopen(NULL, "r", status_fp);
perror("error writing to file"); if (fgets(b, sizeof(b), status_fp) == NULL) {
dead = 1; fprintf(stderr, "Error reading status: %s\n", strerror(errno));
}
if (strncmp(b, "Discharging\n", sizeof(b)) == 0) {
power *= -1;
}
// power is in microwatts
power /= 1e6;
} }
fprintf(output_fp, "%ld\t", uflag ? time(NULL) : elapsed_time);
fprintf(output_fp, "%d\t", capacity);
if (wflag) fprintf(output_fp, "%.2f", power);
fprintf(output_fp, "\n");
sleep(wait_time);
elapsed_time += wait_time; elapsed_time += wait_time;
} }
if (fflag) if (fflag) {
fclose(ofile_ptr); fclose(output_fp);
for (int i = 0; i < fp_num; i++) }
fclose(fp_list[i]); if (capacity_fp) {
free(fp_list); fclose(capacity_fp);
}
if (status_fp) {
fclose(status_fp);
}
if (power_fp) {
fclose(power_fp);
}
return 0; return 0;
} }

Loading…
Cancel
Save