diff --git a/bmon.c b/bmon.c index d4b0eef..8b37fce 100644 --- a/bmon.c +++ b/bmon.c @@ -1,8 +1,10 @@ #define _POSIX_C_SOURCE 200809L -#include -#include + #include #include + +#include +#include #include #include #include @@ -10,8 +12,12 @@ #include #include #include +#include -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; void usage (void) @@ -26,17 +32,26 @@ void usage (void) void int_handler (int signum) { + (void)signum; 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[]) { /* Handle SIGINT */ - dead = 0; - struct sigaction action; - memset(&action, 0, sizeof(action)); - action.sa_handler = int_handler; - sigaction(SIGINT, &action, NULL); + 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; @@ -73,100 +88,87 @@ int main (int argc, char *argv[]) } - DIR *bdir = NULL; - if (!(bdir = opendir(bat_base_path))) { - perror("error opening base directory"); + FILE *capacity_fp = NULL, *status_fp = NULL, *power_fp = NULL; + capacity_fp = fopen(CAPACITY_PATH, "r"); + if (capacity_fp == NULL) { + fprintf(stderr, "Error opening %s: %s\n", CAPACITY_PATH, strerror(errno)); 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 (wflag) { + power_fp = fopen(POWER_PATH, "r"); + if (power_fp == NULL) { + fprintf(stderr, "Error opening %s: %s\n", POWER_PATH, strerror(errno)); + exit(1); + } + 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 (!(ofile_ptr = fopen(ofile_path, "w"))) { - char *tmp = malloc(1024); - snprintf(tmp, 1024, "could not open %s", ofile_path); - perror(tmp); - free(tmp); + if ((output_fp = fopen(ofile_path, "w")) == NULL) { + fprintf(stderr, "Error opening %s: %s\n", ofile_path, strerror(errno)); 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(output_fp, "TIME\t"); + fprintf(output_fp, "CAP\t"); + if (wflag) fprintf(output_fp, "WATTS"); + fprintf(output_fp, "\n"); + while (!dead) { + int capacity = read_int(capacity_fp); + float power = 0; + if (capacity < 0) { + fprintf(stderr, "Error reading capacity: %s\n", strerror(errno)); + break; } - fprintf(ofile_ptr, "%ld\n", uflag ? time(NULL) : elapsed_time); - if (fflush(ofile_ptr)) { - perror("error writing to file"); - dead = 1; + if (wflag) { + power = read_int(power_fp); + if (power < 0) { + fprintf(stderr, "Error reading power: %s\n", strerror(errno)); + break; + } + static char b[128] = {0}; + freopen(NULL, "r", status_fp); + if (fgets(b, sizeof(b), status_fp) == NULL) { + 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; } - if (fflag) - fclose(ofile_ptr); - for (int i = 0; i < fp_num; i++) - fclose(fp_list[i]); - free(fp_list); + if (fflag) { + fclose(output_fp); + } + if (capacity_fp) { + fclose(capacity_fp); + } + if (status_fp) { + fclose(status_fp); + } + if (power_fp) { + fclose(power_fp); + } + return 0; }