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 <QByteArray>
29#include <QIODevice>
30#include <QStringList>
31#include <utility>
32
33// MythTV headers
34#include "mythsystemlegacy.h"
35#include "mythsystem.h"
36#include "exitcodes.h"
37
39{
40 public:
42 const QStringList &args,
43 uint flags,
44 const QString& startPath,
45 Priority /*cpuPriority*/,
46 Priority /*diskPriority*/)
47 {
48 if (args.empty())
49 return nullptr;
50
51 auto *legacy = new MythSystemLegacy(args.join(" "), flags);
52
53 if (!startPath.isEmpty())
54 legacy->SetDirectory(startPath);
55
57 if ((ac & flags) == ac)
58 {
59 legacy->Run();
60 return nullptr;
61 }
62
63 auto *wrapper = new MythSystemLegacyWrapper(legacy, flags);
64
65 // TODO implement cpuPriority and diskPriority
66 return wrapper;
67 }
68
70 {
72 }
73
74 uint GetFlags(void) const override // MythSystem
75 {
76 return m_flags;
77 }
78
80 QString GetStartingPath(void) const override // MythSystem
81 {
82 return m_legacy->GetDirectory();
83 }
84
86 Priority GetCPUPriority(void) const override // MythSystem
87 {
88 return kNormalPriority;
89 }
90
92 Priority GetDiskPriority(void) const override // MythSystem
93 {
94 return kNormalPriority;
95 }
96
103 bool Wait(std::chrono::milliseconds timeout) override // MythSystem
104 {
105 if (timeout >= 1s)
106 timeout = timeout + 500ms;
107 else if (timeout == 0ms)
108 timeout = 0ms;
109 else
110 timeout = 1s;
111 uint legacy_wait_ret = m_legacy->Wait(duration_cast<std::chrono::seconds>(timeout));
112 return GENERIC_EXIT_RUNNING != legacy_wait_ret;
113 }
114
118 QIODevice *GetStandardInputStream(void) override // MythSystem
119 {
120 if (!(kMSStdIn & m_flags))
121 return nullptr;
122
123 if (!m_legacy->GetBuffer(0)->isOpen() &&
124 !m_legacy->GetBuffer(0)->open(QIODevice::WriteOnly))
125 {
126 return nullptr;
127 }
128
129 return m_legacy->GetBuffer(0);
130 }
131
134 QIODevice *GetStandardOutputStream(void) override // MythSystem
135 {
136 if (!(kMSStdOut & m_flags))
137 return nullptr;
138
139 Wait(0ms); // legacy getbuffer is not thread-safe, so wait
140
141 if (!m_legacy->GetBuffer(1)->isOpen() &&
142 !m_legacy->GetBuffer(1)->open(QIODevice::ReadOnly))
143 {
144 return nullptr;
145 }
146
147 return m_legacy->GetBuffer(1);
148 }
149
152 QIODevice *GetStandardErrorStream(void) override // MythSystem
153 {
154 if (!(kMSStdErr & m_flags))
155 return nullptr;
156
157 Wait(0ms); // legacy getbuffer is not thread-safe, so wait
158
159 if (!m_legacy->GetBuffer(2)->isOpen() &&
160 !m_legacy->GetBuffer(2)->open(QIODevice::ReadOnly))
161 {
162 return nullptr;
163 }
164
165 return m_legacy->GetBuffer(2);
166 }
167
169 void Signal(MythSignal sig) override // MythSystem
170 {
171 m_legacy->Signal(sig);
172 }
173
180 int GetExitCode(void) const override // MythSystem
181 {
182 // FIXME doesn't actually know why program exited.
183 // if program returns 142 then we will forever
184 // think it is running even though it is not.
185 int status = m_legacy->GetStatus();
186 if (GENERIC_EXIT_RUNNING == status)
187 return -2;
188 if (GENERIC_EXIT_KILLED == status)
189 return -1;
190 return status;
191 }
192
193 private:
195 m_legacy(legacy), m_flags(flags)
196 {
197 m_legacy->Run();
198 }
199
200 private:
201 QScopedPointer<MythSystemLegacy> m_legacy;
203};
204
206 const QStringList &args,
207 uint flags,
208 const QString& startPath,
209 Priority cpuPriority,
210 Priority diskPriority)
211{
213 args, flags, startPath, cpuPriority, diskPriority);
214}
215
217 const QString& args,
218 uint flags,
219 const QString& startPath,
220 Priority cpuPriority,
221 Priority diskPriority)
222{
223 return MythSystem::Create(
224 args.simplified().split(' '), flags, startPath,
225 cpuPriority, diskPriority);
226}
static MythSystemLegacyWrapper * Create(const QStringList &args, uint flags, const QString &startPath, Priority, Priority)
Definition: mythsystem.cpp:41
Priority GetCPUPriority(void) const override
Return the CPU Priority of the program.
Definition: mythsystem.cpp:86
int GetExitCode(void) const override
returns the exit code, if any, that the program returned.
Definition: mythsystem.cpp:180
QIODevice * GetStandardInputStream(void) override
Returns the standard input stream for the program if the kMSStdIn flag was passed to the constructor.
Definition: mythsystem.cpp:118
uint GetFlags(void) const override
Returns the flags passed to the constructor.
Definition: mythsystem.cpp:74
bool Wait(std::chrono::milliseconds timeout) override
Blocks until child process is collected or timeout reached.
Definition: mythsystem.cpp:103
void Signal(MythSignal sig) override
Sends the selected signal to the program.
Definition: mythsystem.cpp:169
QString GetStartingPath(void) const override
Returns the starting path of the program.
Definition: mythsystem.cpp:80
Priority GetDiskPriority(void) const override
Return the Disk Priority of the program.
Definition: mythsystem.cpp:92
QIODevice * GetStandardErrorStream(void) override
Returns the standard error stream for the program if the kMSStdErr flag was passed to the constructor...
Definition: mythsystem.cpp:152
QIODevice * GetStandardOutputStream(void) override
Returns the standard output stream for the program if the kMSStdOut flag was passed to the constructo...
Definition: mythsystem.cpp:134
QScopedPointer< MythSystemLegacy > m_legacy
Definition: mythsystem.cpp:201
MythSystemLegacyWrapper(MythSystemLegacy *legacy, uint flags)
Definition: mythsystem.cpp:194
~MythSystemLegacyWrapper(void) override
Definition: mythsystem.cpp:69
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:205
@ GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:28
@ GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:26
unsigned int uint
Definition: freesurround.h:24
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