2016-09-03 19:39:43 +02:00
|
|
|
#ifndef DATA_SYNCTHINGPROCESS_H
|
|
|
|
#define DATA_SYNCTHINGPROCESS_H
|
|
|
|
|
2016-09-30 23:55:25 +02:00
|
|
|
#include "./global.h"
|
|
|
|
|
2018-04-02 20:26:00 +02:00
|
|
|
#include <c++utilities/chrono/datetime.h>
|
|
|
|
|
2016-09-03 19:39:43 +02:00
|
|
|
#include <QProcess>
|
2020-04-27 23:08:41 +02:00
|
|
|
#include <QStringList>
|
2018-04-02 23:29:39 +02:00
|
|
|
#include <QTimer>
|
2016-09-03 19:39:43 +02:00
|
|
|
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
#include <memory>
|
|
|
|
#endif
|
|
|
|
|
2016-09-03 19:39:43 +02:00
|
|
|
namespace Data {
|
|
|
|
|
2021-06-21 23:18:51 +02:00
|
|
|
class SyncthingConnection;
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
struct SyncthingProcessInternalData;
|
|
|
|
struct SyncthingProcessIOHandler;
|
|
|
|
using SyncthingProcessBase = QIODevice;
|
|
|
|
#else
|
|
|
|
using SyncthingProcessBase = QProcess;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingProcess : public SyncthingProcessBase {
|
2016-09-03 19:39:43 +02:00
|
|
|
Q_OBJECT
|
2018-04-02 20:26:00 +02:00
|
|
|
Q_PROPERTY(bool running READ isRunning)
|
2019-06-10 22:48:26 +02:00
|
|
|
Q_PROPERTY(CppUtilities::DateTime activeSince READ activeSince)
|
2018-04-02 20:26:00 +02:00
|
|
|
Q_PROPERTY(bool manuallyStopped READ isManuallyStopped)
|
|
|
|
|
2016-09-03 19:39:43 +02:00
|
|
|
public:
|
2017-01-06 15:19:37 +01:00
|
|
|
explicit SyncthingProcess(QObject *parent = nullptr);
|
2021-06-09 20:59:09 +02:00
|
|
|
~SyncthingProcess() override;
|
2018-04-02 20:26:00 +02:00
|
|
|
bool isRunning() const;
|
2019-06-10 22:48:26 +02:00
|
|
|
CppUtilities::DateTime activeSince() const;
|
2018-04-02 20:26:00 +02:00
|
|
|
bool isActiveFor(unsigned int atLeastSeconds) const;
|
|
|
|
bool isManuallyStopped() const;
|
2018-04-11 23:15:15 +02:00
|
|
|
static SyncthingProcess *mainInstance();
|
|
|
|
static void setMainInstance(SyncthingProcess *mainInstance);
|
2018-04-18 23:27:45 +02:00
|
|
|
static QStringList splitArguments(const QString &arguments);
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
QProcess::ProcessState state() const;
|
|
|
|
void start(const QString &program, const QStringList &arguments, QIODevice::OpenMode openMode = QIODevice::ReadOnly);
|
|
|
|
qint64 bytesAvailable() const override;
|
|
|
|
void close() override;
|
|
|
|
int exitCode() const;
|
|
|
|
bool waitForFinished(int msecs = 30000);
|
2021-06-17 20:32:25 +02:00
|
|
|
bool waitForReadyRead(int msecs) override;
|
2021-06-09 20:59:09 +02:00
|
|
|
qint64 processId() const;
|
|
|
|
QString program() const;
|
|
|
|
QStringList arguments() const;
|
2021-06-17 20:32:25 +02:00
|
|
|
QProcess::ProcessChannelMode processChannelMode() const;
|
|
|
|
void setProcessChannelMode(QProcess::ProcessChannelMode mode);
|
2021-06-09 20:59:09 +02:00
|
|
|
#endif
|
2018-04-02 23:29:39 +02:00
|
|
|
|
2016-09-03 19:39:43 +02:00
|
|
|
public Q_SLOTS:
|
2021-06-21 23:18:51 +02:00
|
|
|
void restartSyncthing(const QString &program, const QStringList &arguments, SyncthingConnection *currentConnection = nullptr);
|
2018-04-18 23:27:45 +02:00
|
|
|
void startSyncthing(const QString &program, const QStringList &arguments);
|
2021-06-21 23:18:51 +02:00
|
|
|
void stopSyncthing(SyncthingConnection *currentConnection = nullptr);
|
2018-04-02 23:29:39 +02:00
|
|
|
void killSyncthing();
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
void terminate();
|
|
|
|
void kill();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Q_SIGNALS:
|
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
void started();
|
|
|
|
void finished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
|
|
void errorOccurred(QProcess::ProcessError error);
|
|
|
|
void stateChanged(QProcess::ProcessState newState);
|
|
|
|
#endif
|
|
|
|
void confirmKill();
|
|
|
|
|
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
protected:
|
|
|
|
qint64 readData(char *data, qint64 maxSize) override;
|
|
|
|
qint64 writeData(const char *data, qint64 len) override;
|
|
|
|
#endif
|
2016-09-03 19:39:43 +02:00
|
|
|
|
|
|
|
private Q_SLOTS:
|
2018-04-02 20:26:00 +02:00
|
|
|
void handleStarted();
|
2016-09-03 19:39:43 +02:00
|
|
|
void handleFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
|
|
|
void killToRestart();
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
2021-06-17 21:17:21 +02:00
|
|
|
void handleError(int error, const QString &errorMessage, bool closed);
|
2021-06-09 20:59:09 +02:00
|
|
|
void bufferOutput();
|
|
|
|
void handleLeftoverProcesses();
|
|
|
|
#endif
|
2016-09-03 19:39:43 +02:00
|
|
|
|
|
|
|
private:
|
2018-04-18 23:27:45 +02:00
|
|
|
QString m_program;
|
|
|
|
QStringList m_arguments;
|
2019-06-10 22:48:26 +02:00
|
|
|
CppUtilities::DateTime m_activeSince;
|
2018-04-02 23:29:39 +02:00
|
|
|
QTimer m_killTimer;
|
2021-06-09 20:59:09 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
std::shared_ptr<SyncthingProcessInternalData> m_process;
|
|
|
|
std::unique_ptr<SyncthingProcessIOHandler> m_handler;
|
2021-06-17 20:32:25 +02:00
|
|
|
QProcess::ProcessChannelMode m_mode;
|
2021-06-09 20:59:09 +02:00
|
|
|
#endif
|
2018-04-02 20:26:00 +02:00
|
|
|
bool m_manuallyStopped;
|
2018-04-11 23:15:15 +02:00
|
|
|
static SyncthingProcess *s_mainInstance;
|
2016-09-03 19:39:43 +02:00
|
|
|
};
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/// \brief Returns whether the process is running.
|
2018-04-02 20:26:00 +02:00
|
|
|
inline bool SyncthingProcess::isRunning() const
|
|
|
|
{
|
|
|
|
return state() != QProcess::NotRunning;
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/// \brief Returns the last time when QProcess::started() has been emitted.
|
2019-06-10 22:48:26 +02:00
|
|
|
inline CppUtilities::DateTime SyncthingProcess::activeSince() const
|
2018-04-02 20:26:00 +02:00
|
|
|
{
|
|
|
|
return m_activeSince;
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/// \brief Checks whether the process already runs for the specified number of seconds.
|
2018-04-02 20:26:00 +02:00
|
|
|
inline bool SyncthingProcess::isActiveFor(unsigned int atLeastSeconds) const
|
|
|
|
{
|
2019-06-10 22:48:26 +02:00
|
|
|
return !m_activeSince.isNull() && (CppUtilities::DateTime::gmtNow() - m_activeSince).totalSeconds() > atLeastSeconds;
|
2018-04-02 20:26:00 +02:00
|
|
|
}
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/// \brief Returns whether the process has been manually stopped via SyncthingProcess::stopSyncthing(), SyncthingProcess::killSyncthing()
|
|
|
|
/// or SyncthingProcess::restartSyncthing().
|
2021-07-03 19:29:49 +02:00
|
|
|
/// \remarks Reset on SyncthingProcess::startSyncthing() and SyncthingProcess::restartSyncthing().
|
2018-04-02 20:26:00 +02:00
|
|
|
inline bool SyncthingProcess::isManuallyStopped() const
|
|
|
|
{
|
|
|
|
return m_manuallyStopped;
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/*!
|
|
|
|
* \brief Returns the "main" instance assigned via SyncthingProcess::setMainInstance().
|
|
|
|
*/
|
2018-04-11 23:15:15 +02:00
|
|
|
inline SyncthingProcess *SyncthingProcess::mainInstance()
|
|
|
|
{
|
|
|
|
return s_mainInstance;
|
|
|
|
}
|
|
|
|
|
2019-07-13 16:42:19 +02:00
|
|
|
/*!
|
|
|
|
* \brief Sets the "main" instance.
|
|
|
|
*/
|
2018-04-11 23:15:15 +02:00
|
|
|
inline void SyncthingProcess::setMainInstance(SyncthingProcess *mainInstance)
|
|
|
|
{
|
|
|
|
s_mainInstance = mainInstance;
|
|
|
|
}
|
2016-09-03 19:39:43 +02:00
|
|
|
|
2021-06-17 20:32:25 +02:00
|
|
|
#ifdef LIB_SYNCTHING_CONNECTOR_BOOST_PROCESS
|
|
|
|
/*!
|
|
|
|
* \brief Returns the QProcess::ProcessChannelMode like QProcess::processChannelMode().
|
|
|
|
*/
|
|
|
|
inline QProcess::ProcessChannelMode SyncthingProcess::processChannelMode() const
|
|
|
|
{
|
|
|
|
return m_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Sets the QProcess::ProcessChannelMode like QProcess::setProcessChannelMode().
|
|
|
|
* \remarks
|
|
|
|
* - Does not affect an already running process.
|
|
|
|
* - Supports only QProcess::MergedChannels, QProcess::SeparateChannels and QProcess::ForwardedChannels.
|
|
|
|
*/
|
|
|
|
inline void SyncthingProcess::setProcessChannelMode(QProcess::ProcessChannelMode mode)
|
|
|
|
{
|
|
|
|
m_mode = mode;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2016-09-03 19:39:43 +02:00
|
|
|
} // namespace Data
|
|
|
|
|
|
|
|
#endif // DATA_SYNCTHINGPROCESS_H
|