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 
69  ~MythSystemLegacyWrapper(void) override
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  timeout = (timeout >= 1s) ? timeout + 500ms :
106  ((timeout == 0ms) ? 0ms : 1s);
107  uint legacy_wait_ret = m_legacy->Wait(duration_cast<std::chrono::seconds>(timeout));
108  return GENERIC_EXIT_RUNNING != legacy_wait_ret;
109  }
110 
114  QIODevice *GetStandardInputStream(void) override // MythSystem
115  {
116  if (!(kMSStdIn & m_flags))
117  return nullptr;
118 
119  if (!m_legacy->GetBuffer(0)->isOpen() &&
120  !m_legacy->GetBuffer(0)->open(QIODevice::WriteOnly))
121  {
122  return nullptr;
123  }
124 
125  return m_legacy->GetBuffer(0);
126  }
127 
130  QIODevice *GetStandardOutputStream(void) override // MythSystem
131  {
132  if (!(kMSStdOut & m_flags))
133  return nullptr;
134 
135  Wait(0ms); // legacy getbuffer is not thread-safe, so wait
136 
137  if (!m_legacy->GetBuffer(1)->isOpen() &&
138  !m_legacy->GetBuffer(1)->open(QIODevice::ReadOnly))
139  {
140  return nullptr;
141  }
142 
143  return m_legacy->GetBuffer(1);
144  }
145 
148  QIODevice *GetStandardErrorStream(void) override // MythSystem
149  {
150  if (!(kMSStdErr & m_flags))
151  return nullptr;
152 
153  Wait(0ms); // legacy getbuffer is not thread-safe, so wait
154 
155  if (!m_legacy->GetBuffer(2)->isOpen() &&
156  !m_legacy->GetBuffer(2)->open(QIODevice::ReadOnly))
157  {
158  return nullptr;
159  }
160 
161  return m_legacy->GetBuffer(2);
162  }
163 
165  void Signal(MythSignal sig) override // MythSystem
166  {
167  m_legacy->Signal(sig);
168  }
169 
176  int GetExitCode(void) const override // MythSystem
177  {
178  // FIXME doesn't actually know why program exited.
179  // if program returns 142 then we will forever
180  // think it is running even though it is not.
181  int status = m_legacy->GetStatus();
182  if (GENERIC_EXIT_RUNNING == status)
183  return -2;
184  if (GENERIC_EXIT_KILLED == status)
185  return -1;
186  return status;
187  }
188 
189  private:
191  m_legacy(legacy), m_flags(flags)
192  {
193  m_legacy->Run();
194  }
195 
196  private:
197  QScopedPointer<MythSystemLegacy> m_legacy;
199 };
200 
202  const QStringList &args,
203  uint flags,
204  const QString& startPath,
205  Priority cpuPriority,
206  Priority diskPriority)
207 {
209  args, flags, startPath, cpuPriority, diskPriority);
210 }
211 
213  const QString& args,
214  uint flags,
215  const QString& startPath,
216  Priority cpuPriority,
217  Priority diskPriority)
218 {
219  return MythSystem::Create(
220  args.simplified().split(' '), flags, startPath,
221  cpuPriority, diskPriority);
222 }
kMSStdErr
@ kMSStdErr
allow access to stderr
Definition: mythsystem.h:42
build_compdb.args
args
Definition: build_compdb.py:11
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythSystemLegacyWrapper::MythSystemLegacyWrapper
MythSystemLegacyWrapper(MythSystemLegacy *legacy, uint flags)
Definition: mythsystem.cpp:190
MythSystemLegacyWrapper::GetStartingPath
QString GetStartingPath(void) const override
Returns the starting path of the program.
Definition: mythsystem.cpp:80
MythSystemLegacy
Definition: mythsystemlegacy.h:67
MythSystem
class for managing sub-processes.
Definition: mythsystem.h:80
MythSystemLegacyWrapper::GetStandardOutputStream
QIODevice * GetStandardOutputStream(void) override
Returns the standard output stream for the program if the kMSStdOut flag was passed to the constructo...
Definition: mythsystem.cpp:130
MythSystemLegacyWrapper::GetFlags
uint GetFlags(void) const override
Returns the flags passed to the constructor.
Definition: mythsystem.cpp:74
mythsystemlegacy.h
mythsystem.h
MythSystemLegacyWrapper::GetDiskPriority
Priority GetDiskPriority(void) const override
Return the Disk Priority of the program.
Definition: mythsystem.cpp:92
MythSystemLegacyWrapper::GetCPUPriority
Priority GetCPUPriority(void) const override
Return the CPU Priority of the program.
Definition: mythsystem.cpp:86
MythSystemLegacyWrapper::Create
static MythSystemLegacyWrapper * Create(const QStringList &args, uint flags, const QString &startPath, Priority, Priority)
Definition: mythsystem.cpp:41
MythSystemLegacyWrapper::GetExitCode
int GetExitCode(void) const override
returns the exit code, if any, that the program returned.
Definition: mythsystem.cpp:176
uint
unsigned int uint
Definition: compat.h:140
MythSystemLegacyWrapper::Signal
void Signal(MythSignal sig) override
Sends the selected signal to the program.
Definition: mythsystem.cpp:165
MythSystemLegacyWrapper
Definition: mythsystem.cpp:38
MythSystemLegacyWrapper::GetStandardInputStream
QIODevice * GetStandardInputStream(void) override
Returns the standard input stream for the program if the kMSStdIn flag was passed to the constructor.
Definition: mythsystem.cpp:114
kMSAutoCleanup
@ kMSAutoCleanup
automatically delete if backgrounded
Definition: mythsystem.h:45
kMSRunBackground
@ kMSRunBackground
run child in the background
Definition: mythsystem.h:38
MythSystemLegacyWrapper::~MythSystemLegacyWrapper
~MythSystemLegacyWrapper(void) override
Definition: mythsystem.cpp:69
MythSystemLegacyWrapper::m_legacy
QScopedPointer< MythSystemLegacy > m_legacy
Definition: mythsystem.cpp:197
MythSystemLegacyWrapper::Wait
bool Wait(std::chrono::milliseconds timeout) override
Blocks until child process is collected or timeout reached.
Definition: mythsystem.cpp:103
MythSignal
MythSignal
Definition: mythsystem.h:56
MythSystemLegacyWrapper::GetStandardErrorStream
QIODevice * GetStandardErrorStream(void) override
Returns the standard error stream for the program if the kMSStdErr flag was passed to the constructor...
Definition: mythsystem.cpp:148
MythSystemLegacyWrapper::m_flags
uint m_flags
Definition: mythsystem.cpp:198
MythSystem::kNormalPriority
@ kNormalPriority
run as a normal program
Definition: mythsystem.h:88
GENERIC_EXIT_RUNNING
#define GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:25
exitcodes.h
kMSStdIn
@ kMSStdIn
allow access to stdin
Definition: mythsystem.h:40
kMSStdOut
@ kMSStdOut
allow access to stdout
Definition: mythsystem.h:41
Priority
Definition: channelsettings.cpp:191
MythSystem::Create
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, const QString &startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)
Definition: mythsystem.cpp:201
GENERIC_EXIT_KILLED
#define GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:23