From 0fa03322a935a6ffc564852068f13302f3dd1e72 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Sun, 19 Jun 2016 18:55:35 -0300 Subject: Dynamically adjust the size of line reads * Dynamically adjust the size of line reads. * Remove some more uses of fgets with arbitrary sizes. * Fix reading of lines and width of n column. Fixes #514. --- OpenFilesScreen.c | 22 ++++++++++------------ Settings.c | 11 +++++++---- StringUtils.c | 29 ++++++++++++++++++++++++++++- StringUtils.h | 4 ++++ linux/Battery.c | 17 +++++++++-------- 5 files changed, 58 insertions(+), 25 deletions(-) diff --git a/OpenFilesScreen.c b/OpenFilesScreen.c index 1eda3731..80079d04 100644 --- a/OpenFilesScreen.c +++ b/OpenFilesScreen.c @@ -86,17 +86,12 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { pdata->error = 127; return pdata; } - while (!feof(fd)) { - int cmd = fgetc(fd); - if (cmd == EOF) - break; - char* entry = xMalloc(1024); - if (!fgets(entry, 1024, fd)) { - free(entry); + for (;;) { + char* line = String_readLine(fd); + if (!line) { break; } - char* newline = strrchr(entry, '\n'); - *newline = '\0'; + unsigned char cmd = line[0]; if (cmd == 'f') { OpenFiles_FileData* nextFile = xCalloc(1, sizeof(OpenFiles_FileData)); if (fdata == NULL) { @@ -108,7 +103,8 @@ static OpenFiles_ProcessData* OpenFilesScreen_getProcessData(pid_t pid) { item = &(fdata->data); } assert(cmd >= 0 && cmd <= 0xff); - item->data[cmd] = entry; + item->data[cmd] = xStrdup(line + 1); + free(line); } pdata->error = pclose(fd); return pdata; @@ -132,9 +128,11 @@ void OpenFilesScreen_scan(InfoScreen* this) { } else { OpenFiles_FileData* fdata = pdata->files; while (fdata) { - char entry[1024]; char** data = fdata->data.data; - sprintf(entry, "%5s %4s %10s %10s %10s %s", + int lenN = data['n'] ? strlen(data['n']) : 0; + int sizeEntry = 5 + 7 + 10 + 10 + 10 + lenN + 5 /*spaces*/ + 1 /*null*/; + char* entry = xMalloc(sizeEntry); + snprintf(entry, sizeEntry, "%5.5s %7.7s %10.10s %10.10s %10.10s %s", data['f'] ? data['f'] : "", data['t'] ? data['t'] : "", data['D'] ? data['D'] : "", diff --git a/Settings.c b/Settings.c index eaca7829..0e296c10 100644 --- a/Settings.c +++ b/Settings.c @@ -173,12 +173,15 @@ static bool Settings_read(Settings* this, const char* fileName) { if (!fd) return false; - const int maxLine = 2048; - char buffer[maxLine]; bool readMeters = false; - while (fgets(buffer, maxLine, fd)) { + for (;;) { + char* line = String_readLine(fd); + if (!line) { + break; + } int nOptions; - char** option = String_split(buffer, '=', &nOptions); + char** option = String_split(line, '=', &nOptions); + free (line); if (nOptions < 2) { String_freeArray(option); continue; diff --git a/StringUtils.c b/StringUtils.c index 4465fb15..b53f5eea 100644 --- a/StringUtils.c +++ b/StringUtils.c @@ -13,9 +13,10 @@ in the source distribution for its full text. #include #include #include -#include /*{ +#include + #define String_startsWith(s, match) (strstr((s), (match)) == (s)) #define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL) }*/ @@ -119,3 +120,29 @@ char* String_getToken(const char* line, const unsigned short int numMatch) { match[foundCount] = '\0'; return((char*)xStrdup(match)); } + +char* String_readLine(FILE* fd) { + const int step = 1024; + int bufSize = step; + char* buffer = xMalloc(step + 1); + char* at = buffer; + for (;;) { + char* ok = fgets(at, step + 1, fd); + if (!ok) { + free(buffer); + return NULL; + } + char* newLine = strrchr(at, '\n'); + if (newLine) { + *newLine = '\0'; + return buffer; + } else { + if (feof(fd)) { + return buffer; + } + } + bufSize += step; + buffer = xRealloc(buffer, bufSize + 1); + at = buffer + bufSize - step; + } +} diff --git a/StringUtils.h b/StringUtils.h index 38ffae7f..97620342 100644 --- a/StringUtils.h +++ b/StringUtils.h @@ -9,6 +9,8 @@ Released under the GNU GPL, see the COPYING file in the source distribution for its full text. */ +#include + #define String_startsWith(s, match) (strstr((s), (match)) == (s)) #define String_contains_i(s1, s2) (strcasestr(s1, s2) != NULL) @@ -24,4 +26,6 @@ void String_freeArray(char** s); char* String_getToken(const char* line, const unsigned short int numMatch); +char* String_readLine(FILE* fd); + #endif diff --git a/linux/Battery.c b/linux/Battery.c index 572bad48..10681844 100644 --- a/linux/Battery.c +++ b/linux/Battery.c @@ -65,10 +65,11 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short break; } - char line[50] = ""; + char* line = NULL; for (unsigned short int i = 0; i < lineNum; i++) { - char* ok = fgets(line, sizeof line, file); - if (!ok) break; + free(line); + line = String_readLine(file); + if (!line) break; } fclose(file); @@ -76,7 +77,8 @@ static unsigned long int parseBatInfo(const char *fileName, const unsigned short char *foundNumStr = String_getToken(line, wordNum); const unsigned long int foundNum = atoi(foundNumStr); free(foundNumStr); - + free(line); + total += foundNum; } @@ -116,14 +118,13 @@ static ACPresence procAcpiCheck() { continue; } - char line[100]; - char* ok = fgets(line, sizeof line, file); - if (!ok) continue; - line[sizeof(line) - 1] = '\0'; + char* line = String_readLine(file); + if (!line) continue; fclose(file); const char *isOnline = String_getToken(line, 2); + free(line); if (strcmp(isOnline, "on-line") == 0) { isOn = AC_PRESENT; -- cgit v1.2.3