For 3.4.NN kernels current battery charge level and the maximum it can reach are available in /sys/class/power_supply/BAT*
(usually BAT0
as you normally have just one battery) in files charge_now
and charge_full
. So something along the lines of following should meet your needs.
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <dirent.h>
#include <linux/limits.h>
#include <regex.h>
#define _DATADIR "/sys/class/power_supply"
int main(int argc, char **argv) {
FILE *f_c, *f_f;
long current, full;
DIR *d;
struct dirent *dp;
char b[PATH_MAX];
if((d = opendir(_DATADIR)) == NULL) {
fprintf(stderr, "opendir: %s\n", strerror(errno));
return 3;
}
while((dp = readdir(d)) != NULL) {
snprintf(b, PATH_MAX, "%s/%s", _DATADIR, dp->d_name);
regex_t regex;
if(regcomp(®ex, "BAT[[:alnum:]]+", REG_EXTENDED) != 0) {
fprintf(stderr, "regcomp: %s\n", strerror(errno));
return 4;
}
if(regexec(®ex, b, 0, NULL, 0) == 0) {
snprintf(b, PATH_MAX, "%s/%s/%s", _DATADIR, dp->d_name, "charge_now");
f_c = fopen(b, "r");
snprintf(b, PATH_MAX, "%s/%s/%s", _DATADIR, dp->d_name, "charge_full");
f_f = fopen(b, "r");
if(f_c != NULL && f_f != NULL) {
if(fscanf(f_c, "%ld", ¤t) != 1 || fscanf(f_f, "%ld", &full) != 1)
fprintf(stderr, "fscanf: %s\n", strerror(errno));
else
fprintf(stdout, "charge for %s %.2f\n", dp->d_name,
(current / full) * 100.0);
fclose(f_c);
fclose(f_f);
}
}
regfree(®ex);
}
return 0;
}