From 05e0529013fbd17968ddbe13263d2059b2acc07a Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Tue, 19 Nov 2024 16:08:03 +0100 Subject: [PATCH] Terminal: Fix flushing after process has finished Fixes: QTCREATORBUG-30733 Change-Id: I4b6274d15efbd1b2e6c8ea4960683a4f6bc8952e Reviewed-by: Marcus Tillmanns --- src/libs/3rdparty/libptyqt/conptyprocess.cpp | 77 ++++++++++---------- src/libs/utils/qtcprocess.cpp | 11 ++- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/libs/3rdparty/libptyqt/conptyprocess.cpp b/src/libs/3rdparty/libptyqt/conptyprocess.cpp index c957e0bdd9e..d8f0608ef16 100644 --- a/src/libs/3rdparty/libptyqt/conptyprocess.cpp +++ b/src/libs/3rdparty/libptyqt/conptyprocess.cpp @@ -988,8 +988,11 @@ bool ConPtyProcess::startProcess(const QString &executable, GetExitCodeProcess(hEvent, &exitCode); m_exitCode = exitCode; // Do not respawn if the object is about to be destructed - if (!m_aboutToDestruct) - emit notifier()->aboutToClose(); + if (!m_aboutToDestruct) { + ConptyClosePseudoConsole(m_ptyHandler); + m_ptyHandler = INVALID_HANDLE_VALUE; + emit notifier() -> aboutToClose(); + } m_shellCloseWaitNotifier->setEnabled(false); }, Qt::QueuedConnection); @@ -1028,7 +1031,7 @@ bool ConPtyProcess::startProcess(const QString &executable, bool ConPtyProcess::resize(qint16 cols, qint16 rows) { - if (m_ptyHandler == nullptr) + if (m_ptyHandler == INVALID_HANDLE_VALUE) { return false; } @@ -1047,49 +1050,45 @@ bool ConPtyProcess::resize(qint16 cols, qint16 rows) bool ConPtyProcess::kill() { - bool exitCode = false; - if (m_ptyHandler != INVALID_HANDLE_VALUE) { m_aboutToDestruct = true; // Close ConPTY - this will terminate client process if running WindowsContext::instance().closePseudoConsole(m_ptyHandler); - - // Clean-up the pipes - if (INVALID_HANDLE_VALUE != m_hPipeOut) - CloseHandle(m_hPipeOut); - if (INVALID_HANDLE_VALUE != m_hPipeIn) - CloseHandle(m_hPipeIn); - - if (m_readThread) { - m_readThread->requestInterruption(); - if (!m_readThread->wait(1000)) - m_readThread->terminate(); - m_readThread->deleteLater(); - m_readThread = nullptr; - } - - delete m_shellCloseWaitNotifier; - m_shellCloseWaitNotifier = nullptr; - - m_pid = 0; - m_ptyHandler = INVALID_HANDLE_VALUE; - m_hPipeIn = INVALID_HANDLE_VALUE; - m_hPipeOut = INVALID_HANDLE_VALUE; - - CloseHandle(m_shellProcessInformation.hThread); - CloseHandle(m_shellProcessInformation.hProcess); - - // Cleanup attribute list - if (m_shellStartupInfo.lpAttributeList) { - DeleteProcThreadAttributeList(m_shellStartupInfo.lpAttributeList); - HeapFree(GetProcessHeap(), 0, m_shellStartupInfo.lpAttributeList); - } - - exitCode = true; } - return exitCode; + // Clean-up the pipes + if (INVALID_HANDLE_VALUE != m_hPipeOut) + CloseHandle(m_hPipeOut); + if (INVALID_HANDLE_VALUE != m_hPipeIn) + CloseHandle(m_hPipeIn); + + if (m_readThread) { + m_readThread->requestInterruption(); + if (!m_readThread->wait(1000)) + m_readThread->terminate(); + m_readThread->deleteLater(); + m_readThread = nullptr; + } + + delete m_shellCloseWaitNotifier; + m_shellCloseWaitNotifier = nullptr; + + m_pid = 0; + m_ptyHandler = INVALID_HANDLE_VALUE; + m_hPipeIn = INVALID_HANDLE_VALUE; + m_hPipeOut = INVALID_HANDLE_VALUE; + + CloseHandle(m_shellProcessInformation.hThread); + CloseHandle(m_shellProcessInformation.hProcess); + + // Cleanup attribute list + if (m_shellStartupInfo.lpAttributeList) { + DeleteProcThreadAttributeList(m_shellStartupInfo.lpAttributeList); + HeapFree(GetProcessHeap(), 0, m_shellStartupInfo.lpAttributeList); + } + + return true; } IPtyProcess::PtyType ConPtyProcess::type() diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index fcd5a465bdb..9016f580ba3 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -435,13 +435,22 @@ public: static_cast(m_inputFlags.toInt())); } - emit readyRead(m_ptyProcess->readAll(), {}); + const QByteArray data = m_ptyProcess->readAll(); + if (!data.isEmpty()) + emit readyRead(data, {}); }); connect(m_ptyProcess->notifier(), &QIODevice::aboutToClose, this, [this] { if (m_ptyProcess) { const ProcessResultData result = {m_ptyProcess->exitCode(), QProcess::NormalExit, QProcess::UnknownError, {}}; + + const QByteArray restOfOutput = m_ptyProcess->readAll(); + if (!restOfOutput.isEmpty()) { + emit readyRead(restOfOutput, {}); + m_ptyProcess->notifier()->disconnect(); + } + emit done(result); return; }