#define _POSIX_C_SOURCE 200809L #include #include #include #include #include #include #include #include #include #include #include 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; }