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  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 }
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:102
MythSystemLegacyWrapper::MythSystemLegacyWrapper
MythSystemLegacyWrapper(MythSystemLegacy *legacy, uint flags)
Definition: mythsystem.cpp:194
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:134
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
MythSignal
MythSignal
Definition: mythsystem.h:56
GENERIC_EXIT_KILLED
@ GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:26
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:180
MythSystemLegacyWrapper::Signal
void Signal(MythSignal sig) override
Sends the selected signal to the program.
Definition: mythsystem.cpp:169
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:118
GENERIC_EXIT_RUNNING
@ GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:28
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:201
MythSystemLegacyWrapper::Wait
bool Wait(std::chrono::milliseconds timeout) override
Blocks until child process is collected or timeout reached.
Definition: mythsystem.cpp:103
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:152
MythSystem::kNormalPriority
@ kNormalPriority
run as a normal program
Definition: mythsystem.h:88
MythSystemLegacyWrapper::m_flags
uint m_flags
Definition: mythsystem.cpp:202
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:216
uint
unsigned int uint
Definition: freesurround.h:24
MythSystem::Create
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, const QString &startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)
Definition: mythsystem.cpp:205