1 /*
2 SPDX-FileCopyrightText: 2011 Vishesh Yadav <vishesh3y@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "servewrapper.h"
8 #include "hgwrapper.h"
9
10 #include <QTextCodec>
11
12 HgServeWrapper *HgServeWrapper::m_instance = nullptr;
13
HgServeWrapper(QObject * parent)14 HgServeWrapper::HgServeWrapper(QObject *parent) :
15 QObject(parent)
16 {
17 }
18
~HgServeWrapper()19 HgServeWrapper::~HgServeWrapper()
20 {
21 QMutableHashIterator<QString, ServerProcessType*> it(m_serverList);
22 while (it.hasNext()) {
23 it.next();
24 ///terminate server if not terminated already
25 if (it.value()->process.state() != QProcess::NotRunning) {
26 it.value()->process.terminate();
27 }
28 it.value()->deleteLater();
29 it.remove();
30 }
31 }
32
instance()33 HgServeWrapper *HgServeWrapper::instance()
34 {
35 if (m_instance == nullptr) {
36 m_instance = new HgServeWrapper;
37 }
38 return m_instance;
39 }
40
startServer(const QString & repoLocation,int portNumber)41 void HgServeWrapper::startServer(const QString &repoLocation, int portNumber)
42 {
43 ServerProcessType *server = m_serverList.value(repoLocation, nullptr);
44 if (server != nullptr) {
45 m_serverList.remove(repoLocation);
46 server->deleteLater();
47 }
48 server = new ServerProcessType;
49 m_serverList.insert(repoLocation, server);
50 server->port = portNumber;
51 server->process.setWorkingDirectory(HgWrapper::instance()->getBaseDir());
52
53 connect(&server->process, &QProcess::started,
54 this, &HgServeWrapper::started);
55 connect(&server->process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
56 this, &HgServeWrapper::slotFinished);
57 connect(server, &ServerProcessType::readyReadLine,
58 this, &HgServeWrapper::readyReadLine);
59
60 QStringList args;
61 args << QLatin1String("-oL");
62 args << QLatin1String("hg");
63 args << QLatin1String("serve");
64 args << QLatin1String("--port");
65 args << QString::number(portNumber);
66 server->process.start(QLatin1String("stdbuf"), args);
67 Q_EMIT readyReadLine(repoLocation,
68 i18n("## Starting Server ##"));
69 Q_EMIT readyReadLine(repoLocation,
70 QString("% hg serve --port %1").arg(portNumber));
71 }
72
stopServer(const QString & repoLocation)73 void HgServeWrapper::stopServer(const QString &repoLocation)
74 {
75 ServerProcessType *server = m_serverList.value(repoLocation, nullptr);
76 if (server == nullptr) {
77 return;
78 }
79 server->process.terminate();
80 }
81
running(const QString & repoLocation)82 bool HgServeWrapper::running(const QString &repoLocation)
83 {
84 ServerProcessType *server = m_serverList.value(repoLocation, nullptr);
85 if (server == nullptr) {
86 return false;
87 }
88 return ( server->process.state() == QProcess::Running ||
89 server->process.state() == QProcess::Starting);
90 }
91
slotFinished(int exitCode,QProcess::ExitStatus status)92 void HgServeWrapper::slotFinished(int exitCode, QProcess::ExitStatus status)
93 {
94 if (exitCode == 0 && status == QProcess::NormalExit) {
95 Q_EMIT finished();
96 }
97 else {
98 Q_EMIT error();
99 }
100 }
101
errorMessage(const QString & repoLocation)102 QString HgServeWrapper::errorMessage(const QString &repoLocation)
103 {
104 ServerProcessType *server = m_serverList.value(repoLocation, nullptr);
105 if (server == nullptr) {
106 return QString();
107 }
108 return QTextCodec::codecForLocale()->toUnicode(server->process.readAllStandardError());
109 }
110
normalExit(const QString & repoLocation)111 bool HgServeWrapper::normalExit(const QString &repoLocation)
112 {
113 ServerProcessType *server = m_serverList.value(repoLocation, nullptr);
114 if (server == nullptr) {
115 return true;
116 }
117
118 return (server->process.exitStatus() == QProcess::NormalExit &&
119 server->process.exitCode() == 0);
120 }
121
cleanUnused()122 void HgServeWrapper::cleanUnused()
123 {
124 QMutableHashIterator<QString, ServerProcessType*> it(m_serverList);
125 while (it.hasNext()) {
126 it.next();
127 if (it.value()->process.state() == QProcess::NotRunning) {
128 it.value()->deleteLater();
129 it.remove();
130 }
131 }
132 }
133
134
135