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 <QRegExp>
31 #include <QStringList>
32 #include <utility>
33 
34 // MythTV headers
35 #include "mythsystemlegacy.h"
36 #include "mythsystem.h"
37 #include "exitcodes.h"
38 
39 using namespace std;
40 
42 {
43  public:
45  const QStringList &args,
46  uint flags,
47  const QString& startPath,
48  Priority /*cpuPriority*/,
49  Priority /*diskPriority*/)
50  {
51  if (args.empty())
52  return nullptr;
53 
54  MythSystemLegacy *legacy =
55  new MythSystemLegacy(args.join(" "), flags);
56 
57  if (!startPath.isEmpty())
58  legacy->SetDirectory(startPath);
59 
61  if ((ac & flags) == ac)
62  {
63  legacy->Run();
64  return nullptr;
65  }
66 
67  MythSystemLegacyWrapper *wrapper =
68  new MythSystemLegacyWrapper(legacy, flags);
69 
70  // TODO implement cpuPriority and diskPriority
71  return wrapper;
72  }
73 
74  ~MythSystemLegacyWrapper(void) override
75  {
77  }
78 
79  uint GetFlags(void) const override // MythSystem
80  {
81  return m_flags;
82  }
83 
85  QString GetStartingPath(void) const override // MythSystem
86  {
87  return m_legacy->GetDirectory();
88  }
89 
91  Priority GetCPUPriority(void) const override // MythSystem
92  {
93  return kNormalPriority;
94  }
95 
97  Priority GetDiskPriority(void) const override // MythSystem
98  {
99  return kNormalPriority;
100  }
101 
108  bool Wait(uint timeout_ms) override // MythSystem
109  {
110  timeout_ms = (timeout_ms >= 1000) ? timeout_ms + 500 :
111  ((timeout_ms == 0) ? 0 : 1000);
112  uint legacy_wait_ret = m_legacy->Wait(timeout_ms / 1000);
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(0); // 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(0); // 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  QString startPath,
210  Priority cpuPriority,
211  Priority diskPriority)
212 {
214  args, flags, std::move(startPath), cpuPriority, diskPriority);
215 }
216 
218  const QString& args,
219  uint flags,
220  QString startPath,
221  Priority cpuPriority,
222  Priority diskPriority)
223 {
224  return MythSystem::Create(
225  args.split(QRegExp("\\s+")), flags, std::move(startPath),
226  cpuPriority, diskPriority);
227 }
void Run(time_t timeout=0)
Runs a command inside the /bin/sh shell. Returns immediately.
allow access to stdin
Definition: mythsystem.h:38
automatically delete if backgrounded
Definition: mythsystem.h:43
allow access to stdout
Definition: mythsystem.h:39
Priority GetDiskPriority(void) const override
Return the Disk Priority of the program.
Definition: mythsystem.cpp:97
run child in the background
Definition: mythsystem.h:36
Priority GetCPUPriority(void) const override
Return the CPU Priority of the program.
Definition: mythsystem.cpp:91
#define GENERIC_EXIT_KILLED
Process killed or stopped.
Definition: exitcodes.h:23
static MythSystem * Create(const QStringList &args, uint flags=kMSNone, QString startPath=QString(), Priority cpuPriority=kInheritPriority, Priority diskPriority=kInheritPriority)
Definition: mythsystem.cpp:206
unsigned int uint
Definition: compat.h:140
int GetExitCode(void) const override
returns the exit code, if any, that the program returned.
Definition: mythsystem.cpp:181
QString GetStartingPath(void) const override
Returns the starting path of the program.
Definition: mythsystem.cpp:85
uint GetFlags(void) const override
Returns the flags passed to the constructor.
Definition: mythsystem.cpp:79
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
void SetDirectory(const QString &)
#define GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:25
allow access to stderr
Definition: mythsystem.h:40
class for managing sub-processes.
Definition: mythsystem.h:81
static MythSystemLegacyWrapper * Create(const QStringList &args, uint flags, const QString &startPath, Priority, Priority)
Definition: mythsystem.cpp:44
MythSystemLegacyWrapper(MythSystemLegacy *legacy, uint flags)
Definition: mythsystem.cpp:195
MythSignal
Definition: mythsystem.h:54
void Signal(MythSignal sig) override
Sends the selected signal to the program.
Definition: mythsystem.cpp:170
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
bool Wait(uint timeout_ms) override
Blocks until child process is collected or timeout reached.
Definition: mythsystem.cpp:108
~MythSystemLegacyWrapper(void) override
Definition: mythsystem.cpp:74
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