diff options
Diffstat (limited to 'src/input/killX11Handler.cpp')
| -rw-r--r-- | src/input/killX11Handler.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/input/killX11Handler.cpp b/src/input/killX11Handler.cpp new file mode 100644 index 0000000..7ac75a1 --- /dev/null +++ b/src/input/killX11Handler.cpp @@ -0,0 +1,89 @@ +/* + # Copyright (c) 2009 - OpenSLX Project, Computer Center University of Freiburg + # + # This program is free software distributed under the GPL version 2. + # See http://openslx.org/COPYING + # + # If you have any feedback please consult http://openslx.org/feedback and + # send your suggestions, praise, or complaints to feedback@openslx.org + # + # General information about OpenSLX can be found at http://openslx.org/ + # -------------------------------------------------------------------------- + # killX11Handler.h + # - Kill the X11 Server - implementation + # -------------------------------------------------------------------------- + */ + +#include <sys/types.h> +#include <signal.h> +#include <cerrno> +#include <QDir> +#include <QFileInfo> +#include <QStringList> +#include "pvsCheckPrivileges.h" +#include "killX11Handler.h" + +using namespace std; + +void KillX11Handler::handle(InputEvent const&, InputEventContext const* ctx) +{ + // Find out which display device is used: + QString displayDevice = PVSCheckPrivileges::instance()->getX11DisplayDevice(ctx); + QString displayDeviceAbs = QFileInfo(displayDevice).canonicalFilePath(); + + if(displayDevice.isNull()) + { + qWarning("Can not kill X server for %d,%d,%d: No Display Device", ctx->getSenderPid(), ctx->getSenderUid(), ctx->getSenderGid()); + return; + } + + QList<pid_t> pids; + + // Find all processes that have it opened: + QDir proc("/proc"); + QFileInfoList entries = proc.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot); + foreach(QFileInfo fi, entries) + { + // We are only interested in numerical ids: + bool ok; + pid_t pid = fi.fileName().toUInt(&ok); + if(!ok) + continue; + + // We have a pid. Now check open files: + QDir fds(QString("/proc/%1/fd").arg(pid)); + qDebug("Searching for X server in %s", fds.absolutePath().toLocal8Bit().constData()); + QFileInfoList fdfiles = fds.entryInfoList(QDir::Files); + foreach(QFileInfo fdfile, fdfiles) + { + qDebug(" Looking for terminal in %s", fdfile.absoluteFilePath().toLocal8Bit().constData()); + QFileInfo fdTarget(fdfile.readLink()); + if(fdTarget.canonicalFilePath() == displayDeviceAbs) + { + qDebug(" ... found"); + pids << pid; + } + } + } + + // If everything is well, we have exactly one pid: + if(pids.size() != 1) + { + QStringList pidStrs; + foreach(pid_t pid, pids) + { + pidStrs << QString::number(pid); + } + + qWarning("Display device %s is open by multiple or zero processes (%s). We don't know which is X. Aborting.", + displayDeviceAbs.toLocal8Bit().constData(), + pidStrs.join(", ").toLocal8Bit().constData()); + return; + } + + // We found the PID for the X server. Now kill it. + QString exe = QFileInfo(QString("/proc/%1/exe").arg(pids[0])).readLink(); + qDebug("Killing X server, PID %d, exe name %s with SIGTERM", pids[0], exe.toLocal8Bit().constData()); + +// kill(pids[0], SIGTERM); +} |
