diff --git a/gui/ollie9pclient.cpp b/gui/ollie9pclient.cpp index 73ce6ab..46e143c 100644 --- a/gui/ollie9pclient.cpp +++ b/gui/ollie9pclient.cpp @@ -437,13 +437,19 @@ void Ollie9pClient::ensureRootDataLoaded() void Ollie9pClient::startChatStream() { - if (m_chatProc) return; - if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return; - m_chatProc = new QProcess(this); - connect(m_chatProc, &QProcess::readyReadStandardOutput, this, &Ollie9pClient::onChatReadyRead); - connect(m_chatProc, QOverload::of(&QProcess::finished), - this, &Ollie9pClient::onChatFinished); - m_chatProc->start(ninepBin(), {"-a", serverAddr(), "read", agentPath() + "/chat"}); + if (m_chatProc) return; + if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return; + + // Verify the agent directory exists before opening a blocking read + QString ap = agentPath(); + QByteArray verify = run9p({"stat", ap}); + if (verify.isEmpty()) return; // directory gone + + m_chatProc = new QProcess(this); + connect(m_chatProc, &QProcess::readyReadStandardOutput, this, &Ollie9pClient::onChatReadyRead); + connect(m_chatProc, QOverload::of(&QProcess::finished), + this, &Ollie9pClient::onChatFinished); + m_chatProc->start(ninepBin(), {"-a", serverAddr(), "read", ap + "/chat"}); } void Ollie9pClient::startStateStream() @@ -453,6 +459,16 @@ void Ollie9pClient::startStateStream() // Check if session still exists before starting if (m_activeSessionId.isEmpty() || m_agentId.isEmpty()) return; + // Verify the agent directory still exists before opening a blocking read + QString ap = agentPath(); + QByteArray verify = run9p({"stat", ap}); + if (verify.isEmpty()) { + // Directory gone — don't start spamming + m_agentId.clear(); + emit activeAgentIdChanged(); + return; + } + // Verify the current agent directory still exists QStringList agents = getAgents(m_activeSessionId); if (agents.isEmpty()) { @@ -465,11 +481,11 @@ void Ollie9pClient::startStateStream() emit activeAgentIdChanged(); } - m_stateProc = new QProcess(this); - connect(m_stateProc, &QProcess::readyReadStandardOutput, this, &Ollie9pClient::onStateReadyRead); - connect(m_stateProc, QOverload::of(&QProcess::finished), - this, &Ollie9pClient::onStateFinished); - m_stateProc->start(ninepBin(), {"-a", serverAddr(), "read", agentPath() + "/statewait"}); + m_stateProc = new QProcess(this); + connect(m_stateProc, &QProcess::readyReadStandardOutput, this, &Ollie9pClient::onStateReadyRead); + connect(m_stateProc, QOverload::of(&QProcess::finished), + this, &Ollie9pClient::onStateFinished); + m_stateProc->start(ninepBin(), {"-a", serverAddr(), "read", ap + "/statewait"}); } void Ollie9pClient::stopStreams() @@ -529,8 +545,9 @@ void Ollie9pClient::onStateFinished(int, QProcess::ExitStatus) { m_stateProc->deleteLater(); m_stateProc = nullptr; - // Do NOT restart — statewait is only started when the user - // explicitly selects an agent via setActiveSessionId or switchAgent. + // Restart to pick up the next state change — statewait is a blocking + // read that returns once and closes the FD. + startStateStream(); } void Ollie9pClient::startEventStream()