mirror of
https://github.com/KDE/konsole.git
synced 2025-12-23 23:38:08 -05:00
Fix process info not available in flatpak
Since we are in a sandbox, tcgetpgrp doesn't work. To work around this limitation, get process info using ps BUG: 507763 BUG: 508216
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
|
||||
// KDE
|
||||
#include <KConfigGroup>
|
||||
#include <KSandbox>
|
||||
#include <KSharedConfig>
|
||||
#include <KUser>
|
||||
|
||||
@@ -787,6 +788,84 @@ private:
|
||||
QString LinuxProcessInfo::_createdAppCGroupPath = QString();
|
||||
bool LinuxProcessInfo::_cGroupCreationFailed = false;
|
||||
|
||||
class FlatpakProcessInfo : public ProcessInfo
|
||||
{
|
||||
public:
|
||||
FlatpakProcessInfo(int pid, QByteArrayView tty)
|
||||
: ProcessInfo(pid)
|
||||
{
|
||||
QProcess proc;
|
||||
proc.setProgram(QStringLiteral("ps"));
|
||||
proc.setArguments({
|
||||
QStringLiteral("-o"),
|
||||
QStringLiteral("%U\t%p\t%c"),
|
||||
QStringLiteral("--tty"),
|
||||
QString::fromLatin1(tty.data()),
|
||||
QStringLiteral("--no-headers"),
|
||||
});
|
||||
|
||||
KSandbox::startHostProcess(proc, QProcess::ReadOnly);
|
||||
|
||||
proc.waitForStarted();
|
||||
proc.waitForFinished();
|
||||
|
||||
const QString out = QString::fromUtf8(proc.readAllStandardOutput());
|
||||
for (QStringView line : QStringTokenizer(out, u'\n', Qt::SkipEmptyParts)) {
|
||||
using Container = QVarLengthArray<QStringView, 4>;
|
||||
const Container tokens = QStringTokenizer(line, u'\t', Qt::SkipEmptyParts).toContainer<Container>();
|
||||
if (tokens[1].toInt() == pid) {
|
||||
setUserName(tokens[0].trimmed().toString());
|
||||
setPid(tokens[1].trimmed().toInt());
|
||||
setName(tokens[2].trimmed().toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void readProcessInfo(int) override
|
||||
{
|
||||
/* done in ctor */
|
||||
}
|
||||
|
||||
bool readProcessName(int) override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool readCurrentDir(int) override
|
||||
{
|
||||
bool ok = false;
|
||||
QString pidString = QString::number(pid(&ok));
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QProcess proc;
|
||||
proc.setProgram(QStringLiteral("pwdx"));
|
||||
proc.setArguments({pidString});
|
||||
KSandbox::startHostProcess(proc, QProcess::ReadOnly);
|
||||
if (proc.waitForStarted() && proc.waitForFinished()) {
|
||||
proc.setReadChannel(QProcess::StandardOutput);
|
||||
quint8 buffer[4096];
|
||||
auto line = proc.readLineInto(buffer).trimmed();
|
||||
if (int colon = line.indexOf(": "); colon != -1) {
|
||||
setCurrentDir(QString::fromUtf8(line.mid(colon + 2)));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool readArguments(int) override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void readUserName(void) override
|
||||
{
|
||||
/* done in ctor */
|
||||
}
|
||||
};
|
||||
|
||||
#elif defined(Q_OS_FREEBSD)
|
||||
class FreeBSDProcessInfo : public UnixProcessInfo
|
||||
{
|
||||
@@ -1311,11 +1390,19 @@ private:
|
||||
};
|
||||
#endif
|
||||
|
||||
ProcessInfo *ProcessInfo::newInstance(int pid, int sessionPid)
|
||||
ProcessInfo *ProcessInfo::newInstance(int pid, int sessionPid, QByteArrayView tty)
|
||||
{
|
||||
ProcessInfo *info;
|
||||
#if defined(Q_OS_LINUX)
|
||||
info = new LinuxProcessInfo(pid, sessionPid);
|
||||
if (KSandbox::isFlatpak()) {
|
||||
if (tty.isEmpty()) {
|
||||
info = new NullProcessInfo(pid);
|
||||
} else {
|
||||
info = new FlatpakProcessInfo(pid, tty);
|
||||
}
|
||||
} else {
|
||||
info = new LinuxProcessInfo(pid, sessionPid);
|
||||
}
|
||||
#elif defined(Q_OS_SOLARIS)
|
||||
info = new SolarisProcessInfo(pid);
|
||||
#elif defined(Q_OS_MACOS)
|
||||
|
||||
@@ -68,8 +68,9 @@ public:
|
||||
* @param pid The pid of the process to examine
|
||||
* @param sessionPid -1 if examined process is session process,
|
||||
* else will be pid of session process of the tab housing examined process
|
||||
* @param tty the current tty, used by flatpak
|
||||
*/
|
||||
static ProcessInfo *newInstance(int pid, int sessionPid = -1);
|
||||
static ProcessInfo *newInstance(int pid, int sessionPid = -1, QByteArrayView tty = QByteArrayView());
|
||||
|
||||
virtual ~ProcessInfo()
|
||||
{
|
||||
|
||||
31
src/Pty.cpp
31
src/Pty.cpp
@@ -23,6 +23,7 @@
|
||||
|
||||
// KDE
|
||||
#include <KPtyDevice>
|
||||
#include <KSandbox>
|
||||
|
||||
using Konsole::Pty;
|
||||
|
||||
@@ -303,6 +304,36 @@ void Pty::closePty()
|
||||
|
||||
int Pty::foregroundProcessGroup() const
|
||||
{
|
||||
if (KSandbox::isFlatpak()) {
|
||||
QProcess proc;
|
||||
proc.setProgram(QStringLiteral("ps"));
|
||||
proc.setArguments({QStringLiteral("-o"),
|
||||
QStringLiteral("%p\t"),
|
||||
QStringLiteral("-o"),
|
||||
QStringLiteral("stat"),
|
||||
QStringLiteral("-t"),
|
||||
QStringLiteral("%1").arg(pty()->ttyName()),
|
||||
QStringLiteral("--no-headers")});
|
||||
|
||||
KSandbox::startHostProcess(proc, QProcess::ReadOnly);
|
||||
if (proc.waitForStarted() && proc.waitForFinished()) {
|
||||
while (proc.canReadLine()) {
|
||||
quint8 buffer[256];
|
||||
const QByteArrayView line = proc.readLineInto(buffer);
|
||||
int i = line.indexOf('\t');
|
||||
if (i == -1) {
|
||||
return 0;
|
||||
}
|
||||
QByteArrayView pid = line.mid(0, i);
|
||||
QByteArrayView stat = line.mid(i + 1);
|
||||
if (stat.contains("+")) {
|
||||
return pid.trimmed().toInt();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int master_fd = pty()->masterFd();
|
||||
|
||||
if (master_fd >= 0) {
|
||||
|
||||
@@ -289,7 +289,8 @@ void Session::setInitialWorkingDirectory(const QString &dir)
|
||||
|
||||
QString Session::currentWorkingDirectory()
|
||||
{
|
||||
if (_reportedWorkingUrl.isValid() && _reportedWorkingUrl.isLocalFile() && (_reportedWorkingUrl.host().length() == 0 || _reportedWorkingUrl.host().compare(QSysInfo::machineHostName(), Qt::CaseInsensitive) == 0)) {
|
||||
if (_reportedWorkingUrl.isValid() && _reportedWorkingUrl.isLocalFile()
|
||||
&& (_reportedWorkingUrl.host().length() == 0 || _reportedWorkingUrl.host().compare(QSysInfo::machineHostName(), Qt::CaseInsensitive) == 0)) {
|
||||
return _reportedWorkingUrl.path();
|
||||
}
|
||||
|
||||
@@ -1224,7 +1225,30 @@ void Session::updateSessionProcessInfo()
|
||||
// return 0
|
||||
if ((_sessionProcessInfo == nullptr) || (processId() != 0 && processId() != _sessionProcessInfo->pid(&ok))) {
|
||||
delete _sessionProcessInfo;
|
||||
_sessionProcessInfo = ProcessInfo::newInstance(processId());
|
||||
|
||||
int sessionPid = processId();
|
||||
if (KSandbox::isFlatpak()) {
|
||||
QProcess proc;
|
||||
proc.setProgram(QStringLiteral("ps"));
|
||||
proc.setArguments({QStringLiteral("-o"),
|
||||
QStringLiteral("pid"),
|
||||
QStringLiteral("-t"),
|
||||
QStringLiteral("%1").arg(_shellProcess->pty()->ttyName()),
|
||||
QStringLiteral("--no-headers")});
|
||||
KSandbox::startHostProcess(proc, QProcess::ReadOnly);
|
||||
if (proc.waitForStarted() && proc.waitForFinished()) {
|
||||
proc.setReadChannel(QProcess::StandardOutput);
|
||||
quint8 buffer[256];
|
||||
auto line = proc.readLineInto(buffer).trimmed();
|
||||
bool ok;
|
||||
auto pid = line.toInt(&ok);
|
||||
if (ok) {
|
||||
sessionPid = pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_sessionProcessInfo = ProcessInfo::newInstance(sessionPid, -1, _shellProcess->pty()->ttyName());
|
||||
_sessionProcessInfo->setUserHomeDir();
|
||||
}
|
||||
_sessionProcessInfo->update();
|
||||
@@ -1237,7 +1261,7 @@ bool Session::updateForegroundProcessInfo()
|
||||
const int foregroundPid = _shellProcess->foregroundProcessGroup();
|
||||
if (foregroundPid != _foregroundPid) {
|
||||
delete _foregroundProcessInfo;
|
||||
_foregroundProcessInfo = ProcessInfo::newInstance(foregroundPid, processId());
|
||||
_foregroundProcessInfo = ProcessInfo::newInstance(foregroundPid, processId(), _shellProcess->pty()->ttyName());
|
||||
_foregroundPid = foregroundPid;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user