diff --git a/kde/gui/plumber.cpp b/kde/gui/plumber.cpp index 371f96c..a582368 100644 --- a/kde/gui/plumber.cpp +++ b/kde/gui/plumber.cpp @@ -12,6 +12,8 @@ #include #include +#include +#include // Canonicalise the X11 display the way plan9 getns() does: "xxx:0.0" -> "xxx:0" // and '/' -> '_'. Only the trailing ".0" is stripped. @@ -87,46 +89,85 @@ Q_SIGNALS: protected: void run() override { - NineP nine; - if (!nine.connectAndAttach(m_socketPath, currentUser())) { - Q_EMIT failed(QStringLiteral("plumb connect: %1").arg(nine.errorString())); - return; - } - static constexpr uint32_t PortFid = 1; - if (!nine.walk(PortFid, m_portName) || !nine.open(PortFid, NineP::OREAD)) { - Q_EMIT failed(QStringLiteral("plumb open %1: %2").arg(m_portName, nine.errorString())); - return; - } - static constexpr int PollMs = 200; - bool pending = false; + static constexpr int ReconnectMs = 2000; + + // Log to file for debugging + FILE *logf = fopen("/tmp/ollie-plumber.log", "a"); + auto log = [logf](const char *fmt, ...) { + if (!logf) return; + va_list ap; + va_start(ap, fmt); + vfprintf(logf, fmt, ap); + fprintf(logf, "\n"); + fflush(logf); + va_end(ap); + }; + + log("PlumbReader starting for port %s on %s", qPrintable(m_portName), qPrintable(m_socketPath)); + while (!m_stop.loadRelaxed()) { - if (!pending) { - if (!nine.beginRead(PortFid, 0, nine.msize())) { - Q_EMIT failed(QStringLiteral("plumb read: %1").arg(nine.errorString())); - break; + NineP nine; + log("Connecting to %s...", qPrintable(m_socketPath)); + if (!nine.connectAndAttach(m_socketPath, currentUser())) { + log("Connect failed: %s", qPrintable(nine.errorString())); + QThread::msleep(ReconnectMs); + continue; + } + log("Connected, walking to %s...", qPrintable(m_portName)); + static constexpr uint32_t PortFid = 1; + if (!nine.walk(PortFid, m_portName)) { + log("Walk failed: %s", qPrintable(nine.errorString())); + QThread::msleep(ReconnectMs); + continue; + } + log("Opening %s for read...", qPrintable(m_portName)); + if (!nine.open(PortFid, NineP::OREAD)) { + log("Open failed: %s", qPrintable(nine.errorString())); + QThread::msleep(ReconnectMs); + continue; + } + + log("Port %s connected and open!", qPrintable(m_portName)); + + bool pending = false; + while (!m_stop.loadRelaxed()) { + if (!pending) { + if (!nine.beginRead(PortFid, 0, nine.msize())) { + log("beginRead failed: %s", qPrintable(nine.errorString())); + break; // reconnect + } + pending = true; + } + QByteArray buf; + bool timedOut = false; + const int n = nine.recvReadReply(&buf, PollMs, &timedOut); + if (timedOut) + continue; + if (n < 0) { + log("Read error: %s", qPrintable(nine.errorString())); + break; // reconnect + } + pending = false; + if (n == 0) + continue; + log("Received message: %d bytes", buf.size()); + PlumbMsg m; + if (PlumbMsg::unpack(buf, &m)) { + log("Emitting message: %s", m.data.constData()); + Q_EMIT message(QString::fromUtf8(m.data), m.lookup(QStringLiteral("addr")), + m.wdir); } - pending = true; } - QByteArray buf; - bool timedOut = false; - const int n = nine.recvReadReply(&buf, PollMs, &timedOut); - if (timedOut) - continue; - if (n < 0) { - if (!m_stop.loadRelaxed()) - Q_EMIT failed(QStringLiteral("plumb read: %1").arg(nine.errorString())); - break; - } - pending = false; - if (n == 0) - continue; - PlumbMsg m; - if (PlumbMsg::unpack(buf, &m)) { - Q_EMIT message(QString::fromUtf8(m.data), m.lookup(QStringLiteral("addr")), - m.wdir); + + // Connection lost, wait before reconnecting + if (!m_stop.loadRelaxed()) { + log("Disconnected, reconnecting in %dms...", ReconnectMs); + QThread::msleep(ReconnectMs); } } + log("PlumbReader exiting"); + if (logf) fclose(logf); } private: