From 49bb3c49acf9fb53a30c818efc03d835e5341a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 9 Aug 2024 17:57:10 +0200 Subject: [PATCH] Silence clang analyzer warnings linux/LinuxProcessTable.c:795:11: warning: File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior [unix.Stream] 795 | while (fgets(buffer, sizeof(buffer), fp)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxProcessTable.c:795:11: warning: Read function called when stream is in EOF state. Function has no effect [unix.Stream] 795 | while (fgets(buffer, sizeof(buffer), fp)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxProcessTable.c:840:11: warning: File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior [unix.Stream] 840 | while (fgets(linebuf, sizeof(linebuf), file) != NULL) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxProcessTable.c:840:11: warning: Read function called when stream is in EOF state. Function has no effect [unix.Stream] 840 | while (fgets(linebuf, sizeof(linebuf), file) != NULL) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxMachine.c:81:22: warning: The 1st argument to 'openat' is between -99 and -1 but should be a valid file descriptor or AT_FDCWD [unix.StdCLibraryFunctions] 81 | int cpuDirFd = openat(dirfd(dir), entry->d_name, O_DIRECTORY | O_PATH | O_NOFOLLOW); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxMachine.c:501:11: warning: File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior [unix.Stream] 501 | while (fgets(buffer, sizeof(buffer), file)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/LinuxMachine.c:501:11: warning: Read function called when stream is in EOF state. Function has no effect [unix.Stream] 501 | while (fgets(buffer, sizeof(buffer), file)) { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/Platform.c:467:22: warning: File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior [unix.Stream] 467 | } while ((bytes = fread(env + size, 1, capacity - size, fp)) > 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/Platform.c:467:22: warning: Read function called when stream is in EOF state. Function has no effect [unix.Stream] 467 | } while ((bytes = fread(env + size, 1, capacity - size, fp)) > 0); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/Platform.c:585:15: warning: File position of the stream might be 'indeterminate' after a failed operation. Can cause undefined behavior [unix.Stream] 585 | total = fscanf(fp, "full avg10=%32lf avg60=%32lf avg300=%32lf total=%*f ", ten, sixty, threehundred); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/Platform.c:585:15: warning: Read function called when stream is in EOF state. Function has no effect [unix.Stream] 585 | total = fscanf(fp, "full avg10=%32lf avg60=%32lf avg300=%32lf total=%*f ", ten, sixty, threehundred); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ linux/Platform.c:789:21: warning: The 1st argument to 'openat' is between -99 and -1 but should be a valid file descriptor or AT_FDCWD [unix.StdCLibraryFunctions] 789 | int entryFd = openat(dirfd(dir), entryName, O_DIRECTORY | O_PATH); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- XUtils.h | 17 +++++++++++++++++ linux/LinuxMachine.c | 14 ++++++++------ linux/LinuxProcessTable.c | 16 ++++++---------- linux/Platform.c | 6 +++--- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/XUtils.h b/XUtils.h index 73335a611..17576f937 100644 --- a/XUtils.h +++ b/XUtils.h @@ -14,6 +14,7 @@ in the source distribution for its full text. #error "Must have #include \"config.h\" line at the top of the file that includes these XUtils helper functions" #endif +#include #include #include // IWYU pragma: keep #include @@ -152,4 +153,20 @@ unsigned int countTrailingZeros(unsigned int x); /* IEC unit prefixes */ static const char unitPrefixes[] = { 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 'R', 'Q' }; +static inline bool skipEndOfLine(FILE* fp) { + char buffer[1024]; + while (fgets(buffer, sizeof(buffer), fp)) { + if (strchr(buffer, '\n')) { + return true; + } + } + return false; +} + +static inline int xDirfd(DIR* dirp) { + int r = dirfd(dirp); + assert(r >= 0); + return r; +} + #endif diff --git a/linux/LinuxMachine.c b/linux/LinuxMachine.c index c636be15f..f219cd61c 100644 --- a/linux/LinuxMachine.c +++ b/linux/LinuxMachine.c @@ -78,7 +78,7 @@ static void LinuxMachine_updateCPUcount(LinuxMachine* this) { continue; #ifdef HAVE_OPENAT - int cpuDirFd = openat(dirfd(dir), entry->d_name, O_DIRECTORY | O_PATH | O_NOFOLLOW); + int cpuDirFd = openat(xDirfd(dir), entry->d_name, O_DIRECTORY | O_PATH | O_NOFOLLOW); if (cpuDirFd < 0) continue; #else @@ -497,11 +497,13 @@ static void LinuxMachine_scanCPUTime(LinuxMachine* this) { this->period = (double)this->cpuData[0].totalPeriod / super->activeCPUs; - char buffer[PROC_LINE_LENGTH + 1]; - while (fgets(buffer, sizeof(buffer), file)) { - if (String_startsWith(buffer, "procs_running")) { - this->runningTasks = strtoul(buffer + strlen("procs_running"), NULL, 10); - break; + if (!ferror(file) && !feof(file)) { + char buffer[PROC_LINE_LENGTH + 1]; + while (fgets(buffer, sizeof(buffer), file)) { + if (String_startsWith(buffer, "procs_running")) { + this->runningTasks = (unsigned int) strtoul(buffer + strlen("procs_running"), NULL, 10); + break; + } } } diff --git a/linux/LinuxProcessTable.c b/linux/LinuxProcessTable.c index 904385f9a..b1705904b 100644 --- a/linux/LinuxProcessTable.c +++ b/linux/LinuxProcessTable.c @@ -795,12 +795,11 @@ static bool LinuxProcessTable_readSmapsFile(LinuxProcess* process, openat_arg_t while (fgets(buffer, sizeof(buffer), fp)) { if (!strchr(buffer, '\n')) { // Partial line, skip to end of this line - while (fgets(buffer, sizeof(buffer), fp)) { - if (strchr(buffer, '\n')) { - break; - } + if (!skipEndOfLine(fp)) { + fclose(fp); + return false; } - continue; + } if (String_startsWith(buffer, "Pss:")) { @@ -840,12 +839,9 @@ static void LinuxProcessTable_readOpenVZData(LinuxProcess* process, openat_arg_t while (fgets(linebuf, sizeof(linebuf), file) != NULL) { if (strchr(linebuf, '\n') == NULL) { // Partial line, skip to end of this line - while (fgets(linebuf, sizeof(linebuf), file) != NULL) { - if (strchr(linebuf, '\n') != NULL) { - break; - } + if (!skipEndOfLine(file)) { + break; } - continue; } char* name_value_sep = strchr(linebuf, ':'); diff --git a/linux/Platform.c b/linux/Platform.c index 3316d1dba..c59be6840 100644 --- a/linux/Platform.c +++ b/linux/Platform.c @@ -464,7 +464,7 @@ char* Platform_getProcessEnv(pid_t pid) { size += bytes; capacity += 4096; env = xRealloc(env, capacity); - } while ((bytes = fread(env + size, 1, capacity - size, fp)) > 0); + } while (!ferror(fp) && !feof(fp) && (bytes = fread(env + size, 1, capacity - size, fp)) > 0); fclose(fp); @@ -580,7 +580,7 @@ void Platform_getPressureStall(const char* file, bool some, double* ten, double* return; } int total = fscanf(fp, "some avg10=%32lf avg60=%32lf avg300=%32lf total=%*f ", ten, sixty, threehundred); - if (!some) { + if (total != EOF && !some) { total = fscanf(fp, "full avg10=%32lf avg60=%32lf avg300=%32lf total=%*f ", ten, sixty, threehundred); } (void) total; @@ -785,7 +785,7 @@ static void Platform_Battery_getSysData(double* percent, ACPresence* isOnAC) { const char* entryName = dirEntry->d_name; #ifdef HAVE_OPENAT - int entryFd = openat(dirfd(dir), entryName, O_DIRECTORY | O_PATH); + int entryFd = openat(xDirfd(dir), entryName, O_DIRECTORY | O_PATH); if (entryFd < 0) continue; #else