/* # 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 #include #include #include #include #include #include "pvsCheckPrivileges.h" #include "killX11Handler.h" using namespace std; void KillX11Handler::doHandle(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->senderPid(), ctx->senderUid(), ctx->senderGid()); return; } QList 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); }