MythTV master
mythsystem.cpp
Go to the documentation of this file.
1/* -*- Mode: c++ -*-
2 * Class MythSystem
3 *
4 * Copyright (C) Daniel Kristjansson 2013
5 * Copyright (C) Gavin Hurlbut 2012
6 * Copyright (C) Issac Richards 2008
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23// C++ headers
24#include <cstdint>
25#include <csignal> // for SIGXXX
26
27// Qt headers
28#include <QChar> // Fix Qt6 GCC SFINAE warning
29#include <QByteArray>
30#include <QIODevice>
31#include <QStringList>
32#include <utility>
33
34// MythTV headers
35#include "mythsystemlegacy.h"
36#include "mythsystem.h"
37#include "exitcodes.h"
38
40{
41 public:
43 const QStringList &args,
44 uint flags,
45 const QString& startPath,
46 Priority /*cpuPriority*/,
47 Priority /*diskPriority*/)
48 {
49 if (args.empty())
50 return nullptr;
51
52 auto *legacy = new MythSystemLegacy(args.join(" "), flags);
53
54 if (!startPath.isEmpty())
55 legacy->SetDirectory(startPath);
56
58 if ((ac & flags) == ac)
59 {
60 legacy->Run();
61 return nullptr;
62 }
63
64 auto *wrapper = new MythSystemLegacyWrapper(legacy, flags);
65
66 // TODO implement cpuPriority and diskPriority
67 return wrapper;
68 }
69
71 {
73 }
74
75 uint GetFlags(void) const override // MythSystem
76 {
77 return m_flags;
78 }
79
81 QString GetStartingPath(void) const override // MythSystem
82 {
83 return m_legacy->GetDirectory();
84 }
85
87 Priority GetCPUPriority(void) const override // MythSystem
88 {
89 return kNormalPriority;
90 }
91
93 Priority GetDiskPriority(void) const override // MythSystem
94 {
95 return kNormalPriority;
96 }
97
104 bool Wait(std::chrono::milliseconds timeout) override // MythSystem
105 {
106 if (timeout >= 1s)
107 timeout = timeout + 500ms;
108 else if (timeout == 0ms)
109 timeout = 0ms;
110 else
111 timeout = 1s;
112 uint legacy_wait_ret = m_legacy->Wait(duration_cast<std::chrono::seconds>(timeout));
113 return GENERIC_EXIT_RUNNING != legacy_wait_ret;
114 }
115
119 QIODevice *GetStandardInputStream(void) override // MythSystem
120 {
121 if (!(kMSStdIn & m_flags))
122 return nullptr;
123
124 if (!m_legacy->GetBuffer(0)->isOpen() &&
125 !m_legacy->GetBuffer(0)->open(QIODevice::WriteOnly))
126 {
127 return nullptr;
128 }
129
130 return m_legacy->GetBuffer(0);
131 }
132
135 QIODevice *GetStandardOutputStream(void) override // MythSystem
136 {
137 if (!(kMSStdOut & m_flags))
138 return nullptr;
139
140 Wait(0ms); // legacy getbuffer is not thread-safe, so wait
141
142 if (!m_legacy->GetBuffer(1)->isOpen() &&
143 !m_legacy->GetBuffer(1)->open(QIODevice::ReadOnly))
144 {
145 return nullptr;
146 }
147
148 return m_legacy->GetBuffer(1);
149 }
150
153 QIODevice *GetStandardErrorStream(void) override // MythSystem
154 {
155 if (!(kMSStdErr & m_flags))
156 return nullptr;
157
158 Wait(0ms); // legacy getbuffer is not thread-safe, so wait
159
160 if (!m_legacy->GetBuffer(2)->isOpen() &&
161 !m_legacy->GetBuffer(2)->open(QIODevice::ReadOnly))
162 {
163 return nullptr;
164 }
165
166 return m_legacy->GetBuffer(2);
167 }
168
170 void Signal(MythSignal sig) override // MythSystem
171 {
172 m_legacy->Signal(sig);
173 }
174
181 int GetExitCode(void) const override // MythSystem
182 {
183 // FIXME doesn't actually know why program exited.
184 // if program returns 142 then we will forever
185 // think it is running even though it is not.
186 int status = m_legacy->GetStatus();
187 if (GENERIC_EXIT_RUNNING == status)
188 return -2;
189 if (GENERIC_EXIT_KILLED == status)
190 return -1;
191 return status;
192 }
193
194 private:
196 m_legacy(legacy), m_flags(flags)
197 {
198 m_legacy->Run();
199 }
200
201 private:
202 QScopedPointer<MythSystemLegacy> m_legacy;
204};
205
207 const QStringList &args,
208 uint flags,
209 const QString& startPath,
210 Priority cpuPriority,
211 Priority diskPriority)
212{
214 args, flags, startPath, cpuPriority, diskPriority);
215}
216
218 const QString& args,
219 uint flags,
220 const QString& startPath,
221 Priority cpuPriority,
222 Priority diskPriority)
223{
224 return MythSystem::Create(
225 args.simplified().split(' '), flags, startPath,
226 cpuPriority, diskPriority);
227}
static MythSystemLegacyWrapper * Create(const QStringList &args, uint flags, const QString &startPath, Priority, Priority)
Definition: mythsystem.cpp:42
Priority GetCPUPriority(void) const override
Return the CPU Priority of the program.
Definition: mythsystem.cpp:87
int GetExitCode(void) const override
returns the exit code, if any, that the program returned.
Definition: mythsystem.cpp:181
QIODevice * GetStandardInputStream(void) override
Returns the standard input stream for the program if the kMSStdIn flag was passed to the constructor.
Definition: mythsystem.cpp:119
uint GetFlags(void) const override
Returns the flags passed to the constructor.
Definition: mythsystem.cpp:75
bool Wait(std::chrono::milliseconds timeout) override
Blocks until child process is collected or timeout reached.
Definition: mythsystem.cpp:104
void Signal(MythSignal sig) override
Sends the selected signal to the program.
Definition: mythsystem.cpp:170
QString GetStartingPath(void) const override
Returns the starting path of the program.
Definition: mythsystem.cpp:81
Priority GetDiskPriority(void) const override
Return the Disk Priority of the program.
Definition: mythsystem.cpp:93
QIODevice * GetStandardErrorStream(void) override
Returns the standard error stream for the program if the kMSStdErr flag was passed to the constructor...
Definition: mythsystem.cpp:153
QIODevice * GetStandardOutputStream(void) override
Returns the standard output stream for the program if the kMSStdOut flag was passed to the constructo...
Definition: mythsystem.cpp:135
QScopedPointer< MythSystemLegacy > m_legacy
Definition: mythsystem.cpp:202
MythSystemLegacyWrapper(MythSystemLegacy *legacy, uint flags)
Definition: mythsystem.cpp:195
~MythSystemLegacyWrapper(void) override
Definition: mythsystem.cpp:70
class for managing sub-processes.
Definition: mythsystem.h:81
@ kNormalPriority
run as a normal program
Definition: mythsystem.h:88
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, const QString &startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)
Definition: mythsystem.cpp:206
unsigned int uint
Definition: compat.h:60
@ GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:28
@ GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:26
MythSignal
Definition: mythsystem.h:56
@ kMSStdIn
allow access to stdin
Definition: mythsystem.h:40
@ kMSStdErr
allow access to stderr
Definition: mythsystem.h:42
@ kMSStdOut
allow access to stdout
Definition: mythsystem.h:41
@ kMSRunBackground
run child in the background
Definition: mythsystem.h:38
@ kMSAutoCleanup
automatically delete if backgrounded
Definition: mythsystem.h:45