2020-09-19 09:47:02 +02:00
|
|
|
/*****************************************************************************
|
|
|
|
* smsub Server Manager Subprocess
|
|
|
|
* Copyright (C) 2020 Syping
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without modification,
|
|
|
|
* are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
|
|
* this list of conditions and the following disclaimer in the documentation
|
|
|
|
* and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* This software is provided as-is, no warranties are given to you, we are not
|
|
|
|
* responsible for anything with use of the software, you are self responsible.
|
|
|
|
*****************************************************************************/
|
|
|
|
|
|
|
|
#include <QCoreApplication>
|
|
|
|
#include <QTextStream>
|
|
|
|
#include "SMSubProcess.h"
|
|
|
|
#include "smsub.h"
|
2020-10-14 23:14:33 +02:00
|
|
|
#include <QDebug>
|
2020-09-19 09:47:02 +02:00
|
|
|
|
|
|
|
SMSubProcess::SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int &termTimeout) :
|
|
|
|
termTimeout(termTimeout)
|
|
|
|
{
|
|
|
|
// Set process executable, arguments and working directory
|
|
|
|
process.setProgram(executable);
|
|
|
|
process.setArguments(arguments);
|
|
|
|
process.setWorkingDirectory(workingDirectory);
|
|
|
|
|
|
|
|
// stdout and stderr in same IO stream
|
|
|
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
|
|
|
|
|
|
|
// Connect process signal handlers
|
|
|
|
QObject::connect(&process, &QProcess::readyRead, this, &SMSubProcess::readyRead);
|
|
|
|
QObject::connect(&process, &QProcess::errorOccurred, this, &SMSubProcess::processError);
|
2020-10-14 23:14:33 +02:00
|
|
|
QObject::connect(&process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), [=](int exitCode) {
|
|
|
|
// Exit with the same exit code as the process
|
|
|
|
emit processStopped();
|
|
|
|
QCoreApplication::exit(exitCode);
|
|
|
|
});
|
2020-09-19 09:47:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::start()
|
|
|
|
{
|
|
|
|
process.start(QIODevice::ReadWrite);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::readyRead()
|
|
|
|
{
|
|
|
|
// Read process output and emit event
|
|
|
|
while (process.canReadLine()) {
|
|
|
|
const QByteArray readData = process.readLine().trimmed();
|
|
|
|
emit outputWritten(readData + '\n');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::processError(QProcess::ProcessError error)
|
|
|
|
{
|
|
|
|
// Handle process errors
|
|
|
|
if (likely(error == QProcess::FailedToStart)) {
|
2020-10-14 23:14:33 +02:00
|
|
|
QTextStream(stderr) << "Process failed to start!" << smsub_endl;
|
2020-09-19 09:47:02 +02:00
|
|
|
QCoreApplication::exit(1);
|
|
|
|
}
|
|
|
|
else if (error == QProcess::UnknownError) {
|
2020-10-14 23:14:33 +02:00
|
|
|
QTextStream(stderr) << "Unknown error occurred!" << smsub_endl;
|
2020-09-19 09:47:02 +02:00
|
|
|
QCoreApplication::exit(1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::aboutToQuit()
|
|
|
|
{
|
|
|
|
// Main process terminated, terminate subprocess with set timeout
|
|
|
|
if (process.state() == QProcess::Running) {
|
|
|
|
process.terminate();
|
|
|
|
if (!process.waitForFinished(termTimeout)) {
|
2020-10-14 23:14:33 +02:00
|
|
|
QTextStream(stderr) << "Failed to terminate process!" << smsub_endl;
|
2020-09-19 09:47:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::killProcess()
|
|
|
|
{
|
|
|
|
// Kill process as requested
|
|
|
|
if (process.state() == QProcess::Running) {
|
|
|
|
process.kill();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::stopProcess()
|
|
|
|
{
|
|
|
|
// Terminate process as requested
|
|
|
|
if (process.state() == QProcess::Running) {
|
|
|
|
process.terminate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SMSubProcess::writeInput(const QByteArray &input)
|
|
|
|
{
|
|
|
|
// Write input from Unix/IPC socket to process
|
|
|
|
process.write(input);
|
|
|
|
}
|