File indexing completed on 2024-05-12 17:10:12

0001 /*
0002     ksmserver - the KDE session management server
0003 
0004     SPDX-FileCopyrightText: 2016 Martin Graesslin <mgraesslin@kde.org>
0005 
0006     SPDX-License-Identifier: MIT
0007 */
0008 #include <QCommandLineParser>
0009 #include <QCoreApplication>
0010 #include <QDebug>
0011 #include <QFile>
0012 #include <QFutureWatcher>
0013 #include <QProcess>
0014 #include <QtConcurrentRun>
0015 
0016 #include <unistd.h>
0017 
0018 #include <config.h>
0019 
0020 static void readFromPipe(int pipe)
0021 {
0022     QFile readPipe;
0023     if (!readPipe.open(pipe, QIODevice::ReadOnly)) {
0024         QCoreApplication::exit(1);
0025         return;
0026     }
0027     QByteArray result = readPipe.readLine();
0028     qDebug() << "!!!! Result from helper process: " << result;
0029     if (result.isEmpty()) {
0030         qDebug() << "!!!! Error";
0031         QCoreApplication::exit(1);
0032     }
0033 }
0034 
0035 int main(int argc, char *argv[])
0036 {
0037     QCoreApplication app(argc, argv);
0038 
0039     QCommandLineParser parser;
0040     parser.addHelpOption();
0041 
0042     QCommandLineOption shutdownAllowedOption(QStringLiteral("shutdown-allowed"), QStringLiteral("Whether the user is allowed to shut down the system."));
0043     parser.addOption(shutdownAllowedOption);
0044 
0045     QCommandLineOption chooseOption(QStringLiteral("choose"), QStringLiteral("Whether the user is offered the choices between logout, shutdown, etc."));
0046     parser.addOption(chooseOption);
0047 
0048     QCommandLineOption modeOption(QStringLiteral("mode"),
0049                                   QStringLiteral("The initial exit mode to offer to the user."),
0050                                   QStringLiteral("logout|shutdown|reboot"),
0051                                   QStringLiteral("logout"));
0052     parser.addOption(modeOption);
0053 
0054     parser.process(app);
0055 
0056     int pipeFds[2];
0057     if (pipe(pipeFds) != 0) {
0058         return 1;
0059     }
0060 
0061     QProcess p;
0062     p.setProgram(QStringLiteral(LOGOUT_GREETER_BIN));
0063     QStringList arguments;
0064     if (parser.isSet(shutdownAllowedOption)) {
0065         arguments << QStringLiteral("--shutdown-allowed");
0066     }
0067     if (parser.isSet(chooseOption)) {
0068         arguments << QStringLiteral("--choose");
0069     }
0070     if (parser.isSet(modeOption)) {
0071         arguments << QStringLiteral("--mode");
0072         arguments << parser.value(modeOption);
0073     }
0074     arguments << QStringLiteral("--mode-fd");
0075     arguments << QString::number(pipeFds[1]);
0076     p.setArguments(arguments);
0077 
0078     QObject::connect(&p, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::errorOccurred), &app, [] {
0079         QCoreApplication::exit(1);
0080     });
0081 
0082     const int resultPipe = pipeFds[0];
0083     QObject::connect(&p, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), &app, [resultPipe](int exitCode) {
0084         if (exitCode != 0) {
0085             qDebug() << "!!!! finished with exit code: " << exitCode;
0086             close(resultPipe);
0087             QCoreApplication::exit(1);
0088             return;
0089         }
0090         QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
0091         QObject::connect(watcher, &QFutureWatcher<void>::finished, QCoreApplication::instance(), &QCoreApplication::quit, Qt::QueuedConnection);
0092         QObject::connect(watcher, &QFutureWatcher<void>::finished, watcher, &QFutureWatcher<void>::deleteLater, Qt::QueuedConnection);
0093         watcher->setFuture(QtConcurrent::run(readFromPipe, resultPipe));
0094     });
0095 
0096     p.start();
0097     close(pipeFds[1]);
0098 
0099     return app.exec();
0100 }