Battery MONitor, log battery/power status on stdout
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

167 lines
3.2 KiB

#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
const char *bat_base_path = "/sys/class/power_supply/";
int dead = 0;
void usage (void)
{
printf("usage: bmon [-wuh] [-f file] [-t interval]\n");
}
void int_handler (int signum)
{
dead = 1;
}
int main (int argc, char *argv[])
{
/* Handle SIGINT */
dead = 0;
struct sigaction action;
memset(&action, 0, sizeof(action));
action.sa_handler = int_handler;
sigaction(SIGINT, &action, NULL);
int wflag = 0;
int wait_time = 10;
int fflag = 0;
int uflag = 0;
char ofile_path[256];
int opc;
while ((opc = getopt(argc, argv, "uhwf:t:")) != -1) {
switch (opc) {
case 'w':
wflag = 1;
break;
case 'f':
fflag = 1;
strncpy(ofile_path, optarg, 255);
break;
case 't':
wait_time = atoi(optarg);
if (wait_time < 1) {
usage();
exit(1);
}
break;
case 'u':
uflag = 1;
break;
case 'h':
default: /* '?' */
usage();
exit(1);
break;
}
}
DIR *bdir = NULL;
if (!(bdir = opendir(bat_base_path))) {
perror("error opening base directory");
exit(1);
}
struct dirent *ent = NULL;
FILE **fp_list = NULL;
int fp_num = 0;
for (;;) {
errno = 0;
if (!(ent = readdir(bdir))) {
if (errno) {
perror("error reading base directory");
exit(1);
}
else break;
}
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;
if (fflag) {
if (!(ofile_ptr = fopen(ofile_path, "w"))) {
char *tmp = malloc(1024);
snprintf(tmp, 1024, "could not open %s", ofile_path);
perror(tmp);
free(tmp);
exit(1);
}
}
long int elapsed_time = 0;
long val;
char buf[64];
for (; !dead ; sleep(wait_time)) {
for (int i = 0; i < fp_num; i++) {
if (!freopen(NULL, "r", fp_list[i])) {
perror("error reading the file");
dead = 1;
}
if (!fgets(buf, 64, fp_list[i]))
dead = 1;
val = atol(buf);
fprintf(ofile_ptr, "%ld\t", wflag ? (long)(val / 1E3) : val);
}
fprintf(ofile_ptr, "%ld\n", uflag ? time(NULL) : elapsed_time);
if (fflush(ofile_ptr)) {
perror("error writing to file");
dead = 1;
}
elapsed_time += wait_time;
}
if (fflag)
fclose(ofile_ptr);
for (int i = 0; i < fp_num; i++)
fclose(fp_list[i]);
free(fp_list);
return 0;
}