From 61d4fc009f59ca80f9193c6d9ea34324ac996c1a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 25 May 2026 04:14:32 +0000 Subject: [PATCH 1/3] fix: call curl_global_cleanup on all early-exit paths in main() Two early returns (LCD open failure and OLED begin failure) executed after a successful curl_global_init but before curl_global_cleanup, violating libcurl's documented API contract. Fix each path: - LCD failure: call curl_global_cleanup() before return - OLED failure: close lcdFd then call curl_global_cleanup() before return Also adds the missing trailing newline at end of file. https://claude.ai/code/session_01K8T7AyJxjWzqrg8PfNxDVi --- src/main.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index eea90f1..53d34d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,6 +18,7 @@ #include #include #include +#include namespace { @@ -100,6 +101,7 @@ int main() { int lcdFd = lcd_open(0x27); if (lcdFd < 0) { LOG_ERROR("Failed to open LCD on I2C bus"); + curl_global_cleanup(); return 1; } lcd_init(lcdFd); @@ -109,6 +111,8 @@ int main() { if (!oled.begin(cfg.oledI2CAddr)) { LOG_ERROR("Failed to open OLED on I2C bus at 0x" << std::hex << cfg.oledI2CAddr << std::dec); + close(lcdFd); + curl_global_cleanup(); return 1; } @@ -210,4 +214,4 @@ int main() { curl_global_cleanup(); return 0; // unreachable -} \ No newline at end of file +} From c62ecbc2aa4c45b5bb6552011e20da8bcf775827 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 25 May 2026 04:14:56 +0000 Subject: [PATCH 2/3] chore: ignore a.out generic compiler output https://claude.ai/code/session_01K8T7AyJxjWzqrg8PfNxDVi --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 7f492c3..ce22424 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,7 @@ test_output/ # Test image dumps (defense in depth) *.pgm -*.ppm \ No newline at end of file +*.ppm + +# Generic compiled output +a.out \ No newline at end of file From e60701a7224748496dc1b2d49cff1f37b13cd38a Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 25 May 2026 13:37:47 +0000 Subject: [PATCH 3/3] fix: use atexit for curl_global_cleanup instead of scattered manual calls curl_global_cleanup() was placed after while(true), making it unreachable dead code, with manual copies only in the two early-return error paths. Register it with std::atexit() immediately after a successful curl_global_init() so cleanup runs on every exit path (early returns, normal exit, exit() from signal handling) without requiring each return site to remember to call it. https://claude.ai/code/session_01Lq2gNbRv9voqav7jsmQMnD --- src/main.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 53d34d8..831fd77 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -74,6 +74,7 @@ int main() { LOG_ERROR("curl_global_init failed"); return 1; } + std::atexit(curl_global_cleanup); // ---- Load configuration ---- Config cfg; @@ -101,7 +102,6 @@ int main() { int lcdFd = lcd_open(0x27); if (lcdFd < 0) { LOG_ERROR("Failed to open LCD on I2C bus"); - curl_global_cleanup(); return 1; } lcd_init(lcdFd); @@ -112,7 +112,6 @@ int main() { LOG_ERROR("Failed to open OLED on I2C bus at 0x" << std::hex << cfg.oledI2CAddr << std::dec); close(lcdFd); - curl_global_cleanup(); return 1; } @@ -212,6 +211,5 @@ int main() { } } - curl_global_cleanup(); return 0; // unreachable }