Refactor and fix resource leaks.

This commit is contained in:
Hisham Muhammad 2014-04-22 18:19:01 -03:00
parent 79e390120a
commit b1564c2be9
1 changed files with 126 additions and 134 deletions

View File

@ -36,12 +36,13 @@ int BatteryMeter_attributes[] = {
static unsigned long int parseUevent(FILE * file, const char *key) { static unsigned long int parseUevent(FILE * file, const char *key) {
char line[100]; char line[100];
unsigned long int dValue = 0; unsigned long int dValue = 0;
char* saveptr;
while (fgets(line, sizeof line, file)) { while (fgets(line, sizeof line, file)) {
if (strncmp(line, key, strlen(key)) == 0) { if (strncmp(line, key, strlen(key)) == 0) {
char *value; char *value;
strtok(line, "="); strtok_r(line, "=", &saveptr);
value = strtok(NULL, "="); value = strtok_r(NULL, "=", &saveptr);
dValue = atoi(value); dValue = atoi(value);
break; break;
} }
@ -55,81 +56,78 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short
if (!batteryDir) if (!batteryDir)
return 0; return 0;
typedef struct listLbl { char* batteries[64];
char *content; unsigned int nBatteries = 0;
struct listLbl *next; memset(batteries, sizeof batteries, sizeof (char*));
} list;
list *myList = NULL;
list *newEntry;
/*
Some of this is based off of code found in kismet (they claim it came from gkrellm).
Written for multi battery use...
*/
for (const struct dirent* dirEntries = readdir((DIR *) batteryDir); dirEntries; dirEntries = readdir((DIR *) batteryDir)) {
char* entryName = (char *) dirEntries->d_name;
struct dirent result;
struct dirent* dirEntry;
while (nBatteries < sizeof batteries) {
readdir_r(batteryDir, &result, &dirEntry);
if (!dirEntry)
break;
char* entryName = dirEntry->d_name;
if (strncmp(entryName, "BAT", 3)) if (strncmp(entryName, "BAT", 3))
continue; continue;
batteries[nBatteries] = strdup(entryName);
newEntry = calloc(1, sizeof(list)); nBatteries++;
newEntry->next = myList;
newEntry->content = entryName;
myList = newEntry;
} }
closedir(batteryDir);
unsigned long int total = 0; unsigned long int total = 0;
for (newEntry = myList; newEntry; newEntry = newEntry->next) { for (unsigned int i = 0; i < nBatteries; i++) {
const char infoPath[30]; char infoPath[30];
const FILE *file; snprintf(infoPath, sizeof infoPath, "%s%s/%s", batteryPath, batteries[i], fileName);
FILE* file = fopen(infoPath, "r");
if (!file) {
break;
}
char line[50]; char line[50];
snprintf((char *) infoPath, sizeof infoPath, "%s%s/%s", batteryPath, newEntry->content, fileName);
if ((file = fopen(infoPath, "r")) == NULL) {
closedir(batteryDir);
return 0;
}
for (unsigned short int i = 0; i < lineNum; i++) { for (unsigned short int i = 0; i < lineNum; i++) {
fgets(line, sizeof line, (FILE *) file); fgets(line, sizeof line, file);
} }
fclose((FILE *) file); fclose(file);
const char *foundNumTmp = String_getToken(line, wordNum); char *foundNumStr = String_getToken(line, wordNum);
const unsigned long int foundNum = atoi(foundNumTmp); const unsigned long int foundNum = atoi(foundNumStr);
free((char *) foundNumTmp); free(foundNumStr);
total += foundNum; total += foundNum;
} }
free(myList); for (unsigned int i = 0; i < nBatteries; i++) {
free(newEntry); free(batteries[i]);
closedir(batteryDir); }
return total; return total;
} }
static ACPresence chkIsOnline() { static ACPresence procAcpiCheck() {
FILE *file = NULL;
ACPresence isOn = AC_ERROR; ACPresence isOn = AC_ERROR;
if (access(PROCDIR "/acpi/ac_adapter", F_OK) == 0) {
const char *power_supplyPath = PROCDIR "/acpi/ac_adapter"; const char *power_supplyPath = PROCDIR "/acpi/ac_adapter";
DIR *power_supplyDir = opendir(power_supplyPath); DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir) if (!power_supplyDir) {
return AC_ERROR; return AC_ERROR;
}
for (const struct dirent *dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) { struct dirent result;
char* entryName = (char *) dirEntries->d_name; struct dirent* dirEntry;
for (;;) {
readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (!dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (entryName[0] != 'A') if (entryName[0] != 'A')
continue; continue;
char statePath[50]; char statePath[50];
snprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName); snprintf((char *) statePath, sizeof statePath, "%s/%s/state", power_supplyPath, entryName);
file = fopen(statePath, "r"); FILE* file = fopen(statePath, "r");
if (!file) { if (!file) {
isOn = AC_ERROR; isOn = AC_ERROR;
@ -140,84 +138,76 @@ static ACPresence chkIsOnline() {
fgets(line, sizeof line, file); fgets(line, sizeof line, file);
line[sizeof(line) - 1] = '\0'; line[sizeof(line) - 1] = '\0';
if (file) {
fclose(file); fclose(file);
file = NULL;
}
const char *isOnline = String_getToken(line, 2); const char *isOnline = String_getToken(line, 2);
if (strcmp(isOnline, "on-line") == 0) { if (strcmp(isOnline, "on-line") == 0) {
free((char *) isOnline);
isOn = AC_PRESENT; isOn = AC_PRESENT;
// If any AC adapter is being used then stop
break;
} else { } else {
isOn = AC_ABSENT; isOn = AC_ABSENT;
} }
free((char *) isOnline); free((char *) isOnline);
if (isOn == AC_PRESENT) {
break;
}
} }
if (power_supplyDir) if (power_supplyDir)
closedir(power_supplyDir); closedir(power_supplyDir);
return isOn;
}
} else { static ACPresence sysCheck() {
ACPresence isOn = AC_ERROR;
const char *power_supplyPath = "/sys/class/power_supply"; const char *power_supplyPath = "/sys/class/power_supply";
if (access("/sys/class/power_supply", F_OK) == 0) {
const struct dirent *dirEntries;
DIR *power_supplyDir = opendir(power_supplyPath); DIR *power_supplyDir = opendir(power_supplyPath);
char *entryName;
if (!power_supplyDir) { if (!power_supplyDir) {
return AC_ERROR; return AC_ERROR;
} }
for (dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) { struct dirent result;
entryName = (char *) dirEntries->d_name; struct dirent* dirEntry;
for (;;) {
readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (!dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (strncmp(entryName, "A", 1)) { if (strncmp(entryName, "A", 1)) {
continue; continue;
} }
char onlinePath[50]; char onlinePath[50];
snprintf((char *) onlinePath, sizeof onlinePath, "%s/%s/online", power_supplyPath, entryName); snprintf((char *) onlinePath, sizeof onlinePath, "%s/%s/online", power_supplyPath, entryName);
file = fopen(onlinePath, "r"); FILE* file = fopen(onlinePath, "r");
if (!file) { if (!file) {
isOn = AC_ERROR; isOn = AC_ERROR;
continue; } else {
}
isOn = (fgetc(file) - '0'); isOn = (fgetc(file) - '0');
if (file) {
fclose(file); fclose(file);
file = NULL;
}
if (isOn == AC_PRESENT) { if (isOn == AC_PRESENT) {
// If any AC adapter is being used then stop // If any AC adapter is being used then stop
break; break;
} else { }
continue;
} }
} }
if (power_supplyDir) if (power_supplyDir)
closedir(power_supplyDir); closedir(power_supplyDir);
}
}
// Just in case :-)
if (file)
fclose(file);
return isOn; return isOn;
} }
static ACPresence chkIsOnline() {
if (access(PROCDIR "/acpi/ac_adapter", F_OK) == 0) {
return procAcpiCheck();
} else if (access("/sys/class/power_supply", F_OK) == 0) {
return sysCheck();
} else {
return AC_ERROR;
}
}
static double getProcBatData() { static double getProcBatData() {
const unsigned long int totalFull = parseBatInfo("info", 3, 4); const unsigned long int totalFull = parseBatInfo("info", 3, 4);
if (totalFull == 0) if (totalFull == 0)
@ -232,19 +222,21 @@ static double getProcBatData() {
} }
static double getSysBatData() { static double getSysBatData() {
const struct dirent *dirEntries;
const char *power_supplyPath = "/sys/class/power_supply/"; const char *power_supplyPath = "/sys/class/power_supply/";
DIR *power_supplyDir = opendir(power_supplyPath); DIR *power_supplyDir = opendir(power_supplyPath);
if (!power_supplyDir) if (!power_supplyDir)
return 0; return 0;
char *entryName;
unsigned long int totalFull = 0; unsigned long int totalFull = 0;
unsigned long int totalRemain = 0; unsigned long int totalRemain = 0;
for (dirEntries = readdir((DIR *) power_supplyDir); dirEntries; dirEntries = readdir((DIR *) power_supplyDir)) { struct dirent result;
entryName = (char *) dirEntries->d_name; struct dirent* dirEntry;
for (;;) {
readdir_r((DIR *) power_supplyDir, &result, &dirEntry);
if (!dirEntry)
break;
char* entryName = (char *) dirEntry->d_name;
if (strncmp(entryName, "BAT", 3)) { if (strncmp(entryName, "BAT", 3)) {
continue; continue;