add BufferedReads, add AutoStart and KeepAlive command line options
This commit is contained in:
parent
d37369ad4f
commit
1ddc4ff755
5 changed files with 78 additions and 41 deletions
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.5)
|
cmake_minimum_required(VERSION 3.5)
|
||||||
|
|
||||||
project(smsub LANGUAGES CXX VERSION 0.8)
|
project(smsub LANGUAGES CXX VERSION 0.9)
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
#include "SMSubProcess.h"
|
#include "SMSubProcess.h"
|
||||||
#include "smsub.h"
|
#include "smsub.h"
|
||||||
|
|
||||||
SMSubProcess::SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int &termTimeout, const bool &keepAlive) :
|
SMSubProcess::SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int termTimeout, const bool buffReads, const bool keepAlive) :
|
||||||
termTimeout(termTimeout), keepAlive(keepAlive)
|
termTimeout(termTimeout), buffReads(buffReads), keepAlive(keepAlive)
|
||||||
{
|
{
|
||||||
// Set process executable, arguments and working directory
|
// Set process executable, arguments and working directory
|
||||||
process.setProgram(executable);
|
process.setProgram(executable);
|
||||||
|
@ -33,7 +33,7 @@ SMSubProcess::SMSubProcess(const QString &executable, const QStringList &argumen
|
||||||
// manage input channel
|
// manage input channel
|
||||||
process.setInputChannelMode(QProcess::ManagedInputChannel);
|
process.setInputChannelMode(QProcess::ManagedInputChannel);
|
||||||
|
|
||||||
// stdout and stderr in same IO stream
|
// stdout and stderr in same I/O stream
|
||||||
process.setProcessChannelMode(QProcess::MergedChannels);
|
process.setProcessChannelMode(QProcess::MergedChannels);
|
||||||
|
|
||||||
// Connect process signal handlers
|
// Connect process signal handlers
|
||||||
|
@ -58,22 +58,25 @@ void SMSubProcess::readyRead()
|
||||||
QTextStream(stderr) << "Subprocess I/O RR!" << smsub_endl;
|
QTextStream(stderr) << "Subprocess I/O RR!" << smsub_endl;
|
||||||
#endif
|
#endif
|
||||||
// Read process output and emit event
|
// Read process output and emit event
|
||||||
#ifdef SMSUB_BUFFERED_READS
|
if (buffReads) {
|
||||||
|
while (process.bytesAvailable()) {
|
||||||
#ifdef SMSUB_IODEBUG
|
#ifdef SMSUB_IODEBUG
|
||||||
QTextStream(stderr) << "Subprocess I/O W!" << smsub_endl;
|
QTextStream(stderr) << "Subprocess I/O W!" << smsub_endl;
|
||||||
#endif
|
#endif
|
||||||
const QByteArray readData = process.read(1024);
|
const QByteArray readData = process.read(1024);
|
||||||
if (!readData.isEmpty())
|
if (!readData.isEmpty())
|
||||||
emit outputWritten(readData);
|
emit outputWritten(readData);
|
||||||
#else
|
}
|
||||||
while (process.canReadLine()) {
|
|
||||||
#ifdef SMSUB_IODEBUG
|
|
||||||
QTextStream(stderr) << "Subprocess I/O WL!" << smsub_endl;
|
|
||||||
#endif
|
|
||||||
const QByteArray readData = process.readLine().trimmed();
|
|
||||||
emit outputWritten(readData + '\n');
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
while (process.canReadLine()) {
|
||||||
|
#ifdef SMSUB_IODEBUG
|
||||||
|
QTextStream(stderr) << "Subprocess I/O WL!" << smsub_endl;
|
||||||
#endif
|
#endif
|
||||||
|
const QByteArray readData = process.readLine().trimmed();
|
||||||
|
emit outputWritten(readData + '\n');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMSubProcess::processError(QProcess::ProcessError error)
|
void SMSubProcess::processError(QProcess::ProcessError error)
|
||||||
|
|
|
@ -26,11 +26,12 @@ class SMSubProcess : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int &termTimeout = 60000, const bool &keepAlive = false);
|
SMSubProcess(const QString &executable, const QStringList &arguments, const QString &workingDirectory, const int termTimeout = 60000, const bool buffReads = false, const bool keepAlive = false);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QProcess process;
|
QProcess process;
|
||||||
int termTimeout;
|
int termTimeout;
|
||||||
|
bool buffReads;
|
||||||
bool keepAlive;
|
bool keepAlive;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
|
@ -79,7 +79,7 @@ void SMSubServer::newConnection()
|
||||||
QObject::connect(webSocket, &QWebSocket::disconnected, this, &SMSubServer::deleteSocket);
|
QObject::connect(webSocket, &QWebSocket::disconnected, this, &SMSubServer::deleteSocket);
|
||||||
webSocket->sendBinaryMessage(QString("SMSub Version %1\n").arg(QCoreApplication::applicationVersion()).toUtf8());
|
webSocket->sendBinaryMessage(QString("SMSub Version %1\n").arg(QCoreApplication::applicationVersion()).toUtf8());
|
||||||
socket = webSocket;
|
socket = webSocket;
|
||||||
QTextStream(stderr) << QString("WebSocket %1:%2 connected!").arg(webSocket->peerName(), QString::number(webSocket->peerPort())) << smsub_endl;
|
QTextStream(stderr) << QString("WebSocket %1:%2 connected!").arg(webSocket->peerAddress().toString(), QString::number(webSocket->peerPort())) << smsub_endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Just for being sure
|
// Just for being sure
|
||||||
|
@ -101,25 +101,26 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
|
||||||
// Only allow commands being sent if authenticated
|
// Only allow commands being sent if authenticated
|
||||||
const bool isAuthenticated = socket->property("Authenticated").toBool();
|
const bool isAuthenticated = socket->property("Authenticated").toBool();
|
||||||
if (Q_LIKELY(isAuthenticated)) {
|
if (Q_LIKELY(isAuthenticated)) {
|
||||||
if (message.startsWith("+dbg")) {
|
if (message == "+dbg") {
|
||||||
socket->setProperty("ReceiveDbgMsg", true);
|
socket->setProperty("ReceiveDbgMsg", true);
|
||||||
sendMessage(socket, "Debug messages enabled!\n");
|
sendMessage(socket, "Debug messages enabled!\n");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("-dbg")) {
|
else if (message == "-dbg") {
|
||||||
socket->setProperty("ReceiveDbgMsg", false);
|
socket->setProperty("ReceiveDbgMsg", false);
|
||||||
sendMessage(socket, "Debug messages disabled!\n");
|
sendMessage(socket, "Debug messages disabled!\n");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("+log")) {
|
else if (message == "+log") {
|
||||||
socket->setProperty("ReceiveLog", true);
|
socket->setProperty("ReceiveLog", true);
|
||||||
debugOutput(socket, "Log output enabled!");
|
debugOutput(socket, "Log output enabled!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("-log")) {
|
else if (message == "-log") {
|
||||||
socket->setProperty("ReceiveLog", false);
|
socket->setProperty("ReceiveLog", false);
|
||||||
debugOutput(socket, "Log output disabled!");
|
debugOutput(socket, "Log output disabled!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("+reg")) {
|
else if (message == "+reg") {
|
||||||
if (Q_LIKELY(serverSettings->canRegister)) {
|
if (Q_LIKELY(serverSettings->canRegister)) {
|
||||||
QByteArray authUuid = QUuid::createUuid().toByteArray(QUuid::Id128);
|
QByteArray authUuid = QUuid::createUuid().toByteArray(QUuid::Id128) +
|
||||||
|
QUuid::createUuid().toByteArray(QUuid::Id128);
|
||||||
authUuid = QByteArray::fromHex(authUuid).toBase64(QByteArray::OmitTrailingEquals);
|
authUuid = QByteArray::fromHex(authUuid).toBase64(QByteArray::OmitTrailingEquals);
|
||||||
emit tokenRegistered(QString::fromUtf8(authUuid));
|
emit tokenRegistered(QString::fromUtf8(authUuid));
|
||||||
sendMessage(socket, "Token: " + authUuid + '\n');
|
sendMessage(socket, "Token: " + authUuid + '\n');
|
||||||
|
@ -128,7 +129,7 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
|
||||||
sendMessage(socket, "Permission denied!\n");
|
sendMessage(socket, "Permission denied!\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (message.startsWith("status")) {
|
else if (message == "status") {
|
||||||
if (status) {
|
if (status) {
|
||||||
sendMessage(socket, QString("Status: on\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
|
sendMessage(socket, QString("Status: on\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
|
||||||
}
|
}
|
||||||
|
@ -136,31 +137,31 @@ bool SMSubServer::messageReceived(QObject *socket, const QByteArray &message)
|
||||||
sendMessage(socket, QString("Status: off\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
|
sendMessage(socket, QString("Status: off\nLast Start: %1\nLast Stop: %2\n").arg(QString::number(startTime), QString::number(stopTime)).toUtf8());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (message.startsWith("start")) {
|
else if (message == "start") {
|
||||||
emit startRequested();
|
emit startRequested();
|
||||||
debugOutput(socket, "Starting server!");
|
debugOutput(socket, "Starting server!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("stop")) {
|
else if (message == "stop") {
|
||||||
emit stopRequested();
|
emit stopRequested();
|
||||||
debugOutput(socket, "Stopping server!");
|
debugOutput(socket, "Stopping server!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("kill")) {
|
else if (message == "kill") {
|
||||||
emit killRequested();
|
emit killRequested();
|
||||||
debugOutput(socket, "Killing server!");
|
debugOutput(socket, "Killing server!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("quit")) {
|
else if (message == "quit") {
|
||||||
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
QTimer::singleShot(0, qApp, &QCoreApplication::quit);
|
||||||
debugOutput(socket, "Qutting smsub!");
|
debugOutput(socket, "Qutting smsub!");
|
||||||
}
|
}
|
||||||
else if (message.startsWith("wl")) {
|
else if (message.startsWith("wl ")) {
|
||||||
const QByteArray writeData = message.mid(3);
|
const QByteArray writeData = message.mid(3);
|
||||||
emit inputWritten(writeData + '\n');
|
emit inputWritten(writeData + '\n');
|
||||||
debugOutput(socket, "Write line \"" + writeData + "\"!");
|
debugOutput(socket, "Write line: " + writeData);
|
||||||
}
|
}
|
||||||
else if (message.startsWith("w")) {
|
else if (message.startsWith("w ")) {
|
||||||
const QByteArray writeData = message.mid(2);
|
const QByteArray writeData = message.mid(2);
|
||||||
emit inputWritten(writeData);
|
emit inputWritten(writeData);
|
||||||
debugOutput(socket, "Write \"" + writeData + "\"!");
|
debugOutput(socket, "Write: " + writeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
48
main.cpp
48
main.cpp
|
@ -134,7 +134,7 @@ int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
QCoreApplication a(argc, argv);
|
QCoreApplication a(argc, argv);
|
||||||
a.setApplicationName("Server Manager Subprocess");
|
a.setApplicationName("Server Manager Subprocess");
|
||||||
a.setApplicationVersion("0.8");
|
a.setApplicationVersion("0.9");
|
||||||
|
|
||||||
#ifdef Q_OS_UNIX
|
#ifdef Q_OS_UNIX
|
||||||
catchUnixSignals({SIGINT, SIGHUP, SIGQUIT, SIGTERM});
|
catchUnixSignals({SIGINT, SIGHUP, SIGQUIT, SIGTERM});
|
||||||
|
@ -142,9 +142,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
bool rportSet = false;
|
bool rportSet = false;
|
||||||
bool autoStart = true;
|
bool autoStart = true;
|
||||||
|
bool buffReads = false;
|
||||||
bool keepAlive = false;
|
bool keepAlive = false;
|
||||||
bool timeoutSet = false;
|
bool timeoutSet = false;
|
||||||
int termTimeout = 60000;
|
size_t termTimeout = 60000;
|
||||||
quint16 rport;
|
quint16 rport;
|
||||||
QString socket;
|
QString socket;
|
||||||
QString rsocket;
|
QString rsocket;
|
||||||
|
@ -154,6 +155,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
const QByteArray envEnvironmentMode = qgetenv("SMSUB_ENVIRONMENT_MODE");
|
const QByteArray envEnvironmentMode = qgetenv("SMSUB_ENVIRONMENT_MODE");
|
||||||
const QByteArray envAutoStart = qgetenv("SMSUB_AUTOSTART");
|
const QByteArray envAutoStart = qgetenv("SMSUB_AUTOSTART");
|
||||||
|
const QByteArray envBuffReads = qgetenv("SMSUB_BUFFERED_READS");
|
||||||
const QByteArray envKeepAlive = qgetenv("SMSUB_KEEPALIVE");
|
const QByteArray envKeepAlive = qgetenv("SMSUB_KEEPALIVE");
|
||||||
const QByteArray envManifest = qgetenv("SMSUB_JSON");
|
const QByteArray envManifest = qgetenv("SMSUB_JSON");
|
||||||
const QByteArray envExecutable = qgetenv("SMSUB_EXEC");
|
const QByteArray envExecutable = qgetenv("SMSUB_EXEC");
|
||||||
|
@ -212,6 +214,12 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!envBuffReads.isEmpty()) {
|
||||||
|
if (envBuffReads == "1" || envBuffReads.toLower() == "true" || envBuffReads.toLower() == "yes") {
|
||||||
|
buffReads = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!envKeepAlive.isEmpty()) {
|
if (!envKeepAlive.isEmpty()) {
|
||||||
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
|
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
|
||||||
keepAlive = true;
|
keepAlive = true;
|
||||||
|
@ -285,6 +293,12 @@ int main(int argc, char *argv[])
|
||||||
#endif
|
#endif
|
||||||
commandLineParser.addOption(subprocessRemoteSocket);
|
commandLineParser.addOption(subprocessRemoteSocket);
|
||||||
|
|
||||||
|
QCommandLineOption processAutoStart("autostart", "SMSub autostart mode setting.", "autostart");
|
||||||
|
commandLineParser.addOption(processAutoStart);
|
||||||
|
|
||||||
|
QCommandLineOption processKeepAlive("keepalive", "SMSub keepalive mode setting.", "keepalive");
|
||||||
|
commandLineParser.addOption(processKeepAlive);
|
||||||
|
|
||||||
QCommandLineOption processTimeout("timeout", "SMSub termination timeout.", "timeout");
|
QCommandLineOption processTimeout("timeout", "SMSub termination timeout.", "timeout");
|
||||||
commandLineParser.addOption(processTimeout);
|
commandLineParser.addOption(processTimeout);
|
||||||
|
|
||||||
|
@ -302,7 +316,7 @@ int main(int argc, char *argv[])
|
||||||
!envManifest.isEmpty() && !envArguments.isEmpty() ||
|
!envManifest.isEmpty() && !envArguments.isEmpty() ||
|
||||||
commandLineParser.isSet(processManifest) && !envArguments.isEmpty() ||
|
commandLineParser.isSet(processManifest) && !envArguments.isEmpty() ||
|
||||||
!envManifest.isEmpty() && commandLineParser.isSet(processArguments)) {
|
!envManifest.isEmpty() && commandLineParser.isSet(processArguments)) {
|
||||||
QTextStream(stderr) << "You can't define a Process arguments and a JSON process manifest at the same time!" << smsub_endl;
|
QTextStream(stderr) << "You can't define Process arguments and a JSON process manifest at the same time!" << smsub_endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +334,7 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
if (commandLineParser.isSet(processTimeout)) {
|
if (commandLineParser.isSet(processTimeout)) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int _termTimeout = commandLineParser.value(processTimeout).toInt(&ok);
|
const int _termTimeout = commandLineParser.value(processTimeout).toInt(&ok, 10);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
termTimeout = _termTimeout;
|
termTimeout = _termTimeout;
|
||||||
timeoutSet = true;
|
timeoutSet = true;
|
||||||
|
@ -332,7 +346,7 @@ int main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
else if (!envTimeout.isEmpty()) {
|
else if (!envTimeout.isEmpty()) {
|
||||||
bool ok;
|
bool ok;
|
||||||
const int _termTimeout = envTimeout.toInt(&ok);
|
const int _termTimeout = envTimeout.toInt(&ok, 10);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
termTimeout = _termTimeout;
|
termTimeout = _termTimeout;
|
||||||
timeoutSet = true;
|
timeoutSet = true;
|
||||||
|
@ -350,13 +364,31 @@ int main(int argc, char *argv[])
|
||||||
executable = QString::fromUtf8(envExecutable);
|
executable = QString::fromUtf8(envExecutable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!envAutoStart.isEmpty()) {
|
if (commandLineParser.isSet(processAutoStart)) {
|
||||||
|
const QString claAutoStart = commandLineParser.value(processAutoStart);
|
||||||
|
if (claAutoStart == "0" || claAutoStart.toLower() == "false" || claAutoStart.toLower() == "no") {
|
||||||
|
autoStart = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!envAutoStart.isEmpty()) {
|
||||||
if (envAutoStart == "0" || envAutoStart.toLower() == "false" || envAutoStart.toLower() == "no") {
|
if (envAutoStart == "0" || envAutoStart.toLower() == "false" || envAutoStart.toLower() == "no") {
|
||||||
autoStart = false;
|
autoStart = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!envKeepAlive.isEmpty()) {
|
if (!envBuffReads.isEmpty()) {
|
||||||
|
if (envBuffReads == "1" || envBuffReads.toLower() == "true" || envBuffReads.toLower() == "yes") {
|
||||||
|
buffReads = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (commandLineParser.isSet(processKeepAlive)) {
|
||||||
|
const QString claKeepAlive = commandLineParser.value(processKeepAlive);
|
||||||
|
if (claKeepAlive != "0" || claKeepAlive.toLower() != "false" || claKeepAlive.toLower() != "no") {
|
||||||
|
keepAlive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!envKeepAlive.isEmpty()) {
|
||||||
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
|
if (envKeepAlive == "1" || envKeepAlive.toLower() == "true" || envKeepAlive.toLower() == "yes") {
|
||||||
keepAlive = true;
|
keepAlive = true;
|
||||||
}
|
}
|
||||||
|
@ -534,7 +566,7 @@ int main(int argc, char *argv[])
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SMSubProcess subProcess(executable, argumentList, workingDirectory, termTimeout, keepAlive);
|
SMSubProcess subProcess(executable, argumentList, workingDirectory, termTimeout, buffReads, keepAlive);
|
||||||
|
|
||||||
SMSubServerSettings remoteSettings;
|
SMSubServerSettings remoteSettings;
|
||||||
remoteSettings.canRegister = false;
|
remoteSettings.canRegister = false;
|
||||||
|
|
Loading…
Reference in a new issue