From 3d0f3cca048ba18e02186db0b68e6dfe8dfb6f56 Mon Sep 17 00:00:00 2001 From: Jon Scheiding Date: Fri, 8 May 2026 16:35:50 -0400 Subject: [PATCH] Add StreamLog::isOpen() to detect closed stdin pipe Exposes a non-blocking check for whether the stdin pipe is still connected, so callers can distinguish a stream that's transiently empty from one whose peer has closed the pipe. POSIX uses poll(POLLIN) and treats POLLHUP/POLLERR/POLLNVAL as closed; Windows uses PeekNamedPipe (matching getNextLine). isFinished() is intentionally left unchanged. --- seeklog.cpp | 31 +++++++++++++++++++++++++++++++ seeklog.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/seeklog.cpp b/seeklog.cpp index 4dad928..6bae889 100644 --- a/seeklog.cpp +++ b/seeklog.cpp @@ -32,6 +32,10 @@ #include #endif +#ifndef _WIN32 +#include +#endif + long long gSeekLogMaxBufferSize = 104857600; //StreamLog @@ -95,6 +99,33 @@ bool StreamLog::isFinished() { return false; } +bool StreamLog::isOpen() { + if(fcntl_fail) return false; + +#ifdef _WIN32 + DWORD available_bytes; + if(!PeekNamedPipe(stdin_handle, 0, 0, 0, &available_bytes, 0)) { + return false; + } + return true; +#else + struct pollfd pfd; + pfd.fd = STDIN_FILENO; + pfd.events = POLLIN; + + int ret = poll(&pfd, 1, 0); + + if(ret < 0) return false; + if(ret == 0) return true; + + if(pfd.revents & (POLLHUP | POLLERR | POLLNVAL)) { + return false; + } + + return true; +#endif +} + // SeekLog SeekLog::SeekLog(std::string logfile) { diff --git a/seeklog.h b/seeklog.h index 19abe6e..5df09b1 100644 --- a/seeklog.h +++ b/seeklog.h @@ -44,6 +44,7 @@ class BaseLog { virtual ~BaseLog() {}; virtual bool getNextLine(std::string& line) { return false; }; virtual bool isFinished() { return false; }; + virtual bool isOpen() { return !isFinished(); }; }; class StreamLog : public BaseLog { @@ -58,6 +59,7 @@ class StreamLog : public BaseLog { bool getNextLine(std::string& line); bool isFinished(); + bool isOpen(); }; class SeekLogException : public std::exception {