diff options
| author | Vaxry <vaxry@vaxry.net> | 2026-02-28 15:06:10 +0000 |
|---|---|---|
| committer | Vaxry <vaxry@vaxry.net> | 2026-02-28 15:06:10 +0000 |
| commit | 362ea7b0f3bb858996198a8d760acbd3397dea22 (patch) | |
| tree | d55c8f2ab7d368c3379a95b042e1fb0a81f5c961 /src/debug | |
| parent | f7114016c6dbf524763038642521892b473f4d36 (diff) | |
hyprctl: fix buffer overflowing writes to the socket
Diffstat (limited to 'src/debug')
| -rw-r--r-- | src/debug/HyprCtl.cpp | 36 |
1 files changed, 29 insertions, 7 deletions
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index f3a9402d..1fcb3dd1 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -2210,16 +2210,38 @@ std::string CHyprCtl::makeDynamicCall(const std::string& input) { } static bool successWrite(int fd, const std::string& data, bool needLog = true) { - if (write(fd, data.c_str(), data.length()) > 0) - return true; + size_t totalWritten = 0; + size_t remaining = data.length(); + size_t waitsDone = 0; + constexpr const size_t MAX_WAITS = 20; // 2000µs = 2ms - if (errno == EAGAIN) - return true; + while (totalWritten < data.length()) { + ssize_t written = write(fd, data.c_str() + totalWritten, remaining); - if (needLog) - Log::logger->log(Log::ERR, "Couldn't write to socket. Error: " + std::string(strerror(errno))); + if (waitsDone > MAX_WAITS) { + Log::logger->log(Log::ERR, "Couldn't write to socket. Buffer was full and the client couldn't read in time."); + return false; + } + + if (written < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + // socket buffer full, wait a bit and retry + std::this_thread::sleep_for(std::chrono::microseconds(100)); + waitsDone++; + continue; + } + if (needLog) + Log::logger->log(Log::ERR, "Couldn't write to socket. Error: {}", strerror(errno)); + return false; + } + + waitsDone = 0; + + totalWritten += written; + remaining -= written; + } - return false; + return true; } static void runWritingDebugLogThread(const int conn) { |
